October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
automated testing

How to Take Selenium Screenshots on Test Failure (Python, pytest, Java, and CI)

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Take the screenshot before Selenium tears down the WebDriver session, and let your test runner decide when a failure has occurred. Selenium supplies capture methods; pytest, JUnit, TestNG, or another runner supplies the failure lifecycle. In Python, the most reliable pytest pattern is a pytest_runtest_makereport hook that checks the report phase, captures the live driver, and stores a uniquely named PNG as a CI artifact.

This guide shows that pattern, explains setup, call, and teardown failures, covers bytes and Base64 attachments, and then shows equivalent Java options. It also addresses naming collisions, parallel workers, capture errors, and preserving the original test failure.

What Selenium does—and what it does not do

Selenium WebDriver can capture the current browser window. Python provides save_screenshot(path) and get_screenshot_as_file(path) for a PNG file, plus methods that return PNG bytes or Base64 data. The Java TakesScreenshot interface likewise exposes several output targets (Java API).

Selenium does not know that your test has failed. The test framework creates a failure report, and your hook or listener connects that report to a still-open driver. A screenshot is only the visible state at capture time; retain the assertion message and, when useful, browser logs or page source as well.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Sale
Philips 24 Inch Computer Monitor FHD 100Hz VA VESA Flicker-Free, 241V8LB
  • CRISP CLARITY: This 23.8″ Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
  • INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
  • THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
  • WORK SEAMLESSLY: This sleek monitor is virtually bezel-free on three sides, so the screen looks even bigger for the viewer. This minimalistic design also allows for seamless multi-monitor setups that enhance your workflow and boost productivity
  • A BETTER READING EXPERIENCE: For busy office workers, EasyRead mode provides a more paper-like experience for when viewing lengthy documents

Python and pytest: capture a failed test body

Install compatible Selenium and pytest versions in the environment that runs your suite. Keep the driver in a fixture or on the test item, ensure the artifact directory exists, and use a filesystem-safe, collision-resistant name.

1. Expose the driver and create the output directory

# conftest.py
from pathlib import Path
import pytest
from selenium import webdriver

ARTIFACT_DIR = Path("test-artifacts/screenshots")

@pytest.fixture
def driver(request):
    browser = webdriver.Chrome()
    # Make the live driver discoverable by the report hook.
    request.node.driver = browser
    yield browser
    browser.quit()

The exact fixture shape can differ in your project. The important ordering is that the report hook runs while driver is usable, before the fixture closes it.

2. Add the report hook

# conftest.py (continued)
from pathlib import Path
import re


def safe_name(value: str) -> str:
    return re.sub(r"[^A-Za-z0-9_.-]+", "_", value)[:160]


@pytest.hookimpl(wrapper=True, tryfirst=True)
def pytest_runtest_makereport(item, call):
    report = yield

    # Capture failures in the test body. See the phase choices below.
    if report.when != "call" or not report.failed:
        return

    driver = getattr(item, "driver", None)
    if driver is None:
        return

    ARTIFACT_DIR.mkdir(parents=True, exist_ok=True)
    worker = item.config.getoption("--worker-id", default="master")
    filename = safe_name(f"{worker}-{item.nodeid}") + ".png"
    destination = ARTIFACT_DIR / filename

    try:
        saved = driver.save_screenshot(str(destination))
        if saved is False:
            # Selenium documents False for a file I/O failure.
            print(f"Screenshot was not saved: {destination}")
    except Exception as exc:
        # Do not replace the assertion that caused the test to fail.
        print(f"Screenshot capture failed for {item.nodeid}: {exc}")

The current pytest example uses the wrapper form: the hook yields to let other hooks create the report, then inspects report.when and report.failed (pytest report-hook example). Selenium’s Python file API and return behavior are documented in its WebDriver reference.

Why the call phase is explicit

pytest creates reports for three phases: setup, call, and teardown (pytest API reference). The code above captures only an assertion or test-body failure. That avoids taking a second image for every fixture problem, but it also means a fixture failure will not be captured.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
Philips 22 Inch Computer Monitor FHD 100Hz VA VESA Flicker-Free, 221V8LB
  • CRISP CLARITY: This 22 inch class (21.5″ viewable) Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
  • 100HZ FAST REFRESH RATE: 100Hz brings your favorite movies and video games to life. Stream, binge, and play effortlessly
  • SMOOTH ACTION WITH ADAPTIVE-SYNC: Adaptive-Sync technology ensures fluid action sequences and rapid response time. Every frame will be rendered smoothly with crystal clarity and without stutter
  • INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
  • THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors

To capture setup and teardown failures too, replace the phase test with:

