To run a Selenium 4 UI test without opening a visible browser window, set the browser’s headless option before creating the WebDriver. For Chrome and Chromium Edge, use --headless=new; for Firefox, use -headless. Then pass the configured options object to the driver, navigate to the page, and always close the session with quit().
What headless mode changes—and what it does not
Headless mode runs a real browser without displaying its graphical window. Selenium still drives the browser through WebDriver, so the test can navigate, inspect the DOM, interact with controls, and verify application behavior. It is useful in CI jobs and containers that have no desktop session.
Headless mode does not guarantee identical rendering or timing across browsers, browser versions, operating systems, fonts, or viewport sizes. Set a deliberate viewport and compare a failing test in headful mode before assuming the application or selector is at fault. Do not expect a fixed speed improvement: the available authoritative documentation does not establish a general performance percentage.
Run a Chrome test headlessly with Python
Create a ChromeOptions object, add the headless argument and any other browser arguments, then pass it to webdriver.Chrome. The viewport below is explicit so responsive layouts have a predictable starting size.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →#1 Best Overall
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
options.add_argument("--window-size=1440,1000")
driver = webdriver.Chrome(options=options)
try:
driver.get("https://example.test")
assert "Example" in driver.title
finally:
driver.quit()
Replace https://example.test with the application under test and adjust the assertion to match its expected result. The finally block closes the browser even if navigation or an assertion fails. This matters in local runs as well as CI, where orphaned browser processes can consume resources or interfere with later tests.
Choose the browser-specific headless option
Chrome and Chromium
Selenium’s current Chrome documentation lists Chrome v75 and greater as compatible with Selenium 4 and requires Chrome and ChromeDriver to have matching major versions. It includes --headless=new among common Chrome arguments. Google’s Chrome for Developers documentation says current Headless and headful modes are unified; from Chrome 132.0.6793.0, the old Headless implementation is available as a separate chrome-headless-shell binary. See Selenium’s Chrome documentation and Chrome Headless documentation.
For Java, configure options before constructing the driver:
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
public class HeadlessChromeTest {
public static void main(String[] args) {
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless=new", "--window-size=1440,1000");
WebDriver driver = new ChromeDriver(options);
try {
driver.get("https://example.test");
System.out.println(driver.getTitle());
} finally {
driver.quit();
}
}
}
Firefox
Selenium’s Firefox documentation states that Selenium 4 requires Firefox 78 or greater and lists -headless as a common argument. It recommends using the latest geckodriver. The options below also set the viewport dimensions.
Rank #2
from selenium import webdriver
options = webdriver.FirefoxOptions()
options.add_argument("-headless")
options.add_argument("--width=1440")
options.add_argument("--height=1000")
driver = webdriver.Firefox(options=options)
try:
driver.get("https://example.test")
print(driver.title)
finally:
driver.quit()
The corresponding Java setup is:
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
FirefoxOptions options = new FirefoxOptions();
options.addArguments("-headless");
WebDriver driver = new FirefoxDriver(options);
try {
driver.get("https://example.test");
} finally {
driver.quit();
}
See Selenium’s Firefox documentation for the current browser-specific guidance.
Chromium Edge
Use Selenium 4’s built-in Edge classes and add --headless=new through EdgeOptions. Microsoft documents this pattern across its Selenium language examples; older Selenium 3 Edge tooling is not the supported approach.
from selenium import webdriver
from selenium.webdriver.edge.options import Options
options = Options()
options.add_argument("--headless=new")
driver = webdriver.Edge(options=options)
try:
driver.get("https://example.test")
print(driver.title)
finally:
driver.quit()
See Microsoft’s Edge WebDriver guidance for language-specific setup.
Set up drivers and keep versions compatible
Selenium Manager has shipped with Selenium releases since 4.6. When a driver is not supplied, Selenium bindings can use it to discover, download, and cache the required driver. This reduces manual driver installation in suitable environments, but it does not make incompatible browser and driver versions interchangeable. For Chrome, match ChromeDriver’s major version to Chrome’s major version.
Free tools Windows power users keep installed
One-click scans. No signup required.
Rank #3
Selenium Manager is not a substitute for controlling your CI environment. A browser that auto-updates while your pipeline pins a driver can produce a mismatch. Record the browser version in CI and decide whether the environment should keep browser and driver versions aligned through a managed image, explicit versioning, or Selenium Manager. Refer to Selenium Manager documentation.
Run tests in CI, containers, or on a remote browser
Local CI or Docker execution
Headless mode removes the need to show a browser window, but the runtime still needs a usable browser binary, compatible driver setup, and the libraries and permissions required by that browser and image. If startup fails in a container, first identify the browser binary and driver versions and inspect the first driver-log error. Do not blindly add --no-sandbox: use it only when the container or runtime requires it and your security model permits it.
For CI, make failures diagnosable rather than relying on a green/red result alone. Save the screenshot, page source, browser console or driver log, and test metadata when a test fails. Pin or record the container image and browser versions so that a later run can be compared with the original failure.
Remote WebDriver and Selenium Grid
Remote WebDriver accepts the same browser options plus a Grid URL. The session then runs on another host, which can be useful when the CI container lacks a desktop, when multiple browser versions need to run in parallel, or when a hosted grid supplies the browsers. Configure the options for the target browser, then create a remote session using the Grid endpoint supplied by your environment. Check the grid provider’s current browser availability, regions, pricing, retention, and terms directly; those details can change.
Recommended Free Tools
Rank #4
Make headless failures reproducible
- Record the environment. Capture the Selenium binding, browser, driver, operating system, and container image versions with the failed test.
- Try one headful run. If the same test passes visibly but fails headlessly, compare rendering, viewport, timing, and environment startup before rewriting selectors.
- Read the first driver error. Prioritize version mismatch and missing browser binary messages; later log lines may only be consequences of the initial failure.
- Fix the viewport and synchronization. Set a known window size and wait for the application state the test needs instead of using arbitrary sleeps.
- Keep failure artifacts. Save a screenshot, page source, console or driver log, and test metadata when the test fails.
- Close every session. Use
quit()in afinallyblock or the test framework’s teardown mechanism.
Troubleshoot common headless Selenium errors
“Session not created” or browser fails during startup
Common causes include a browser/driver major-version mismatch, an unavailable browser binary, or a container runtime constraint. Print or log browser and driver versions, inspect the first driver error, and verify that the binary exists in the environment. For Chrome, align the browser and ChromeDriver major versions. Use --no-sandbox only if required by that runtime and allowed by your security policy.
The test opens a browser window anyway
Confirm that the options object containing the headless argument is the same object passed to the driver constructor. Check that the argument is spelled for the selected browser: Chrome and Edge use --headless=new in the examples here, while Firefox uses -headless. If a wrapper or test framework creates the driver, put the options in that framework’s browser configuration rather than creating an unused options object.
The page is blank or the expected element is missing
First distinguish a browser startup failure from an application wait or rendering issue. Inspect the screenshot, page source, console or driver log, and verify that the page reached the expected state. Use an explicit wait for the element or application condition instead of a fixed sleep, and compare a headful run at the same viewport. A selector change should follow evidence that the DOM or layout differs, not be the first response to a headless failure.
Layout differs from a desktop run
A different viewport can select another responsive breakpoint, while fonts, browser versions, and operating systems can also affect rendering. Set the same intended viewport in both modes and keep CI’s browser environment stable. If the difference remains, treat it as a real cross-environment rendering condition your test should either cover or explicitly control.
PC 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 & 11Outdated 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 matchBest Value
Or skip the browser setup
If your goal is to capture a website image or PDF rather than exercise interactive UI behavior with Selenium, ScreenshotNeo provides a screenshot API and MCP server for developers. A single GET request can return PNG, JPEG, WebP, or PDF. Its capture flow can accept cookie/consent banners like a visitor and remove more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be disabled. Bot checks/CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, with verdict and billing information in response headers. AI agents can use its MCP server tools, including take_screenshot, get_page_info, and capture_pdf.
Example cURL request (replace the target URL and supply your API key):
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.test -o shot.webp
See the ScreenshotNeo API documentation for request parameters and response details. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Sign up for ScreenshotNeo’s free plan.
FAQ
Does headless Selenium run a real browser?
Yes. It runs the browser without displaying its graphical window; it is not a substitute for browser automation with a different rendering engine.
Can a headless test prove that a site works for every visitor?
No. It verifies behavior for the browser and environment in which it ran. Differences in browser, viewport, operating system, and application timing may require additional coverage.
Should I use a fixed sleep to wait for a page?
Prefer an explicit wait for the page or element state the test needs. Fixed sleeps can be too short on a slow run and waste time on a fast one.
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.

