Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Use Selenium 4’s WebDriver screenshot API after navigating to the page and waiting for the state you want to document. In Python, driver.save_screenshot("artifacts/home.png") writes a PNG; in Java, cast the driver (or a supported element) to TakesScreenshot and call getScreenshotAs. A normal driver screenshot is the current viewport. Element screenshots and full-document images are separate cases with different support.
Choose the screenshot scope and output
Decide these two things before writing code:
- Viewport: captures the current browser window as displayed.
- Element: captures a located
WebElement, when the browser binding implements element screenshots. - Full page: captures the document beyond the viewport. This is binding- and browser-specific rather than a universal WebDriver operation.
Your output can be a file for CI artifacts, bytes for image processing, or Base64 for an HTML report. Keep the driver on the intended window, frame and scroll position: the screenshot describes the current browsing context.
| Need | Python | Java |
|---|---|---|
| PNG file | save_screenshot(path) or get_screenshot_as_file(path) |
getScreenshotAs(OutputType.FILE) |
| Image in memory | get_screenshot_as_png() |
Use an appropriate OutputType |
| Base64 for HTML | get_screenshot_as_base64() |
getScreenshotAs(OutputType.BASE64) |
| Element image | Use the element screenshot method when supported by the binding/browser | WebElement is a documented TakesScreenshot subinterface |
| Full document | Firefox exposes dedicated full-page methods | Check the target browser and binding; support is not uniform |
Python: save a Selenium 4 screenshot to a file
The file methods save the current window as PNG. They do not create a missing directory, so create it first and use a deterministic name in automation.
from pathlib import Path
from selenium import webdriver
from selenium.common.exceptions import WebDriverException
output = Path("artifacts")
output.mkdir(parents=True, exist_ok=True)
path = output / "home.png"
driver = webdriver.Chrome()
try:
driver.get("https://example.com")
# Replace this with an explicit wait for the state your test needs.
ok = driver.save_screenshot(str(path))
if not ok:
raise IOError(f"Selenium could not write {path}")
print(f"Saved {path}")
except WebDriverException as exc:
print(f"Browser screenshot failed: {exc}")
raise
finally:
driver.quit()
save_screenshot and get_screenshot_as_file return True on success and False for an I/O error. Prefer an absolute path in CI when the runner’s working directory is uncertain, and end the name in .png.
#1 Best Overall
Use the alternative Python file method
ok = driver.get_screenshot_as_file("/absolute/path/artifacts/home.png")
if not ok:
raise IOError("Screenshot was not written")
Both methods represent the current window. They do not automatically wait for an application to finish rendering. Add an explicit wait for a meaningful element, state or network-driven condition before capturing.
Python: keep the image in memory
Use bytes when another library will process the image, and Base64 when an HTML report needs an inline image.
png_bytes = driver.get_screenshot_as_png()
with open("artifacts/home.png", "wb") as image:
image.write(png_bytes)
base64_text = driver.get_screenshot_as_base64()
html_img = f'
'
The bytes and Base64 methods avoid a temporary screenshot file. They still capture the current viewport and can raise a WebDriver exception if the implementation cannot take screenshots.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minuteJava: use TakesScreenshot and OutputType
Selenium’s Java API exposes screenshot capture through TakesScreenshot, which can be implemented by a driver or a supported HTML element. Choose the output type that matches your workflow.
Rank #2
import java.io.File;
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;
import org.openqa.selenium.WebDriverException;
WebDriver driver = new ChromeDriver();
try {
driver.get("https://example.com");
File temporary = ((TakesScreenshot) driver)
.getScreenshotAs(OutputType.FILE);
Path destination = Path.of("artifacts", "home.png");
Files.createDirectories(destination.getParent());
Files.copy(temporary.toPath(), destination,
StandardCopyOption.REPLACE_EXISTING);
} catch (WebDriverException e) {
throw e;
} finally {
driver.quit();
}
OutputType.FILE gives you a temporary file to copy into a stable artifact location. Java also supports Base64:
String screenshotBase64 = ((TakesScreenshot) element)
.getScreenshotAs(OutputType.BASE64);
Use OutputType.BASE64 for inline reports or transport, and another supported output type when your binding provides it. The API can throw UnsupportedOperationException when the underlying implementation does not support screenshots; handle that separately from a filesystem failure.
Capture one element
An element screenshot is not the same as a driver screenshot. Locate the element after the page has reached the required state, then call the element’s screenshot method. Support depends on the browser and language binding.
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 →Python element example
from pathlib import Path
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
try:
driver.get("https://example.com")
card = WebDriverWait(driver, 15).until(
EC.visibility_of_element_located((By.CSS_SELECTOR, "main"))
)
Path("artifacts").mkdir(exist_ok=True)
ok = card.screenshot("artifacts/main.png")
if not ok:
raise IOError("Element screenshot was not written")
finally:
driver.quit()
The selector must identify the intended element, and the element must be rendered in the current browsing context. A hidden, detached or zero-size element can produce an error or an unusable image. Scroll it into view when the target browser requires that, and wait for images or fonts that affect the element’s final appearance.
Rank #3
Java element example
WebElement card = driver.findElement(By.cssSelector("main"));
File elementFile = ((TakesScreenshot) card)
.getScreenshotAs(OutputType.FILE);
Copy elementFile to your artifact path as you would with a driver screenshot. If the cast or call is unsupported, fall back to a viewport capture or use a browser/binding combination that documents element screenshots.
Full-page screenshots: what Selenium 4 actually guarantees
A standard driver.save_screenshot or getScreenshotAs call captures the current viewport, not necessarily the entire document. Full-page capture is a separate capability whose behavior varies by browser and binding.
Firefox Python binding
The Firefox Python binding documents dedicated methods such as get_full_page_screenshot_as_file and save_full_page_screenshot. Use the method exposed by the Selenium version installed in your project:
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchfrom pathlib import Path
from selenium import webdriver
Path("artifacts").mkdir(exist_ok=True)
driver = webdriver.Firefox()
try:
driver.get("https://example.com/long-page")
ok = driver.save_full_page_screenshot("artifacts/full-page.png")
if not ok:
raise IOError("Full-page screenshot was not written")
finally:
driver.quit()
Check the current Firefox binding’s method names and limitations before standardizing this in a cross-browser suite. A method available in Firefox Python should not be presented as a guarantee for Chrome, Edge, Java or another binding.
Rank #4
When you need cross-browser full-page output
Define what “full page” means for your product: the complete document, a stitched viewport sequence, or a print/PDF rendering. Compare the target browser’s current implementation, test fixed headers and lazy-loaded images, and verify that the resulting dimensions and scroll stitching meet your visual requirements. If exact behavior is critical, treat full-page capture as a browser-specific adapter rather than one universal Selenium call.
Wait for the right state before capturing
- Navigate to the URL.
- Wait for a stable, meaningful condition, such as visibility of the component under test.
- Switch to the intended window and frame; screenshots are scoped to the current browsing context.
- Choose viewport, element or the browser-specific full-page method.
- Write to a unique, stable path or keep bytes in memory.
- Check Boolean file results and catch WebDriver exceptions.
For dynamic pages, also account for animations, cookie dialogs, lazy images, web fonts and asynchronous data. A screenshot taken immediately after get can be valid but visually incomplete.
Troubleshooting common failures
| Symptom | Likely cause | Fix |
|---|---|---|
File method returns False |
Path or filesystem I/O problem | Create the directory, use a writable absolute path, ensure the filename ends in .png, and check the return value. |
| No screenshot method on the object | Unsupported driver, element or binding operation | Use a documented TakesScreenshot target, update compatible Selenium/browser components, or choose a supported capture scope. |
| Image shows a loading screen | Capture happened before the page state was ready | Add an explicit wait for the element or condition that proves readiness; control animations where practical. |
| Element image is blank or clipped | Element is hidden, detached, zero-size or outside supported rendering behavior | Wait for visibility, re-locate after DOM changes, scroll into view, and test the binding/browser’s element support. |
| Only the visible portion appears | Driver screenshot is a viewport capture | Use the target binding’s full-page method, or implement a tested browser-specific strategy. |
Java reports UnsupportedOperationException |
Underlying implementation does not provide screenshots | Switch to a supported driver/browser or change the capture approach; do not treat it as a PNG path error. |
| Different results in CI | Different viewport, device scale, fonts, browser or current window/frame | Set these deliberately, wait for stable content, and record browser and binding versions with the artifact. |
Reliability, performance and artifact design
- Stable names: Include test name, browser and a timestamp or run identifier to prevent parallel jobs overwriting one another.
- Failure capture: Take a viewport screenshot in a test teardown path, but guard against a closed session and preserve the original test exception.
- Size: Full-page images consume more memory and storage than viewport or element images. Use element capture when the diagnostic question concerns one component.
- Determinism: Fix window dimensions and relevant browser settings, wait for fonts and data, and disable transitions if pixel comparison is the goal.
- Security: Screenshots can contain credentials, personal data and tokens rendered in the page. Restrict artifact access and redact before sharing.
- Parallelism: Give each worker its own output directory or collision-resistant filename.
Or skip the browser setup
If you need a clean website image rather than an interactive Selenium session, ScreenshotNeo provides a website screenshot API and MCP server. It accepts a URL and returns PNG, JPEG, WebP or PDF. Before capture it accepts cookie/consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups and chat widgets; each step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers.
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 API documentation for parameters and response details. 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 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 also offers full-page and element capture, device presets and custom viewports, retina scale, PDF controls, custom CSS and JavaScript, clicks, waits, request blocking, headers, cookies, user agents, timezone and geolocation, transparent backgrounds, resizing, configurable caching, signed links, asynchronous jobs, webhooks, bulk capture of up to 100 URLs per call, a usage API and an OpenAPI specification. Its MCP server exposes take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients.
Best Value
The Free plan includes 1,000 shots per month with no card. Paid plans start at $5 for 3,000 shots; yearly billing gives two months free, and every feature is on every plan. Create a free ScreenshotNeo account to try it.
FAQ
Does Selenium 4 save screenshots as JPEG?
The documented Python file methods save PNG screenshots. If another format is required, capture PNG bytes and convert them with an image-processing library after capture.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Can a screenshot include a different tab?
Only the current window handle is captured. Switch to the required window before taking the image, then restore the original handle if the test continues.
Should screenshots be taken before or after quitting the driver?
Before quitting. Once the session is closed, screenshot commands cannot describe the page.
Frequently Asked Questions
Can I capture a screenshot while a WebDriver alert is open?
A modal alert changes what commands the browser accepts. Handle or dismiss the alert according to your test flow before attempting capture, and verify behavior with the specific driver you support.
Why is my screenshot the wrong size on a high-density display?
The resulting pixel dimensions depend on browser window size and device scale. Set the window and scale deliberately in the test environment, then compare images produced under the same settings.
Free tools Windows power users keep installed
One-click scans. No signup required.
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.

