Free tools Windows power users keep installed
One-click scans. No signup required.
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.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →#1 Best Overall
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.
Recommended Free Tools
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.
Rank #2
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:
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.
Rank #3
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.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsTroubleshooting 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.
Rank #4
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.
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.
Best Value
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.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.
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, andcapture_pdffor 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.
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.
Quick Recap
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.