if report.when not in {"setup", "call", "teardown"} or not report.failed:
    return

For setup failures, a driver may never have been created. For teardown failures, the driver may already be closing. Keep the driver is None check and the exception guard, and treat the image as best-effort evidence.

Fixture ordering and reliable artifact handling

Keep the browser alive until capture finishes

A hook cannot capture a closed session. If a fixture’s finalizer calls driver.quit() before the report hook runs, move capture into a fixture finalizer that executes before quit, or change the integration so the report hook has access to the live driver. The correct placement depends on your fixture scopes and plugin ordering; verify it with a deliberately failing test.

Avoid overwritten files

  • Use item.nodeid, not only item.name; parameterized cases can share a name.
  • Replace slashes, brackets, spaces, and other unsafe characters before writing.
  • Include the pytest-xdist worker ID when tests run in parallel. Store each worker in a separate directory if your CI collects artifacts concurrently.
  • Create the directory before saving and check the Boolean result from save_screenshot.

Do not mask the original failure

WebDriver capture can raise a driver exception, and filesystem permissions or a full disk can make saving fail. Log the capture problem, but never raise it from the report hook in a way that hides the assertion, exception, or stack trace that caused the test failure. A missing screenshot should be visible in CI diagnostics without changing the test’s outcome.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
Sale
Dell 24 Monitor - SE2426H - 23.8-inch FHD (1920x1080) 144Hz 1ms Display, in-Plane Switching (IPS) Technology, AMD FreeSync™, TÜV 3-Star 2X HDMI, Tilt
  • Clear visuals. Fluid motion: A 144Hz refresh rate and 1ms MPRT deliver smooth, tear‑free motion across work, gaming, and streaming for clearer, more fluid viewing.
  • Eye comfort: TÜV Rheinland 3‑star* certification reduces harmful blue light while preserving stunning color quality without compromise. *TÜV Rheinland 3-star eye comfort certification.
  • Wide viewing angle: Get consistent views across a wide 178° /178° viewing angle.
  • In-Plane Switching (IPS): See excellent color accuracy and consistency across wide viewing angles with In-plane Switching (IPS) technology.
  • Ultra-thin bezels: Maximize your viewing experience with thin bezels.

Attach bytes or Base64 instead of writing a file

Files are convenient for CI retention. Report portals often prefer an in-memory attachment. Python Selenium can return PNG bytes or a Base64 representation; use the form your reporter accepts:

# Inside the failure branch, while driver is still alive
png_bytes = driver.get_screenshot_as_png()
encoded = driver.get_screenshot_as_base64()
# Pass png_bytes or encoded to your report plugin's attachment API.

Do not assume that an attachment API closes or owns the WebDriver; capture first, then perform teardown. If you need both a file and an embedded image, capture once to bytes and write those bytes yourself, or use one Selenium call for each deliberately.

A complete pytest example

# test_login.py
def test_invalid_login(driver):
    driver.get("https://example.test/login")
    driver.find_element("id", "username").send_keys("wrong-user")
    driver.find_element("id", "password").send_keys("wrong-password")
    driver.find_element("css selector", "button[type='submit']").click()
    assert "Account locked" in driver.page_source

Run it with pytest -q. On failure, look under test-artifacts/screenshots/ and configure your CI system to retain that directory. Use a stable test URL or your own application in real tests; the example is illustrative.

Java: use the stack your project already has

Raw Selenium with a listener or rule

In Java, cast the driver to TakesScreenshot and choose an output target:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Samsung 27" Essential S3 (S36GD) Series FHD 1800R Curved Computer Monitor
  • CURVED FOR ENHANCED ENGAGEMENT: An immersive viewing experience with a curved monitor that wraps more closely around your field of vision; It creates a wider view, enhancing depth perception and minimizing peripheral distraction
  • SMOOTH PERFORMANCE FOR SEAMLESS CONTENT: Stay in the action when playing games, watching videos, or working on creative projects; The 100Hz refresh rate reduces lag and motion blur so you don't miss a thing in fast-paced moments¹
  • MORE GAMING POWER: Gain the edge with optimizable game settings; Color and image contrast can be adjusted to see scenes more vividly and spot enemies hiding in the dark; Game Mode adjusts any game to fill the screen so you can view every detail²
  • KEEP IT EASY ON THE EYES: Care for your eyes and stay comfortable, even during long sessions; Advanced eye comfort technology certified by TÜV reduces eye strain by minimizing blue light and reducing irritating screen flicker²
  • INCREASED VERSATILITY: Connect to more; Plug devices straight into your monitor for increased flexibility, making your computing environment even more convenient
