ScreenshotNeo

BlogComparisons

Selenium Screenshot vs. Chrome DevTools Screenshot for Web Pages

Compare Selenium’s portable viewport screenshots with Chrome DevTools Protocol controls for format, clipping, and beyond-viewport capture, with runnable examples and troubleshooting.

By the ScreenshotNeo team4 October 202610 min read

Short answer: Use Selenium’s standard screenshot command for portable viewport screenshots in an existing WebDriver workflow. Use Chrome DevTools Protocol (CDP) Page.captureScreenshot when a Chrome-specific workflow needs a clip rectangle, an output format, JPEG quality, or a request to capture beyond the viewport. Neither option guarantees a correct full-page image for every page; check the output on your target browser and site.

Selenium exposes the WebDriver screenshot command through language bindings. The W3C WebDriver specification defines it as capturing the top-level browsing context’s visual viewport. CDP is Chrome’s protocol and offers additional page-capture parameters. [W3C WebDriver screen capture; CDP Page.captureScreenshot]

Choose by capture scope and browser requirements

Need Use What to keep in mind
A viewport screenshot in an existing WebDriver test Selenium screenshot command Standard WebDriver behavior; captures the visual viewport.
The visible region of one element Selenium element screenshot The element is scrolled into view; this is not a screenshot of the whole document.
A specific rectangular region CDP with clip Chrome-specific protocol control; coordinates and scale must match the page’s layout.
PNG, JPEG, WebP, or JPEG quality control CDP Format and quality are protocol options. Quality applies to JPEG.
Content beyond the viewport CDP with captureBeyondViewport, or a separately supported full-page method The parameter defaults to false in current protocol docs. Results still depend on the browser version and page behavior.
A WebDriver-based workflow intended to work across browsers Start with Selenium’s standard API CDP is Chrome-specific; verify browser and client protocol compatibility if you use it.

These are differences in interface and documented controls, not a speed comparison. The available sources provide no comparative benchmark.

Take a viewport screenshot with Selenium in Python

Install Selenium, ensure a compatible Chrome browser and driver setup is available, then run this script. Selenium’s driver-management behavior depends on its version and environment; if automatic setup is unavailable, configure a matching driver using the Selenium documentation for your platform.

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
# Uncomment for a headless run:
# options.add_argument("--headless=new")

driver = webdriver.Chrome(options=options)
try:
    driver.set_window_size(1440, 1000)
    driver.get("https://example.com")
    driver.save_screenshot("viewport.png")
finally:
    driver.quit()

save_screenshot writes the screenshot to the supplied path and returns whether it succeeded. The standard capture is the current visual viewport, not an automatic full-document image. See the Selenium window and viewport documentation and Selenium WebDriver documentation.

Capture one element with Selenium

from selenium import webdriver
from selenium.webdriver.common.by import By

with webdriver.Chrome() as driver:
    driver.get("https://example.com")
    card = driver.find_element(By.CSS_SELECTOR, "main")
    card.screenshot("main-element.png")

The WebDriver element screenshot operation captures the visible region of the element’s bounding rectangle after scrolling it into view. For a very tall element, check whether the resulting image covers the region you need. [W3C WebDriver screen capture; Selenium element interactions]

Capture with Chrome DevTools Protocol

CDP’s Page.captureScreenshot returns base64-encoded image data. Its documented parameters include image format, JPEG quality, a clipping rectangle, and captureBeyondViewport. The example below uses Selenium’s Chrome driver to send a CDP command, then decodes the returned PNG. Selenium’s CDP command bridge and the available protocol version are tied to the browser and Selenium combination, so use a compatible version and consult the API for your installed release.

import base64
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
# Uncomment for a headless run:
# options.add_argument("--headless=new")

driver = webdriver.Chrome(options=options)
try:
    driver.set_window_size(1440, 1000)
    driver.get("https://example.com")

    result = driver.execute_cdp_cmd("Page.captureScreenshot", {
        "format": "png",
        "captureBeyondViewport": True
    })
    with open("page.png", "wb") as image_file:
        image_file.write(base64.b64decode(result["data"]))
