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.

The correct Selenium screenshot method depends on what you need to prove. Use driver.save_screenshot() for the current browser window, element.screenshot() for one WebElement, and a driver-specific full-document method when you need the entire scrollable page. Create the destination directory, use a predictable window size, wait for a meaningful application-ready condition, and check the method’s return value before treating the artifact as valid.

Choose the screenshot scope first

“A screenshot” can mean several different artifacts. Selecting the scope before writing code prevents a common mistake: calling a current-window API and assuming it captured the whole document.

Need Python approach Important qualification
Visible browser window driver.save_screenshot(path) or driver.get_screenshot_as_file(path) Documented as a current-window PNG capture; check the Boolean save result.
One component element.screenshot(path) Locate a WebElement first; the documented file output is PNG.
Entire scrollable document Firefox Python full-page methods Use the API documented for your driver; universal full-page support is not established.
Bytes for a report or upload get_screenshot_as_png() or a Base64 getter Keep the image in memory instead of writing a file immediately.

Capture the current browser window in Python

For the usual test artifact, save a PNG after navigation and after the page reaches a condition that matters to your application. The example below uses Selenium’s Python API and performs explicit cleanup.

from pathlib import Path
from selenium import webdriver
from selenium.webdriver.common.by import By

Path("screenshots").mkdir(parents=True, exist_ok=True)
driver = webdriver.Chrome()
try:
    driver.set_window_size(1440, 1000)
    driver.get("https://example.com")

    saved = driver.save_screenshot("screenshots/page.png")
    if not saved:
        raise OSError("Could not save screenshot")

    heading = driver.find_element(By.TAG_NAME, "h1")
    if not heading.screenshot("screenshots/heading.png"):
        raise OSError("Could not save element screenshot")
finally:
    driver.quit()

Use a full path when a test runner’s working directory may vary. Selenium’s file methods return False on an I/O failure, so a test should fail loudly rather than publishing a missing or stale image. A .png extension matches the documented file capture.

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

Set dimensions deliberately

driver.set_window_size(width, height) accepts pixel dimensions, and Selenium also provides a getter. Fix the browser, driver, execution environment, and target dimensions when comparing screenshots over time. Window size is not guaranteed to equal the CSS viewport in every desktop or headless configuration, so record the environment if pixel-level comparisons matter.

Wait for a real ready condition

Navigation completion alone may occur before an application has rendered data, opened a modal, or finished an asynchronous transition. Prefer a meaningful condition such as the presence and visibility of a result element, a known loading indicator disappearing, or an application-specific state. An arbitrary sleep is not a universal screenshot fix: it can be too short on a slow run and waste time on a fast one.

Capture a single WebElement

When the evidence should contain only a card, chart, heading, form, or error banner, locate that element and call its screenshot method:

from selenium.webdriver.common.by import By

card = driver.find_element(By.CSS_SELECTOR, "[data-testid='invoice-card']")
if not card.screenshot("screenshots/invoice-card.png"):
    raise OSError("Element screenshot could not be written")

This produces a PNG for the located WebElement, not a screenshot of every matching element and not a crop of an arbitrary selector string. If the element is absent, the locator raises an exception; if it is present but outside the expected state, wait for the state your test is asserting before capturing.

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

Element-capture edge cases

  • An element covered by a modal, animation, or sticky layer may not represent the state you intended. Wait for overlays to disappear or for the relevant class/attribute to change.
  • Responsive layout can alter the element’s dimensions. Set the window size before navigation and use the same browser mode in comparison runs.
  • For a report that needs context, capture both the element and the current window, using distinct filenames so one does not overwrite the other.

Capture a full-page document

Do not describe driver.save_screenshot() as a universal full-page solution. The generic WebDriver Python documentation describes current-window capture. The Firefox Python API separately lists full-document methods, including get_full_page_screenshot_as_file, save_full_page_screenshot, and byte/Base64 variants.

Firefox-specific methods

Use the full-document call documented for the Selenium and Firefox versions installed in your project, then verify the output just as you would for a window screenshot. API and driver support can evolve, so confirm the method name against the version you actually run rather than copying a call intended for another browser.

A full-document image can be very tall. Consider whether a single image is usable in a CI report; for long pages, an element capture, a PDF, or several evidence points may be easier to inspect. Lazy-loaded content may also require scrolling or an application-level trigger before capture; Selenium’s screenshot API does not by itself guarantee that every deferred image has loaded.

Use screenshot bytes in a test report

If your reporting system accepts binary data, avoid a temporary file:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
png_bytes = driver.get_screenshot_as_png()
with open("screenshots/page-from-bytes.png", "wb") as image_file:
    image_file.write(png_bytes)

