When Selenium does not save a screenshot where you expect, first distinguish a capture failure from a file-write failure. In Python, pass an absolute filename ending in .png, create the parent directory yourself, verify that the process can write there, and check the method’s Boolean result. save_screenshot() and get_screenshot_as_file() return True after a successful write and False for an I/O error; a Selenium exception instead indicates a capture or driver problem.
The reliable Python fix
Selenium does not promise to create missing parent directories. Create the directory before calling the screenshot method and use an absolute path so an IDE, test runner, notebook, CI job, or container cannot silently change the destination.
from pathlib import Path
from selenium import webdriver
output_dir = Path("/absolute/path/to/screenshots")
output_dir.mkdir(parents=True, exist_ok=True)
output_file = output_dir / "page.png"
driver = webdriver.Chrome()
try:
driver.get("https://example.com")
saved = driver.save_screenshot(str(output_file))
if not saved:
raise OSError(f"Selenium could not write screenshot to {output_file}")
print(f"Saved {output_file}")
finally:
driver.quit()
The filename is the complete destination, not merely a directory. A call such as driver.save_screenshot("screenshots") is wrong because Selenium expects a file path. A filename without .png may also make the resulting artifact confusing to identify, so follow Selenium’s documented recommendation to use a full path ending in .png.
Read the result before changing your test
True or False in Python
Both Python file-saving methods return a Boolean. True means the PNG bytes were written to the supplied filename. False means the binding encountered an operating-system I/O error while opening or writing that file. A call that returns without raising is therefore not proof that the file exists.
#1 Best Overall
An exception during capture
If Selenium raises an exception while taking the screenshot, investigate the browser, driver, or WebDriver implementation before inspecting the destination directory. The Java API documents WebDriverException for capture failures and UnsupportedOperationException when screenshot capture is unsupported. This is a different branch from a successful capture followed by a local write error.
Log the exact path
from pathlib import Path
path = Path("screenshots/page.png").expanduser().resolve()
print("Working directory:", Path.cwd())
print("Screenshot path:", path)
print("Parent exists:", path.parent.exists())
print("Parent writable:", path.parent.is_dir())
resolve() shows where a relative path would actually land. The last check confirms that the parent is a directory; on systems where you need a definitive permission check, attempt a small temporary-file write as the same user that runs Selenium.
Use an explicit, writable destination
Create the parent directory
The Python implementation opens the exact filename in binary-write mode. It does not create missing folders. Use Path.mkdir(parents=True, exist_ok=True), or create the directory in your test fixture or CI setup.
Check operating-system filename rules
Use a filename valid for the machine doing the writing. Windows rejects characters such as :, *, and ?; Unix-like systems reject a slash inside one filename component. Also check that the account running the browser test has write permission and that an existing file is not read-only or locked by another process.
Avoid accidental relative paths
Relative paths are resolved from the test process’s current working directory, which may differ from the project folder shown in an editor. Print Path.cwd() and prefer a configured absolute artifact directory in repeatable jobs.
Separate capture from storage when necessary
Save PNG bytes yourself
If the convenience method’s file write is the failing part, obtain the bytes and control the storage operation directly:
from pathlib import Path
from selenium import webdriver
path = Path("/absolute/path/to/screenshots/page.png")
path.parent.mkdir(parents=True, exist_ok=True)
driver = webdriver.Chrome()
try:
driver.get("https://example.com")
png = driver.get_screenshot_as_png()
path.write_bytes(png)
finally:
driver.quit()
get_screenshot_as_png() returns the PNG bytes. get_screenshot_as_base64() provides an encoded form when your next step is a message, database record, or artifact API rather than a local file. In either case, the browser capture and your storage operation are separate, so log failures from each step independently.
Use unique names in parallel tests
When several tests write to one directory, include a test identifier, timestamp, or worker identifier in each filename. Otherwise, two successful writes can overwrite one another and look like a missing-screenshot problem. Create the directory once during setup and still check each individual write result.
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 minuteJava: obtain the temporary file, then copy it
Java’s TakesScreenshot API can return a File through OutputType.FILE. Copy that file to your chosen directory as a second, explicit filesystem operation.
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class ScreenshotExample {
public static void main(String[] args) throws IOException {
Path destination = Path.of("/absolute/path/to/screenshots/page.png");
Files.createDirectories(destination.getParent());
WebDriver driver = new ChromeDriver();
try {
driver.get("https://example.com");
File source = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
Files.copy(source.toPath(), destination, StandardCopyOption.REPLACE_EXISTING);
System.out.println("Saved " + destination);
} finally {
driver.quit();
}
}
}
If getScreenshotAs throws, troubleshoot driver support or capture first. If it succeeds but Files.copy throws, inspect the destination directory, permissions, filename, and the Java process’s filesystem.
Rank #3
Local, remote, CI, and container paths
A path belongs to the machine on which the test code performs the write. With a local driver, that is normally your workstation. With Selenium Grid, a hosted WebDriver, a CI worker, or a container, the path may belong to that worker instead. A file saved successfully in a container is not automatically present on your laptop.
- Print the resolved path and hostname in the test job.
- Inspect the worker or container filesystem, not only the machine from which you launched the test.
- Configure the CI system’s artifact upload step for the screenshot directory.
- For a remote provider, follow that provider’s documented artifact-transfer mechanism; WebDriver itself does not define a universal local-download behavior for every hosted Grid.
If you need storage controlled by your application, use get_screenshot_as_png() or Base64 and upload the returned data through your own artifact or object-storage client.
Free tools Windows power users keep installed
One-click scans. No signup required.
What Selenium’s screenshot actually captures
The screenshot is taken from the current WebDriver or WebElement browsing context. A normal driver screenshot is not a universal promise of a complete, vertically stitched page in every browser, driver, and language binding. If the file exists but the image appears to omit content below the viewport, verify the specific browser, driver, binding, and any full-page API it supports; do not treat that visual limitation as a directory-write failure.
Capture the intended page before saving: navigate to the correct URL, wait for the state your test requires, and ensure the relevant window or frame is active. Those steps affect image content, while the path checks above determine whether the resulting PNG reaches disk.
Systematic troubleshooting
| Symptom | Likely location of failure | What to do |
|---|---|---|
| A Selenium exception is raised by the screenshot call | Browser, driver, or unsupported screenshot operation | Read the exception, confirm the driver is alive, update or match browser and driver versions, and verify that the implementation supports screenshots. |
The Python call returns False |
Local file I/O | Use an absolute .png filename, create the parent, check permissions and free space, and validate the filename for the operating system. |
| No exception, but no file is visible | Wrong working directory or different machine | Print Path.cwd() and the resolved path; then inspect the CI worker, Grid node, or container that ran the code. |
| The path names a directory | Destination is not a file | Append a filename such as page.png; Selenium’s argument must be the complete file path. |
| Only one of many expected files remains | Filename collisions | Give each test or worker a unique filename and avoid concurrent writes to one path. |
| The PNG exists but is not full page | Capture-scope behavior | Check the browser and driver support for full-page capture. A regular screenshot is tied to the current browsing context and may be viewport-sized. |
| Java returns a file but the destination is empty or missing | Copy step or destination path | Create the destination directory, handle the Java I/O exception, and verify the source file and destination on the same execution machine. |
Reliability, timing, and cost considerations
- Wait for the right state: a successful write can still contain an incomplete page if navigation, fonts, images, or application rendering has not finished. Use your normal explicit waits before capture.
- Keep capture and write logs separate: record the URL, resolved filename, return value or exception, and execution host. This makes a driver failure distinguishable from an artifact-upload failure.
- Do not assume a screenshot is free of storage limits: large PNGs consume disk and CI artifact quota. Reuse a controlled directory and apply your retention policy after the test has uploaded artifacts.
- Close the driver in a
finallyblock: this prevents abandoned browser processes from complicating later diagnosis.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server for developers. One GET request returns a PNG, JPEG, WebP, or PDF, so there is no Selenium driver, browser binary, or local screenshot directory to configure.
Rank #4
For the API parameters and response details, see the ScreenshotNeo documentation. A direct call looks like this:
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
The same request in 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)
And in 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}`);
ScreenshotNeo accepts cookie and consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup 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. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.
For automated jobs, you can request full-page capture with lazy images loaded, a CSS-selected element, dark mode, device or custom viewport, retina scale, waits, custom headers and cookies, user-agent or authorization, geolocation and timezone, blocked resources, custom JavaScript or CSS, transparent backgrounds, resizing, a chosen cache TTL, signed image links, asynchronous webhooks, bulk capture of up to 100 URLs per call, and usage reporting. These controls let you replace browser setup only when they match the behavior your test needs.
The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 screenshots; every feature is on every plan, and annual billing provides two months free. Create a free ScreenshotNeo account to try the API without a card.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.FAQ
Can I prove which process wrote a screenshot?
Log the resolved filename, process or worker identifier, and host alongside the screenshot. In remote execution, this establishes whether the file was written on a Grid node, CI worker, or container rather than on your workstation.
Recommended Free Tools
Should I overwrite an existing screenshot?
Overwrite deliberately with a stable name when you want one latest artifact. For debugging parallel or repeated runs, generate unique names so a later test cannot conceal an earlier result.
Best Value
What should I store when a file system is unavailable?
Capture PNG bytes or Base64 from Selenium and send them to an artifact service or other storage you control. This keeps browser capture independent from the destination filesystem.
Frequently Asked Questions
Can I prove which process wrote a screenshot?
Log the resolved filename, process or worker identifier, and host alongside the screenshot. In remote execution, this establishes whether the file was written on a Grid node, CI worker, or container rather than on your workstation.
Should I overwrite an existing screenshot?
Overwrite deliberately with a stable name when you want one latest artifact. For debugging parallel or repeated runs, generate unique names so a later test cannot conceal an earlier result.
What should I store when a file system is unavailable?
Capture PNG bytes or Base64 from Selenium and send them to an artifact service or other storage you control. This keeps browser capture independent from the destination filesystem.
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.