finally:
    driver.quit()

For a clipped capture, pass a rectangle in the page’s CSS pixel coordinate space, for example {"x": 0, "y": 0, "width": 800, "height": 600, "scale": 1} as the clip value. Set format to "jpeg" or "webp" when appropriate; CDP documents quality for JPEG. Check the protocol supported by the browser you actually run. [CDP Page.captureScreenshot; Selenium Chromium v136 protocol definition]

Version caution: The mutable CDP “tot” documentation can change, and the Chromium v136 protocol definition labels captureBeyondViewport experimental. That v136 snapshot is not a compatibility matrix. Confirm parameter support against the Chrome and Selenium versions in your environment.

Full-page screenshots: what the options do and do not promise

The standard WebDriver screenshot is defined around the visual viewport. CDP’s captureBeyondViewport requests content beyond that viewport, but the protocol documentation does not promise that this alone handles every tall or dynamically rendered page. For pages with lazy images, infinite scroll, sticky headers, or content that appears after scripts run, validate the image against the actual page and browser.

  1. Decide what “full page” means for the task: all document content, a long page up to a limit, or a particular region.
  2. Wait for the content you need. A page load event may not mean client-rendered content or lazy images are ready.
  3. If using CDP beyond-viewport capture, request the parameter and inspect the resulting dimensions and content. Do not assume it is supported identically across versions.
  4. Check for missing lazy-loaded images, repeated or obscured sticky elements, blank areas, and unexpected scaling.
  5. If the output is unreliable, use a page-specific scroll-and-stitch workflow or another documented full-page mechanism supported by your browser tooling, then validate seams and fixed elements.

Scroll-and-stitch is a workaround, not a guarantee: animations and page layout shifts can create seams or repeated content. The practical validation advice here follows from the documented capture scopes and options; it is not a claim of comparative product testing.

Wait for the right state before capturing

Both approaches capture what the browser has rendered when the command runs. If a site is asynchronous, wait for a meaningful condition rather than adding an arbitrary delay wherever possible.

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

with webdriver.Chrome() as driver:
    driver.get("https://example.com")
    WebDriverWait(driver, 15).until(
        EC.visibility_of_element_located((By.CSS_SELECTOR, "main"))
    )
    driver.save_screenshot("ready.png")

Use the narrowest useful readiness condition: a visible content element, a known application state, or a network-idle condition if your own tooling exposes one reliably. A generic network-idle condition can be unsuitable for pages with long-lived requests. For lazy content, scrolling the relevant region into view may be necessary before capture.

Other language bindings

Selenium supports multiple language bindings. The following examples show the standard viewport capture; use the matching Selenium package and a configured browser driver.

Java

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

WebDriver driver = new ChromeDriver();
try {
    driver.get("https://example.com");
    File source = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
    Files.copy(source.toPath(), new File("viewport.png").toPath(),
               StandardCopyOption.REPLACE_EXISTING);
} finally {
    driver.quit();
}

JavaScript

const { Builder } = require('selenium-webdriver');

(async () => {
  const driver = await new Builder().forBrowser('chrome').build();
  try {
    await driver.get('https://example.com');
    const pngBase64 = await driver.takeScreenshot();
    require('fs').writeFileSync('viewport.png', pngBase64, 'base64');
  } finally {
    await driver.quit();
  }
})();

For exact method names and return types in other bindings, use Selenium’s official examples and API documentation. [Selenium documentation]

Automation alternatives: cURL, Python, and Node.js

Selenium and CDP require a browser automation setup. If the requirement is simply to request a rendered screenshot from an API, ScreenshotNeo is the alternative to try first: it returns clean shots, bills only clean shots, and its paid plans start at $5.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server for developers. One GET request returns an image or PDF. Cookie banners are accepted like a visitor and 60+ known consent platforms, newsletter popups, and chat widgets are removed before capture; each step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits cost nothing, and response headers indicate the page verdict and billing status. Its MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Every feature is on every plan. See the ScreenshotNeo site and API documentation.

