Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The most common fix is to wait for the page state you need, not just for navigation to finish. Selenium’s page-load wait is tied to the document’s readyState; JavaScript can still add or reveal content afterward. In a Selenium run, wait for the specific element to be present or visible, set a deliberate viewport, and capture only after that condition is met. If the screenshot is still white or incomplete, record the browser, driver and Selenium versions and compare the same page state in headless and headful Chrome.

First determine what is actually failing

A white screenshot and a missing element are related symptoms, but they do not identify the same cause. A screenshot can be empty because capture happened before the page rendered, while a particular element can be absent because the application has not inserted it, has hidden it, or shows it only after an interaction. A viewport mismatch can also make a responsive page look different from what you expected.

Start by separating three questions: did Chrome navigate to the intended page, did the application reach the state you intended to capture, and does the screenshot file have the dimensions you expected? Navigation returning is not proof that a JavaScript-driven application is ready. Selenium’s Waiting Strategies documentation explains that its navigation wait concerns assets defined in the HTML; JavaScript can then change the page or add elements.

  • Entire image is white or nearly empty: check the current URL, document state, visible page content and capture timing before changing browser flags.
  • Only one section or element is missing: check whether the exact element exists in the live DOM and whether Selenium considers it displayed.
  • Content appears in a different place or layout: record the viewport and compare it with the intended capture size; a responsive page can rearrange content at different widths.

Without the failing URL, code, screenshot, browser and driver versions, operating system, and logs, there is no reliable way to name one cause for a particular failure. The steps below are a diagnostic sequence, not a claim that every white screenshot has the same fix.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use a condition-based wait before capturing

For a page that renders content asynchronously, wait for the condition that matters to the screenshot. If a heading must be visible, wait for visibility; if you only need to confirm that an element has been added to the DOM, wait for presence. Selenium’s documentation distinguishes wait strategies and warns that mixing implicit and explicit waits can produce unpredictable total wait times.

Runnable Python example

This example uses an explicit wait for a visible page heading, then saves a screenshot. Replace the URL and CSS selector with the page and element you actually need. It assumes a working Python Selenium installation and a Chrome/ChromeDriver setup that can launch Chrome in your environment.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait

options = webdriver.ChromeOptions()
options.add_argument("--headless")
options.add_argument("--window-size=1440,1200")

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

    heading = WebDriverWait(driver, 20).until(
        EC.visibility_of_element_located((By.CSS_SELECTOR, "main h1"))
    )
    print("Visible heading:", heading.text)
    print("Current URL:", driver.current_url)
    print("Document readyState:", driver.execute_script("return document.readyState"))

    driver.save_screenshot("page.png")
finally:
    driver.quit()

The example’s selector is illustrative: if the target site has no main h1, the wait will not succeed. Choose a selector that represents the page state you need, such as the result container after a search, rather than a generic element that appears before the important content. The 20-second wait is a maximum for this example, not a guarantee that every site will be ready within that interval.

Presence, visibility and interaction are different conditions

  • Presence: use a presence condition when the next step only requires the node to exist in the DOM.
  • Visibility: use a visibility condition when the element must be displayed before capture or interaction.
  • Post-action state: if content appears only after a click, perform the click and then wait for the resulting content or state—not merely for the button to exist.

A condition-based wait ties synchronization to the next task. A fixed sleep does not: it can be too short on a slow run and unnecessarily long on a fast one. Selenium also supports implicit waits for element-location calls, but a global implicit wait is less targeted than an explicit wait for a particular state. Avoid combining the two casually; consult the Selenium wait documentation linked above if you need to understand their timing interaction.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Check viewport, capture timing and Chrome mode

Set the window size intentionally and record it with the run. An unexpected viewport can trigger a different responsive layout, move content or change what fits in the captured image. Confirm the output image dimensions as well as the page’s visible state; do not assume that a screenshot file’s existence means the intended content was captured.

Chrome’s command-line capture documentation describes --screenshot alongside --window-size, and documents a --timeout maximum wait before command-line capture even if loading continues. It also documents --virtual-time-budget for fast-forwarding time-dependent JavaScript during command-line capture. These are Chrome CLI controls, not drop-in Selenium wait APIs. For Selenium, use a condition that represents the application state you need before calling the screenshot method. See the Chrome Headless command-line reference.

When investigating, compare headless and headful runs using the same Chrome version, driver, URL, viewport and wait condition. A difference is a useful clue, not proof of a universal headless bug. Chrome’s Headless mode documentation says the implementation was updated in Chrome 112 so headless and headful share the Chrome implementation. Starting with Chrome 132.0.6793.0, the older Headless implementation is available only as the separate chrome-headless-shell binary. That history may explain why old advice or old test environments behave differently; it does not establish that a version mismatch caused a specific failure.

