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

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 Chrome’s unified Headless mode with Selenium’s --headless=new argument, then make the browser environment deterministic: match Chrome and ChromeDriver major versions, set the viewport and any relevant locale or profile state, and wait for the condition your test actually needs. This brings headless execution closer to visible Chrome, but it does not make every machine, website session, or automation run identical.

What “behave like a full browser” means

Modern Chrome Headless is not a separate, lightweight browser implementation with a different rendering engine. Chrome describes its new Headless mode as “the real Chrome browser”: it shares the browser code used by headful Chrome, while running without a visible browser window. In Selenium, headless mode is configured as a browser argument, not a special Selenium driver type.

That distinction matters if a test fails only when headless. With a unified browser implementation, first look for differences in the environment or test setup—such as viewport size, fonts, profile state, network timing, permissions, or container restrictions—instead of assuming that headless Chrome necessarily uses a fundamentally different page renderer.

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.

Headless does not mean invisible to a website. The mode addresses the old split between headless and full Chrome code; it does not promise that a site will treat automated browsing as a human-operated session or that every execution environment will produce identical results.

Configure Selenium to use unified Headless Chrome

For Selenium’s Python bindings, add --headless=new to ChromeOptions. Set a window size explicitly if layout or responsive breakpoints matter. The following example is runnable with Selenium installed and a Chrome installation available to Selenium Manager:

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

options = Options()
options.add_argument("--headless=new")
options.add_argument("--window-size=1920,1080")

driver = webdriver.Chrome(options=options)
try:
    driver.get("https://example.com")
    heading = WebDriverWait(driver, 10).until(
        EC.visibility_of_element_located((By.TAG_NAME, "h1"))
    )
    print(heading.text)
    driver.save_screenshot("example.png")
finally:
    driver.quit()

webdriver.Chrome(options=options) asks Selenium to create a Chrome session using those options. Selenium Manager is built in for ordinary driver discovery; if it cannot locate or obtain a compatible driver in your environment, check the installed browser and driver versions rather than changing headless flags at random.

The old convenience method setHeadless(true) was removed in Selenium 4.10.0. Use an explicit browser argument such as --headless=new. Chrome 96–108 used the earlier spelling --headless=chrome; Chrome 109 adopted --headless=new for the newer mode. Since Chrome 132, the old Headless implementation is distributed as the separate chrome-headless-shell binary. For ordinary Selenium tests intended to behave like current full Chrome, use the unified mode rather than selecting the legacy shell.

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

Make the test environment reproducible

The same Chrome code can still produce different outcomes when important inputs differ. Decide which variables are part of the test and hold them constant. Do not add every available flag by habit: flags may alter security, rendering, or resource behavior and can conceal the issue the test is meant to catch.

Viewport and display scale

--window-size=1920,1080 sets a predictable window size for the example, but use dimensions appropriate to the page and test. A different viewport can select a different responsive layout, change line wrapping, move controls, and affect screenshot comparisons. If device scale factor or screen emulation matters, configure it deliberately; setting a window size alone is not the same as defining every device characteristic.

Profile and persistent state

Chrome profiles can carry cookies, local storage, permissions, extensions, and other state. For a clean, isolated session, give each test its own temporary profile. For example, the following pattern creates a disposable profile and removes it after the browser exits:

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

with tempfile.TemporaryDirectory(prefix="selenium-profile-") as profile:
    options = Options()
    options.add_argument("--headless=new")
    options.add_argument("--window-size=1920,1080")
    options.add_argument(f"--user-data-dir={profile}")

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

Use a persistent profile only when persistence is intentional and managed. Do not point parallel test sessions at the same active profile; profile collisions and leftover state make failures harder to reproduce. Choose a writable profile location on the host or container running Chrome.

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

Locale, permissions, network, and fonts

Normalize locale, timezone, geolocation, permissions, proxy settings, user-agent, and installed fonts only when they affect the behavior under test. These can change translated text, date formatting, geolocation prompts, responsive decisions, or rendered text metrics. Network speed and resource availability also affect when a page becomes usable. Record such dependencies in the test environment rather than compensating with a longer arbitrary delay.

Wait for the condition the next action needs

A successful call to driver.get() does not prove that an application has finished rendering or that a particular control is ready. Use an explicit wait for the next action’s real precondition: an element becoming visible, a button becoming clickable, text appearing, or an application-specific state changing. In the example above, Selenium waits up to ten seconds for a visible heading before reading it.

A fixed sleep pauses for the same duration regardless of whether the page is ready sooner or still not ready when the pause ends. It can make a suite both slower and less reliable. Choose the condition based on the next operation and a timeout appropriate to the application and environment.

Selenium’s guidance advises against mixing implicit and explicit waits because their combined timing can be surprising. Prefer explicit waits for condition-based synchronization, and keep each WebDriver instance confined to one test rather than sharing a driver across tests.

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

