Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Selenium’s screenshot API does not have one universal “size” setting. First identify what you need: the visible browser viewport, one element’s visible region, or the entire scrollable page. Then measure three separate things in the same run: the requested window rectangle, the browser’s effective viewport, and the saved PNG dimensions. A driver screenshot is normally viewport-scoped; an element screenshot is scoped to that element’s visible bounding rectangle. The returned file, byte array, or Base64 string changes representation, not capture scope.
What “screenshot size” means in Selenium
Several independent dimensions are often confused:
- Capture scope: the visual viewport, a visible element, or a full scrollable document.
- Window geometry: the outer top-level browser window requested through WebDriver.
- Viewport geometry: the page area remaining after browser chrome and implementation constraints.
- Image dimensions: the pixel width and height encoded in the PNG, JPEG, or other image returned by the driver.
- Representation: a temporary file, raw bytes, or a Base64 string.
These values can differ. A requested window size is expressed in CSS pixels and includes browser chrome. Drivers may clamp it to a screen boundary, a minimum size, or headless-mode constraints. Therefore, setting setSize is not a guarantee that the output image will have exactly those pixel dimensions.
Choose the correct capture scope first
Visible viewport
Cast the driver to TakesScreenshot and call getScreenshotAs. The standards-defined driver screenshot represents the top-level browsing context’s visual viewport. It is not a promise to include content below the fold.
Outdated 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 matchPC 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 & 11One visible element
Use Selenium’s element screenshot operation when the target is a particular chart, card, banner, or form. The operation captures the visible region of that element’s bounding rectangle. It is a different scope from a driver screenshot; changing OutputType cannot turn one into the other.
The complete scrollable page
Do not infer full-page support merely from the document’s reported height. The standard viewport command does not certify a cross-browser full-document image. Full-page behavior is driver- and browser-specific, especially in headless and remote sessions. Verify the selected browser and version, and test the resulting image rather than assuming that a tall page equals a full-page screenshot.
#1 Best Overall
Use the Java API correctly
Save a viewport screenshot to a durable path
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 ViewportShot {
public static void main(String[] args) throws IOException {
WebDriver driver = new ChromeDriver();
try {
driver.get("https://example.com");
TakesScreenshot screenshot = (TakesScreenshot) driver;
File temporary = screenshot.getScreenshotAs(OutputType.FILE);
Path destination = Path.of("artifacts", "viewport.png");
Files.createDirectories(destination.getParent());
Files.copy(temporary.toPath(), destination,
StandardCopyOption.REPLACE_EXISTING);
System.out.println("Saved " + destination.toAbsolutePath());
} finally {
driver.quit();
}
}
}
OutputType.FILE returns a temporary file. Copy it before the JVM exits if the image must remain available; Selenium’s temporary result is deleted when the JVM terminates.
Use bytes or Base64 when that is the real requirement
byte[] png = ((TakesScreenshot) driver)
.getScreenshotAs(OutputType.BYTES);
String base64 = ((TakesScreenshot) driver)
.getScreenshotAs(OutputType.BASE64);
These forms are useful for an HTTP upload, database blob, test attachment, or an inline report. They do not request a larger, smaller, full-page, or element-only capture. If an image is malformed or missing, debug the representation and persistence path separately from width and height.
Capture a visible element
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
WebElement card = driver.findElement(By.cssSelector(".pricing-card"));
File temporary = card.getScreenshotAs(OutputType.FILE);
Path target = Path.of("artifacts", "pricing-card.png");
Files.createDirectories(target.getParent());
Files.copy(temporary.toPath(), target, StandardCopyOption.REPLACE_EXISTING);
The element must be present and the driver must support element screenshots. The result is tied to the element’s visible bounding rectangle, not the entire document and not necessarily every part hidden outside the viewport.
Rank #2
Set window geometry, then verify what was realized
Window commands operate on the top-level window, including browser chrome. They use CSS-pixel dimensions, and the implementation may return a different realized rectangle. Treat the request as an input, not as an image-size assertion.
import org.openqa.selenium.Dimension;
Dimension requested = new Dimension(1440, 1000);
driver.manage().window().setSize(requested);
Dimension realized = driver.manage().window().getSize();
System.out.printf("requested=%dx%d realized=%dx%d%n",
requested.getWidth(), requested.getHeight(),
realized.getWidth(), realized.getHeight());
Run this in the same browser, driver, headless mode, operating system, and local or remote configuration where the mismatch occurs. A headed browser may reserve space for tabs, toolbars, borders, and the operating system. A headless implementation may apply its own limits. Remote infrastructure can impose another screen or window policy.
Measure the viewport and the PNG instead of guessing
Record browser-side metrics immediately before capture. These values are CSS pixels and describe the page viewport, not the encoded image’s pixel dimensions.
Free tools Windows power users keep installed
One-click scans. No signup required.
Rank #3
import java.util.Map;
@SuppressWarnings("unchecked")
Map<String, Object> metrics = (Map<String, Object>) ((org.openqa.selenium.JavascriptExecutor) driver)
.executeScript(
"return {innerWidth: window.innerWidth, innerHeight: window.innerHeight, " +
"clientWidth: document.documentElement.clientWidth, " +
"clientHeight: document.documentElement.clientHeight, " +
"devicePixelRatio: window.devicePixelRatio, " +
"scrollWidth: document.documentElement.scrollWidth, " +
"scrollHeight: document.documentElement.scrollHeight};");
System.out.println(metrics);
Then inspect the actual saved image. Java’s standard image reader can report the encoded dimensions:
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
BufferedImage image = ImageIO.read(new File("artifacts/viewport.png"));
if (image == null) {
throw new IllegalStateException("The file is not a readable image");
}
System.out.printf("PNG dimensions=%dx%d%n", image.getWidth(), image.getHeight());
Compare the requested window, realized window, viewport metrics, device-pixel ratio, and PNG dimensions as one record. Do not apply a hard-coded formula such as “window width equals PNG width” across every browser configuration. The standards and API definitions do not establish one universal CSS-to-device-pixel rule for all browsers and headless environments.
A repeatable diagnosis for size mismatches
- Write down the expected scope. State whether the requirement is viewport, visible element, or full document. A full-page requirement cannot be fixed by changing
OutputType. - Confirm the operation. Check whether the code calls the driver or an element. Ensure the result is not being cropped later by an image-processing or report-upload step.
- Log realized geometry. Print
getSize(), JavaScript viewport values, anddevicePixelRatioat capture time. - Inspect the encoded file. Read the saved image dimensions and verify that the file is complete and readable.
- Reproduce in the target environment. Use the same browser version, driver, headless flag, container or grid node, and display settings. A local headed result is not proof that a remote headless session behaves identically.
- Only then adjust geometry. Change the requested rectangle or browser-specific full-page method, capture again, and compare measurements.
Common symptoms, causes, and fixes
| Symptom | Likely cause | Action |
|---|---|---|
| The image is viewport-sized, but the page continues below it | A standard driver screenshot captures the visual viewport | Use a browser-specific, tested full-page technique or capture and stitch regions; do not treat page height alone as proof of support. |
Changing OutputType.FILE to BYTES changes nothing about dimensions |
Output type controls representation, not scope | Change the capture operation or browser geometry, then verify the PNG. |
| The requested 1440×1000 window produces another image size | Window dimensions include chrome and may be clamped | Log the realized window and viewport; measure the PNG in the same environment. |
| The file disappears after tests finish | FILE is temporary |
Copy it to a durable artifact directory before JVM exit. |
| An element image is unexpectedly short or clipped | Element screenshots cover the visible bounding rectangle | Scroll the element into view, ensure it is displayed, and confirm that the requirement is visible-element capture rather than full document capture. |
| The saved file cannot be decoded | Incomplete persistence, wrong path, or a non-image response in a wrapper | Check file length and image-reader output, preserve the original bytes, and debug storage separately from geometry. |
| Local and CI dimensions differ | Different headless mode, display, browser, driver, or remote node | Record all environment details and compare effective metrics, not only the requested size. |
Full-page capture: what you can and cannot assume
“Full screenshot” commonly means one image containing the entire scrollable document. The standard driver screenshot definition is narrower: the visual viewport. Some browser and driver combinations expose a full-page capability, while others require browser-specific commands or a scroll-and-stitch workflow. Because behavior varies, document the exact browser and driver versions in your test suite and validate pages with fixed, sticky, lazy-loaded, and very tall content.
A scroll-and-stitch implementation must account for sticky headers, animations, lazy images, overlapping screenshots, and content that changes while scrolling. It can also produce seams or duplicate fixed elements. If exact document capture is a release requirement, treat the chosen method as an environment-specific integration and keep a regression image for the browser configuration you support.
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 →Reliability and performance considerations
- Capture only after the page state is deterministic. Wait for the application’s own ready condition, fonts, images, and asynchronous data rather than relying on a fixed sleep alone.
- Keep viewport and device-pixel-ratio settings stable in visual tests; otherwise a valid rendering change can look like a size defect.
- Use unique artifact names containing browser, mode, and test identifiers so parallel runs do not overwrite one another.
- For remote sessions, transfer and store the bytes deliberately. A temporary path on the remote node may not exist on the machine running the test report.
- Very large full-page images consume more memory and storage. Compress or resize only after preserving the original when pixel-level debugging matters.
- When comparing images, compare dimensions before pixels. A width mismatch makes every later pixel comparison noisy.
Or skip the browser setup
If your goal is a clean URL screenshot rather than Selenium interaction, ScreenshotNeo provides a single HTTP endpoint. It accepts consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be disabled. 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. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.
The service supports full-page capture with lazy images loaded, CSS-selector element capture, dark mode, device presets or custom viewports, retina scale, PDF paper and margin controls, custom CSS and JavaScript, clicks before capture, selector or network-idle waits, request and resource blocking, headers, cookies, user agents, authorization, timezone and geolocation, transparent backgrounds, resizing, TTL caching, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, and an OpenAPI specification. Parameters used by other screenshot APIs are also accepted to ease migration.
Rank #4
One-call examples
See the ScreenshotNeo documentation for current parameters and authentication details.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
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)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
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. Create a free ScreenshotNeo account.
Decision guide
| Need | Best starting point | What to verify |
|---|---|---|
| Current visible browser area during an interactive test | Driver getScreenshotAs |
Effective viewport and saved image dimensions |
| One visible component | Element getScreenshotAs |
Element visibility and bounding rectangle |
| Entire scrollable document in Selenium | Browser-specific full-page method | Exact browser, driver, headless mode, and page behavior |
| URL capture without managing a browser | ScreenshotNeo | Required cleanup, waiting, output, and billing headers |
Frequently Asked Questions
Does OutputType.BYTES increase screenshot resolution?
No. FILE, BYTES, and BASE64 select how Selenium returns the captured data. Resolution and scope depend on the driver, viewport, element operation, and browser environment.
Best Value
Why does a 1440-pixel window request not create a 1440-pixel-wide PNG?
The request describes outer window geometry in CSS pixels and includes browser chrome. Implementations can clamp or adjust it, and device-pixel scaling can differ. Measure the realized viewport and encoded image in the same run.
Can Selenium’s normal screenshot call capture the whole page?
The standards-defined driver screenshot is the visual viewport. Full-document capture requires a browser-specific capability or another tested technique; do not assume the normal call includes content below the fold.
Where should I look when screenshots differ only in CI?
Compare browser and driver versions, headless or headed mode, remote node, display settings, realized window, JavaScript viewport metrics, device-pixel ratio, and the saved PNG dimensions.
Recommended Free Tools
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.

