Most Selenium screenshot problems are either a capture failure or a file-save failure. Start with an absolute, writable .png path, check Selenium’s Boolean result, and test get_screenshot_as_png() separately. That tells you whether the browser command or your filesystem is responsible.
Selenium’s Python WebDriver API describes a screenshot as an image of the current window. A call that appears to “fail” can actually mean several different things: an exception was raised, the method returned False, no file appeared, the file is empty or unreadable, the image is blank, or the image contains only the visible viewport. Each symptom needs a different check.
First, identify which part failed
Record the exact symptom before changing code. This quick split prevents you from debugging page loading when the real problem is a directory permission, or from debugging file I/O when the WebDriver session is already broken.
| Observed result | Likely layer | First check |
|---|---|---|
| WebDriver exception at the screenshot call | Browser, driver, session, or selected window | Keep the complete traceback and inspect the active session |
Method returns False |
Opening or writing the destination file | Use an absolute path, create its parent directory, and verify permissions |
| No file, but no exception | Relative path or unexpected working directory | Print the resolved path and the Boolean return value |
| Zero-byte or unreadable PNG | Incomplete write or filesystem issue | Try returning PNG bytes and writing them with Python |
| Image is valid but looks blank | Wrong page, wrong tab, rendering state, or a page that is genuinely blank | Print the URL and window handle immediately before capture |
| Only the top of a long page is present | Viewport capture rather than full-document capture | Use a full-page facility appropriate to your browser |
The Selenium API documents save_screenshot(filename) and get_screenshot_as_file(filename) as saving the current window to a PNG file. The latter returns a Boolean; its Python implementation returns False when opening or writing the path raises an OSError. A call that does not raise therefore does not automatically prove that a usable artifact exists.
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 errors#1 Best Overall
Use a known-good absolute path
Relative paths are resolved from the Python process’s current working directory, which can differ from the directory containing your script. Create the output directory explicitly and pass a resolved filename ending in .png.
from pathlib import Path
from selenium import webdriver
out = Path("artifacts/selenium-shot.png").resolve()
out.parent.mkdir(parents=True, exist_ok=True)
driver = webdriver.Chrome()
try:
driver.get("https://example.com")
print("url:", driver.current_url)
print("window:", driver.current_window_handle)
saved = driver.save_screenshot(str(out))
print("saved:", saved)
print("path:", out)
print("exists:", out.exists())
if out.exists():
print("bytes:", out.stat().st_size)
finally:
driver.quit()
This is a diagnostic pattern, not a guarantee about a particular machine. If saved is False, inspect the printed path, parent-directory permissions, available disk space, and whether another process has restricted the destination. If the method raises, preserve the full exception instead of replacing it with a generic “screenshot failed” message.
Separate browser capture from file writing
Selenium exposes the PNG payload independently through get_screenshot_as_png(). Use it when you need to determine whether WebDriver can produce image data at all.
from pathlib import Path
from selenium import webdriver
out = Path("artifacts/bytes-shot.png").resolve()
out.parent.mkdir(parents=True, exist_ok=True)
driver = webdriver.Chrome()
try:
driver.get("https://example.com")
png = driver.get_screenshot_as_png()
print("received bytes:", len(png))
with out.open("wb") as image_file:
image_file.write(png)
print("wrote:", out, "bytes:", out.stat().st_size)
finally:
driver.quit()
- If
get_screenshot_as_png()raises, investigate the WebDriver command, browser session, current window, and driver environment. - If it returns bytes but the path-based method returns
False, the browser capture works and the problem is at the filesystem boundary. - If Python writes the bytes successfully but an image viewer rejects the file, retain the byte count and inspect the generated artifact in the same environment where it was written.
Confirm the intended page and window
Both standard methods capture the current window. A test that opened a second tab, switched windows, closed the original tab, or navigated after the assertion can legitimately capture something other than the page you had in mind.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCrashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minute- Print
driver.current_urlimmediately before the screenshot. - Print
driver.current_window_handleand, when tabs are involved, inspectdriver.window_handles. - Switch explicitly to the intended handle before calling the screenshot method.
- Do not call
driver.quit()until after the screenshot and all file checks.
A valid PNG of the wrong tab is not a capture failure. Treat navigation and window selection as assertions in their own right.
Rank #2
Viewport capture is not full-page capture
The ordinary screenshot methods capture the current window’s rendered view. They do not promise a single image containing every document pixel below the fold. If the file exists and opens but the lower content is missing, distinguish that expectation from a save error.
Firefox provides a separately named full-document screenshot API. Do not assume that Firefox-only method is present in Chrome or in every Selenium language binding. For portable code, decide whether you need a viewport image or a browser-specific full-document operation before writing your test.
When diagnosing a viewport image, record the browser window size and whether the page uses lazy-loaded images. A screenshot can be valid while still omitting content that the page has not loaded or that lies outside the current viewport.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Keep environment details when an exception is raised
The title of the problem is not enough to identify a root cause. Save the complete exception together with:
- Selenium version (the current API documentation identifies Selenium 4.49.0).
- Browser and WebDriver versions.
- Operating system and architecture.
- Whether the browser is headless, and the exact headless arguments.
- The Python version and the complete, minimal code path.
- The resolved output path and its parent-directory permissions.
- The URL, active window handle, and whether the same code works in a visible browser.
These details let you distinguish a session or driver error from a page-specific rendering issue. Without the actual exception and environment, a more specific diagnosis would be speculation.
Common failure modes and fixes
The file is saved somewhere else
Symptom: the method reports success, but you cannot find the image. Fix: resolve the path with Path(...).resolve(), print it, create the parent directory, and inspect that exact location. The process working directory—not necessarily the script directory—controls a relative path.
get_screenshot_as_file() returns False
Symptom: no exception, Boolean result is false. Fix: treat it as a file I/O signal. Check that the parent exists, the process can write there, the filename ends in .png, and the destination is not a protected or unavailable mount. Use the byte-returning method to prove whether capture itself works.
Free tools Windows power users keep installed
One-click scans. No signup required.
The screenshot call raises a WebDriver exception
Symptom: execution stops at the command. Fix: retain the full traceback, then verify that the driver session is alive, the browser has not exited, and the selected window handle still exists. Compare a visible-browser run with the headless configuration and record all version numbers.
The image is blank or shows the wrong site
Symptom: a readable PNG contains an unexpected page. Fix: print the current URL and handle immediately before capture, switch to the intended tab, and verify that navigation reached the expected address. A blank page can be the actual response, a page still rendering, or a different window.
Below-the-fold content is missing
Symptom: the PNG opens but contains only the visible area. Fix: classify it as a viewport/full-document mismatch. Use the browser’s supported full-document mechanism when you require the entire page; do not infer a failed file write from image height alone.
Images or content are absent in a valid capture
Symptom: the page shell appears, but lazy images or late content do not. Fix: make the test wait for a page-specific condition before capture, and record whether the page relies on lazy loading. Keep the wait logic separate from the file-save check so each failure remains diagnosable.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Make screenshot artifacts reliable in automation
- Use a run-specific directory or filename so parallel jobs do not overwrite one another.
- Include the test name and a timestamp or unique identifier in the filename.
- Assert the Boolean result, file existence, and a non-zero size in CI.
- Upload the artifact only after the write check succeeds; preserve the traceback and environment log on failure.
- Keep capture and cleanup in a
try/finallyblock so a failed assertion still closes the browser. - For repeated captures, avoid unnecessary browser restarts, but do not reuse a session after a driver or browser crash.
A small validation helper can make failures explicit:
from pathlib import Path
def require_png(path: Path) -> None:
if not path.exists():
raise AssertionError(f"Screenshot was not created: {path}")
size = path.stat().st_size
if size == 0:
raise AssertionError(f"Screenshot is empty: {path}")
with path.open("rb") as file:
if file.read(8) != b"x89PNGrnx1an":
raise AssertionError(f"Not a PNG file: {path}")
This checks the artifact produced by your process; it does not diagnose a browser exception. Keep both kinds of evidence when reporting a failure.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
ScreenshotNeo provides a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF, so you do not have to install or manage a local browser for a straightforward URL capture. Its cleaning steps accept cookie or consent banners and remove more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be disabled.
For a direct call, see the ScreenshotNeo API documentation:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
The equivalent Python request is:
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://example.com"},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
ScreenshotNeo reports whether a response was a clean shot, a bot check or CAPTCHA, a blank page, a timeout, a failed load, or a cache hit through its response headers. Only clean shots are billed; those other outcomes and cache hits cost nothing. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.
Best Value
There are 1,000 free shots per month with no card. Paid plans start at $5 for 3,000 shots; yearly billing provides two months free, and every feature is available on every plan. Create a free ScreenshotNeo account to try the capture without a card.
FAQ
Should I keep screenshots from failed tests?
Yes. Save the artifact, resolved path, URL, window handle, and complete exception together. A screenshot can show the last rendered state even when a later assertion fails.
How can a CI job detect a corrupted artifact?
Check that the path exists, its size is greater than zero, and its first eight bytes match the PNG signature. Keep that validation separate from WebDriver exception handling.
Can I use the same diagnostic code for every browser?
The path and byte-versus-file checks are broadly useful, but full-document capture is browser-specific. Treat viewport behavior and browser-specific APIs as a separate compatibility decision.
Frequently Asked Questions
Should I keep screenshots from failed tests?
Yes. Save the artifact, resolved path, URL, window handle, and complete exception together. A screenshot can show the last rendered state even when a later assertion fails.
How can a CI job detect a corrupted artifact?
Check that the path exists, its size is greater than zero, and its first eight bytes match the PNG signature. Keep that validation separate from WebDriver exception handling.
Can I use the same diagnostic code for every browser?
The path and byte-versus-file checks are broadly useful, but full-document capture is browser-specific. Treat viewport behavior and browser-specific APIs as a separate compatibility decision.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →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.