File source = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
Files.createDirectories(Path.of("test-artifacts/screenshots"));
Files.copy(source.toPath(), Path.of("test-artifacts/screenshots", "failed-test.png"),
           StandardCopyOption.REPLACE_EXISTING);

Put this call in the failure callback supplied by your JUnit or TestNG integration, before the driver is quit. The interface documents capture and possible capture exceptions (TakesScreenshot). A production listener must generate unique names and catch copy or WebDriver errors without replacing the test exception.

Selenide

If the project already uses Selenide, its documentation says screenshots are automatically taken when some Selenide checks fail. It also documents a JUnit 4 ScreenShooter.failedTests() rule and a TestNG ScreenShooter listener (Selenide screenshot documentation). This behavior is framework-specific: automatic capture for Selenide checks does not prove that every assertion source or custom listener failure will be captured. Confirm the coverage and output location for your installed version.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Diagnosing common failures

No image appears

  • Driver is missing: the fixture did not attach it to the item, or setup failed before creation. Expose the driver consistently and accept that some setup failures have no browser state.
  • Driver is closed: teardown ran first. Move capture earlier or change finalizer/listener ordering.
  • Directory is absent: call mkdir(parents=True, exist_ok=True) or create it in CI.
  • Permission or disk error: check the workspace permissions and available space; honor the method’s False result.

The wrong phase is captured

Inspect report.when. Select call for test-body failures, or include setup and teardown intentionally. A teardown report may describe cleanup rather than the page state that caused an earlier failure.

Images overwrite one another

Use the complete node ID, sanitized parameter values, and a worker identifier. In CI, preserve worker directories rather than letting parallel processes write the same filename.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
Sale
Sceptre New 22-Inch Gaming Monitor, FHD 1080p, Up to 144Hz, HDMI, DisplayPort, Built-in Speakers, Machine Black (E225W-FW144 Series, 2026)
  • 【INTEGRATED SPEAKERS】Whether you're at work or in the midst of an intense gaming session, our built-in speakers provide rich and seamless audio, all while keeping your desk clutter-free.
  • 【EASY ON THE EYES】 Protect your eyes and enhance your comfort with Blue-Light Shift technology. This feature reduces harmful blue light emissions from your screen, helping to alleviate eye strain during long hours of use and promoting healthier viewing habits.
  • 【WIDEN YOUR PERSPECTIVE】Our sleek minimal bezel design ensures undivided attention. The nearly bezel-free display seamlessly connects in a dual monitor arrangement, delivering an unobstructed view that lets you focus on more at once, completely distraction-free.

The screenshot is blank or irrelevant

Capture is a view of the current window, not a timeline. Wait for the condition your test needs before asserting, and capture immediately after the failure report is made. Pair the image with logs, the assertion text, URL, and page source when diagnosing timing or navigation problems.

Capture errors hide useful diagnostics

Wrap capture and file writes in a narrow exception handler that reports the artifact error separately. Never convert a screenshot problem into the primary test failure.

Performance, reliability, and CI choices

  • Capture only failures: it keeps artifact volume and storage lower than taking an image for every test.
  • Use bytes for report embedding: it avoids a second file-management path, while files are easier for generic CI artifact collectors.
  • Keep names deterministic but unique: deterministic names simplify links; parameter and worker components prevent collisions.
  • Validate after upgrades: the Selenium Python API page used here is for Selenium 4.49.0, while the Java API link is version 4.28.0. Confirm signatures and listener behavior against the versions installed in your project.
  • Test the failure path: add one intentionally failing test in a safe branch and verify that the browser is live, the image opens, and CI retains it.

Or skip the browser setup

If you need a rendered image of a URL outside a WebDriver test, ScreenshotNeo provides a one-request screenshot API and an MCP server for AI agents. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status.

Read the parameter and response details in the ScreenshotNeo documentation. A minimal call is:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo also offers an MCP server with take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. Every plan includes its options, including full-page and element capture, device and retina settings, PDF output, custom CSS or JavaScript, waits, request blocking, headers and cookies, geolocation, caching, signed links, asynchronous webhooks, bulk capture, and a usage API. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.

Frequently Asked Questions

Can Selenium capture an element instead of the whole window?

Element-level capture support depends on the driver and language API you use; verify the installed Selenium binding. The patterns here capture the current window.

Should I capture setup, call, and teardown failures?

Choose phases deliberately. Test-body failures use call; include the other phases only when their diagnostics matter and a live driver is available.

Is a screenshot enough to debug a flaky test?

No. Keep the assertion and exception details, URL, and relevant logs or page source alongside the image.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.