ScreenshotNeo

BlogHow-to

How to Get Consistent-Sized Screenshots with Selenium WebDriver

Set, verify and standardize Selenium browser dimensions for repeatable screenshots, with full-page guidance, troubleshooting and an API alternative.

By the ScreenshotNeo team1 October 20267 min read

Set the browser window to a fixed width and height, read the size back, then capture using the same browser, operating system, headless configuration and procedure each time. Selenium sizing improves repeatability, but it does not guarantee pixel-identical PNGs across every browser, operating system, display scale or headless environment.

Selenium’s official documentation shows driver.set_window_size(1024, 768) and driver.get_window_size(). Screen resolution can affect rendering, so treat explicit sizing as one control in a consistent capture environment.

1. Minimal Python example

from selenium import webdriver

with webdriver.Chrome() as driver:
    driver.set_window_size(1024, 768)
    actual_size = driver.get_window_size()
    print(f"Browser-reported size: {actual_size['width']}x{actual_size['height']}")

    driver.get("https://example.com")
    driver.save_screenshot("screenshot.png")

save_screenshot() writes a PNG of the current browsing context. The returned size confirms what that WebDriver session reports after the request; it is better evidence than assuming the requested dimensions were applied unchanged.

See Selenium’s window and tab documentation and the Python API reference.

2. Why screenshot sizes vary

  • Window size and viewport size differ. Browser chrome, driver behavior and operating-system window management can affect the content area.
  • Screen resolution affects layout. Responsive breakpoints, font rasterization and available rendering space can change when the host display or virtual display changes.
  • Device pixel ratio changes output pixels. A CSS viewport measured in CSS pixels may be rasterized at a different scale in another environment.
  • Headless and headed sessions can differ. Keep the mode and browser launch configuration fixed for comparisons.
  • Page state is dynamic. Animations, late-loading fonts, ads, cookie banners and data fetched after navigation can alter the image even when dimensions match.

Window sizing is therefore a reproducibility control, not a universal guarantee of identical image bytes.

3. A repeatable capture procedure

  1. Pin the browser family and version used by your capture job.
  2. Use the same WebDriver version and driver configuration.
  3. Choose a fixed width and height for the browser window.
  4. Set the size before navigation, then read it back and log the result.
  5. Use the same headless or headed mode and the same operating-system or container image.
  6. Navigate to the URL and wait for the page state your comparison requires.
  7. Capture the current browsing context with save_screenshot().
  8. Keep filenames and image format consistent so downstream comparison tools do not add another variable.

Reusable helper

from selenium import webdriver


def capture(url, path, width=1024, height=768):
    with webdriver.Chrome() as driver:
        driver.set_window_size(width, height)
        reported = driver.get_window_size()
        if (reported["width"], reported["height"]) != (width, height):
            raise RuntimeError(f"Requested {width}x{height}, got {reported}")
        driver.get(url)
        driver.save_screenshot(path)
        return reported


capture("https://example.com", "example.png")

Whether to fail on a mismatch depends on your pipeline. Failing makes an image-comparison job explicit; logging and continuing may be preferable for exploratory captures.

4. Viewport screenshots versus full-document screenshots

The ordinary WebDriver screenshot captures the current browsing context. Use it when the required artifact is the visible viewport at your chosen size.

If you need the entire long document, select a browser-specific full-document API and verify support for the browser used by your job. Selenium’s Firefox Python API documents separate full-page methods; do not assume the ordinary screenshot call captures the full document in every browser.

Requirement Capture choice Check before relying on it
Fixed visible area driver.save_screenshot() Reported window size and environment consistency
Entire page Browser-specific full-document method Browser support, resulting dimensions and stitching behavior

Firefox’s documented full-page methods are listed in its Python WebDriver API reference.

5. Complete example with deterministic page preparation

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait

URL = "https://example.com"
WIDTH, HEIGHT = 1280, 800

with webdriver.Chrome() as driver:
    driver.set_window_size(WIDTH, HEIGHT)
    size = driver.get_window_size()
    print("reported window:", size)

    driver.get(URL)
    WebDriverWait(driver, 30).until(
        lambda browser: browser.execute_script("return document.readyState") == "complete"
    )

    driver.save_screenshot("viewport-1280x800.png")