The same API family exposes Base64 output for systems that embed images as text. Keep the byte capture close to the failure or assertion that it explains, and give the resulting artifact a run- or test-specific name.

Attach screenshots to failing pytest tests

pytest-selenium’s documented debug capture is failure-oriented by default. Its configuration can select never, failure, or always, and reports can exclude screenshots and other collected data. Failure-only capture is usually a practical balance: it preserves evidence when an assertion fails without making every successful run larger.

Choose a collection policy

  • Failure: the documented default; useful for diagnosing unexpected states.
  • Never: appropriate when screenshots may contain secrets or when artifact retention is not allowed.
  • Always: useful for visual auditing, but it can greatly increase report size and data exposure.

Decide whether HTML, logs, and images may contain personal, financial, or authentication data. Configure report exclusions where needed, and apply the same retention and access controls to screenshots as to test logs.

Make captures reproducible

Control the execution environment

  • Pin or record Selenium, browser, and driver versions. The referenced Selenium Python WebDriver and Firefox API pages identify 4.49.0, while the WebElement page identifies 4.33.0; your installed versions may differ.
  • Use a fixed window size and consistent headless or headed mode.
  • Use deterministic test data and stable account state.
  • Capture after a semantic readiness condition, not a guessed delay.
  • Store artifacts outside source control unless they are intentional fixtures.

Name files so parallel runs do not collide

Include the test name, browser, viewport, and a run identifier in the filename. Create the directory before the driver starts. In parallel CI, give each worker its own artifact directory or use a collision-resistant name.

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

Troubleshooting common failures

The file is missing or empty

Check that the parent directory exists, the process can write there, and the path is absolute or resolved from a known working directory. Check the Boolean returned by the file method and fail the test when it is False. Also verify that a later cleanup step is not deleting the artifact.

The image shows the wrong responsive layout

Set the window size before loading the URL and keep browser mode, operating system, and driver configuration consistent. Remember that outer window dimensions and CSS viewport dimensions are not identical in every environment.

The screenshot is taken before content appears

Replace a fixed sleep with an explicit wait for the result, visible element, disappeared spinner, or application state that defines “ready” for your test. If the page uses lazy loading, trigger the documented application behavior before capturing.

Only the visible portion of a long page is present

You used the generic current-window API or a browser that does not expose the full-document method you expected. Select a driver-specific full-page capability—Firefox documents one—or capture the relevant elements separately.

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

An element screenshot fails to locate the target

Confirm the locator, frame, and window. Switch into the correct iframe before finding the element, wait for it to exist and become visible, and ensure the page has not navigated away.

Reports have become too large

Change collection from always to failure, exclude screenshots or other debug data where policy allows, and set retention limits in your CI system. Screenshots can contain more sensitive content than a short assertion message.

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

When Selenium is the wrong capture boundary

Selenium is appropriate when the screenshot must be tied to an interactive browser session, a test assertion, or a particular authenticated state. For a service that repeatedly captures public URLs, a screenshot API can remove browser provisioning and artifact plumbing. Compare the required control—cookies, headers, viewport, waiting, PDF output, or retries—with the cost of maintaining your own browser workers.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server for developers. One GET request returns PNG, JPEG, WebP, or PDF. Its cleanup step accepts cookie and consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and each response identifies the result with X-Page-Verdict and X-Billed headers.

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

Here is a one-call cURL capture (the parameter names commonly used by other screenshot APIs also work):

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo documentation for the complete option set and response behavior.

Python

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)

Node.js

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

Controls available when a URL needs more than a default shot

  • Full-page capture with lazy images loaded, or one element selected by CSS selector.
  • Dark mode, 12 device presets, custom viewports, and retina scale.
  • PDF paper size, margins, landscape mode, and page ranges.
  • HTML/CSS-to-image, custom CSS and JavaScript, pre-capture clicks, hidden selectors, and waits for a selector, delay, or network idle.
  • Blocking for ads, trackers, requests, or resource types.
  • Custom headers, cookies, user agent, Authorization, timezone, and geolocation.
  • Transparent backgrounds, image resizing, selectable-TTL caching, signed public-image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, and an OpenAPI specification.
  • An MCP server with take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.

The Free plan includes 1,000 shots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is on every plan, and yearly billing gives two months free. Create a free ScreenshotNeo account to start without a card.

FAQ

Should I save PNG or use bytes?

Save a PNG when a human or CI artifact store needs a file. Use PNG bytes or Base64 when your report pipeline embeds the image directly.

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

Is Selenium’s screenshot automatically full page?

No. Treat the generic WebDriver call as current-window capture and verify a driver-specific full-document API for long pages.

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.