Keep Chrome and ChromeDriver compatible

The Chrome browser and ChromeDriver must have matching major versions. Selenium’s version guidance states that their major versions must match. When a session fails to start after a browser update, inspect both versions first; an old driver paired with a newer Chrome installation is a compatibility problem, not a reason to switch to a different headless implementation.

Selenium Manager handles ordinary driver discovery for many setups, but network restrictions, custom browser locations, or managed build images can complicate driver acquisition. In those environments, arrange a compatible driver in the image or environment and verify the actual browser binary Selenium launches. Re-check the pairing when updating Chrome in CI or a container.

Diagnose headless-only failures with browser events

When a page behaves differently, capture evidence at the point of failure: the current URL, page title, relevant DOM state, browser console errors, and network failures. A screenshot can show whether the page is blank, partially rendered, or simply laid out at an unexpected breakpoint. In Selenium, save such artifacts before quitting the driver, and include them with the failing test output.

WebDriver BiDi for browser events

Selenium describes WebDriver BiDi as a bidirectional WebSocket connection and its cross-browser direction for capabilities traditionally associated with Chrome DevTools Protocol. Use BiDi when you need browser console, JavaScript-error, or network events in a cross-browser-oriented test setup. Availability and API details depend on the Selenium bindings and browser combination you use, so consult the documentation for the versions in your environment before wiring event collection into a suite.

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

CDP for Chrome-specific controls

Use Chrome DevTools Protocol (CDP) when the test specifically needs Chrome capabilities such as emulation controls. CDP provides broader Chrome-specific access, but its protocol documentation notes that stable Chrome exposes a subset of the full protocol. Avoid making a test depend on an experimental or unavailable command without checking support in the browser version being run.

Chrome’s Emulation domain can override user-agent, accepted language, platform, user-agent metadata, and screen configuration. Apply those overrides only when the test has a defined emulation requirement. Changing them to make a site accept automation is not a general compatibility fix, and no universal stealth recipe is established here.

Troubleshoot common failures

Symptom Likely cause What to check or change
setHeadless is missing or rejected The old Selenium convenience setter was removed in Selenium 4.10.0. Configure ChromeOptions with --headless=new.
ChromeDriver cannot create a session Chrome and ChromeDriver major versions may not match, or Selenium may be launching a different browser binary than expected. Inspect both versions and the browser path; use a driver with the same major version as Chrome.
An element lookup times out in headless mode The element may not yet meet the condition your test assumes, or the page may be waiting on slower resources or an application state. Wait explicitly for the condition needed by the next action, and inspect the URL, DOM, console, network, and screenshot at the timeout.
Layout or screenshot differs from visible Chrome Viewport, display scale, fonts, locale, GPU availability, profile state, or host environment may differ. Normalize the variables relevant to the test. Verify the same viewport and profile assumptions before comparing results.
Chrome exits or fails only in a container The container may differ in sandbox permissions, resource limits, fonts, or available browser dependencies. Check the container’s Chrome launch error and runtime environment. Add only a narrowly justified configuration change; do not blindly copy security-altering flags from unrelated setups.
A test passes alone but fails in a suite Tests may be sharing driver or profile state, or competing for resources. Use an isolated WebDriver and profile per test, and collect artifacts to identify the first failing condition.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If you need a website screenshot or PDF rather than browser interaction and assertions, ScreenshotNeo provides a screenshot API and MCP server. A single GET request can return an image or PDF. Here is a cURL example; see the ScreenshotNeo API documentation for request options:

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

ScreenshotNeo accepts cookie and 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 turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing status in headers. Its MCP server offers take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. All features are available on every plan.

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

Sign up for ScreenshotNeo’s free plan: 1,000 screenshots a month, no card required.

Choosing the right approach

Use Selenium Headless Chrome when the test needs to interact with a page, assert application behavior, control browser state, or reproduce a user flow. Use a screenshot API when the task is simply to capture a page or PDF and you do not need WebDriver interaction. For faithful Selenium results, the practical priorities are unified Headless mode, compatible browser and driver versions, controlled environment inputs, isolated sessions, and waits tied to actual page conditions.

Frequently Asked Questions

Can I run Selenium Headless Chrome on a machine without a desktop session?

Yes. Headless mode runs without displaying a browser window; Chrome still needs to be installed and able to launch in that host or container environment.

Does a headless Selenium test prove that a site works for human visitors?

No. It verifies behavior in the configured automated browser environment. Important user-facing cases may also need tests in visible browsers, other browsers, or real-device conditions.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

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

Should I switch to the old headless shell if unified Headless has a failure?

Not as a first fix. Diagnose the browser-driver pairing, environment, and failing condition first; the separate legacy shell is a distinct implementation and may not match the full-Chrome behavior you want.

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.