cURL

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.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://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer())));

Create a free ScreenshotNeo account for 1,000 screenshots a month with no card.

Options and configuration checklist

  • Capture scope: viewport, visible element, CDP clip, or beyond-viewport request.
  • Viewport: set the browser window size before navigation or capture when repeatable dimensions matter. Device pixel ratio and browser configuration can affect image dimensions.
  • Format: Selenium’s standard command is a straightforward screenshot flow. CDP supports PNG, JPEG, and WebP; quality is a JPEG option.
  • Timing: wait for application content and images required by the test.
  • Browser/protocol: use CDP only when the Chrome-specific dependency is acceptable, and check the installed protocol version.
  • Output: check that the file exists, decodes, and has expected dimensions; keep failure evidence if a capture is used in CI.

Troubleshooting

Symptom Likely cause Fix
Image shows only the top visible section The WebDriver screenshot captures the visual viewport. Use a supported full-page mechanism or CDP beyond-viewport request; verify the output on the target page.
CDP command or parameter is unknown The browser’s protocol version or Selenium bridge does not support the requested command or option. Check Chrome and Selenium versions and their protocol pairing; remove unsupported parameters or use the standard WebDriver screenshot.
Screenshot is blank or content is missing Capture ran before client rendering, fonts, images, or a lazy-loaded region became ready. Wait for a relevant element or application state; scroll lazy content into view and inspect again.
Wrong size or crop Viewport dimensions, device scale, clip coordinates, or page layout differ from expectations. Set the window size deliberately; check CSS-pixel clip values, output dimensions, and browser scaling.
Sticky header repeats or covers content in a stitched image Each scroll capture includes fixed-position elements or the page reflows between captures. Use a single supported capture where it works, or account for fixed elements and layout changes in a stitching workflow.
Driver cannot start Browser/driver setup, permissions, or headless environment configuration is incomplete. Install/configure a compatible browser driver, inspect Selenium’s startup error, and run with the environment’s supported headless configuration.
Image cannot be decoded from a CDP response The returned base64 data was not decoded or written as binary. Decode the data field before writing; preserve binary bytes and use the matching extension and format.

Performance, reliability, and cost

The research sources do not establish that Selenium or CDP is faster. In either case, page navigation, scripts, fonts, images, waiting conditions, and image dimensions affect the work involved. Larger output images can take more memory and storage; unnecessary sleeps increase run time. Prefer a clear readiness condition and capture only the scope the test needs.

Reliability depends on page state and browser/protocol pairing. Standard WebDriver offers a portable interface for WebDriver workflows; CDP offers Chrome-specific controls. Full-page behavior should be checked for dynamic content, lazy loading, sticky elements, and the actual browser version. No comparative reliability figure is available in the sources used here.

With Selenium or CDP running in your own test environment, account for the compute and maintenance required for browser setup and execution. ScreenshotNeo’s stated pricing is Free for 1,000 shots/month with no card, 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. Every feature is included on every plan. Only clean shots are billed; response headers identify verdict and billing. Pricing and product details: ScreenshotNeo.

FAQ

Is a Selenium screenshot a full-page screenshot?

The standard WebDriver command captures the visual viewport. Selenium also has an element screenshot operation for an element’s visible region.

Does CDP always capture the entire page when beyond-viewport is enabled?

No universal guarantee is stated in the protocol documentation. Check the result for the browser version and page you use.

Can I use CDP with browsers other than Chrome?

CDP is Chrome’s DevTools Protocol. For a WebDriver workflow intended to use multiple browsers, begin with the standard Selenium screenshot API.

Which should I use for a test failure attachment?

Use Selenium’s standard screenshot when the current viewport is sufficient and the test already uses WebDriver. Choose CDP if the test specifically needs its Chrome capture controls.

Sources