The readiness check only confirms the document’s ready state. It does not prove that every image, web font, animation or application request has finished. Add an application-specific wait when your page needs one, such as waiting for a known element to appear.

6. Troubleshooting

Symptom Likely cause Fix
Returned dimensions differ from the request Driver, browser or window-manager behavior Log get_window_size(), use the returned value in diagnostics, and standardize the runtime.
Images have different pixel widths despite the same CSS size Device pixel ratio or display scaling changed Use the same host/container and display scale; compare the actual output dimensions.
Layout changes between runs Responsive breakpoint, viewport difference or dynamic content Fix dimensions, browser/runtime versions and page state; wait for the required element or data.
Screenshot is only the visible area Ordinary WebDriver capture is a current-context screenshot Use a documented full-document method supported by your chosen browser.
Cookie dialog, newsletter popup or chat bubble appears Page overlays are part of the live page state Handle the overlay in your Selenium flow or hide it before capture, and record that preprocessing step.
Capture sometimes shows a blank or half-loaded page Navigation or asynchronous resources are incomplete Wait for a meaningful application condition, increase the navigation timeout where appropriate, and keep network conditions consistent.
Text differs on the same URL Web fonts, localization, timezone or live data changed Control the environment and page inputs, or accept that the comparison is not pixel-stable.

7. Reliability and performance practices

  • Reuse a configured driver for a batch of captures when isolation between pages is not required; start a fresh session when state leakage would invalidate comparisons.
  • Record URL, requested size, reported size, browser version, driver version and capture timestamp with each artifact.
  • Keep waits targeted. A fixed sleep can be simple, but an element or application-state condition usually avoids unnecessary delay.
  • Capture at the same point in animations. Disable or pause animations only if that reflects your comparison policy.
  • Use a stable test page or fixture for regression tests; production pages can change independently of your code.
  • Compare decoded image dimensions and visual differences separately from byte-for-byte equality. Identical dimensions do not imply identical pixels.

8. Or skip the browser setup

ScreenshotNeo provides a website screenshot API when you need a consistent capture service without maintaining Selenium browser setup. The API accepts one GET request and returns PNG, JPEG, WebP or PDF. Read the ScreenshotNeo API documentation for the full option list.

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}`);

Before capture, ScreenshotNeo can accept consent banners and remove more than 60 known consent platforms, newsletter popups and chat widgets; each step can be turned off. Bot checks, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing result. It also offers an MCP server for Claude, Cursor and other MCP clients, so AI agents can call take_screenshot, get_page_info and capture_pdf. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

9. Cost and scaling considerations

Selenium costs depend on the machines, browsers and orchestration you operate. More parallel sessions can reduce wall-clock time while increasing CPU, memory and infrastructure usage. Full-document captures can also produce larger files and take longer than viewport captures.

ScreenshotNeo pricing is usage-based: Free 1,000 shots/month, Starter $5 for 3,000, Growth $15 for 15,000, Pro $39 for 60,000, Scale $99 for 250,000 and Business $249 for 1,000,000. Yearly billing gives two months free, and every feature is on every plan. Its cache TTL, bulk capture (up to 100 URLs per call), async jobs, signed webhooks and usage API can help with larger capture queues.

10. Checklist

  • Fixed width and height selected
  • Window size read back and logged
  • Browser, driver, operating system and display scale standardized
  • Headless or headed mode kept consistent
  • Viewport versus full-document requirement decided
  • Page readiness condition defined
  • Dynamic overlays, fonts and animations handled
  • Output dimensions and metadata recorded

11. FAQ

Does set_window_size() guarantee identical PNG dimensions?

No. It sets a requested browser window size and lets you verify the reported result. Browser, operating-system, headless and display-scale differences can still affect output.

Should I use 1024×768?

It is a documented example, not a universal standard. Choose the dimensions required by your application and keep them fixed.

Why does my screenshot omit content below the fold?

The ordinary screenshot captures the current browsing context. Use a browser-specific full-document method when you need the entire page.

Can I compare screenshots from different browsers?

You can, but differences in layout, fonts and rasterization may be expected. For visual regression, keep the browser and runtime consistent.

When is an API preferable to Selenium?

Use an API when you want a remote capture workflow, built-in handling for common overlays and failed pages, or agent integrations without operating browser drivers yourself.