Follow a repeatable diagnostic sequence

  1. Save the run details. Record the target URL, operating system or container, Chrome version, ChromeDriver version, Selenium version, viewport dimensions and the point at which the screenshot call runs.
  2. Check the page before capture. Inspect the live DOM, current URL and the target element’s existence and displayed state. If the target is absent, capturing later without understanding the application’s render condition may only hide the underlying issue.
  3. Wait for the target state. Replace a sleep used as synchronization with an explicit wait for the exact content or visibility condition needed.
  4. Make the viewport explicit. Set a known window size in the run and compare the output dimensions with the expected capture.
  5. Account for delayed behavior. Determine whether the target depends on JavaScript, a delayed update or an interaction. Wait on the meaningful resulting state instead of assuming a navigation wait covers it.
  6. Compare modes under controlled conditions. Run headless and headful Chrome with the same versions, viewport and waits. Change one factor at a time so the comparison remains useful.

Keep the evidence from each run. If a failure recurs, the versions, viewport and recorded page state make it possible to distinguish an application timing problem from a reproducible environment-specific difference.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Troubleshoot by symptom

The whole screenshot is white

  • Capture starts too early: verify whether meaningful page content is visible before the screenshot call. Wait for a page-specific element or state.
  • Navigation ended at an unexpected page: print and verify driver.current_url; the intended destination may not be the page currently open.
  • The viewport is not what the test expects: set a deliberate window size and inspect the saved image’s dimensions.
  • Headless differs from headful: compare the two modes with all other conditions held steady, then investigate the difference rather than applying an unverified flag.

A specific element is missing

  • It is inserted later: wait for presence or visibility according to what the next step requires.
  • It appears only after an action: perform the action, then wait for the resulting element or state.
  • The selector does not match the page: inspect the live DOM and confirm the selector identifies the intended element on this page and state.
  • The element exists but is hidden: presence alone is insufficient when the screenshot needs visible content; use a visibility condition and investigate why the application has not displayed it.

The failure is intermittent

Intermittent results often indicate that a fixed delay is not synchronized with variable rendering time, but this is a diagnostic possibility rather than a diagnosis. Replace timing guesses with a condition, keep the viewport constant, and compare captured runs alongside their version and environment records. Do not change multiple browser options at once: if behavior changes, you will not know which change mattered.

The suggested wait never completes

Check that the selector is correct and that the expected state can occur for this URL and run. A wait for visibility will not succeed if the element never becomes visible; a wait for an element that only appears after a click will not succeed if the click has not occurred. Treat a timeout as evidence that the condition was not observed within the configured limit, not as proof that Chrome failed to take a screenshot.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Performance, reliability and cost considerations

In a Selenium workflow, the main reliability improvement is replacing a guessed delay with a wait that ends when the required state is observed. Keep the condition narrow: waiting for a relevant result element avoids coupling capture to unrelated activity elsewhere on a page. Set a viewport once for repeatable comparisons, and preserve the same browser and driver versions when investigating a regression.

There is no universal wait duration established for all sites. A short maximum can fail on a slow run; a very long maximum can delay failure reporting. Choose a limit appropriate to the application and environment, and make a timeout actionable by recording which condition was being awaited. For a local or CI Selenium workflow, budget for browser execution time and screenshot storage; those operational costs are separate from the timing diagnosis and depend on the infrastructure you run.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Or skip the browser setup:

If your goal is a website screenshot rather than diagnosing a Selenium-controlled browser, ScreenshotNeo is a screenshot API and MCP server for developers. Its capture flow accepts cookie and consent banners like a visitor, then removes more than 60 known consent platforms, newsletter popups and chat widgets; each of those steps can be turned off. 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 provides take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients.

For example, one GET request can save an image. Create an API key first; replace YOUR_API_KEY and use the page URL you want to capture. See the ScreenshotNeo API documentation for parameters and response details.

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

The same request pattern in Python:

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://example.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://example.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
  • Cookie banners, popups and chat widgets are removed before the shot.
  • Bot checks, blank pages and failed loads are never billed.
  • An MCP server lets AI agents take screenshots.
  • The Free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. All features are on every plan.

Sign up for ScreenshotNeo’s free plan to get 1,000 screenshots a month with no card.

Frequently Asked Questions

Does a white screenshot by itself prove a Chrome headless bug?

No. It shows that the captured output is not what you expected, but it does not distinguish a timing problem, an unexpected page state, viewport behavior or an environment-specific difference. Compare the live page state and a controlled headful run before assigning a cause.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Should I switch from Selenium to Chrome’s command-line screenshot flags to fix a Selenium wait?

Not as a direct fix. Chrome documents CLI capture controls such as --timeout and --virtual-time-budget for command-line use; Selenium synchronization should use a wait for the application condition required before its screenshot call.

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.