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

Use Chrome’s --headless switch, or set the equivalent option in your test framework. A direct command such as google-chrome --headless starts Chrome without a visible window. Puppeteer uses headless: true (its default), while Selenium adds --headless to Chrome options. For current end-to-end and extension tests, use unified Headless; the former implementation is now distributed separately as chrome-headless-shell.

This guide covers command-line checks, Puppeteer and Selenium, capture and timing flags, CI behavior, mode selection, failures and a browser-free screenshot alternative.

What headless Chrome changes

Headless mode runs Chrome with no visible user interface. The browser still loads pages, executes JavaScript, maintains a DOM and exposes the same automation surfaces needed for navigation, interaction and assertions. That makes it suitable for continuous-integration workers, containers, servers and other unattended machines.

Headless is not a different test framework. The Chrome command line can inspect a page or produce an artifact, whereas Puppeteer and Selenium provide APIs for clicking, typing, waiting and asserting application behavior.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
HP 14" HD Chromebook Laptop for Students, Intel Quad-Core N4120(> N4020), 4GB RAM, 64GB eMMC, WiFi, Webcam, HDMI, USB-A&C, 14 Hours Battery Life, Zoom, Chrome OS, CUE Accessories
  • Intel Celeron N4120: 4 Cores & Threads, 1.1GHz Base Clock, Up to 2.6GHz Boost Clock, 4MB Cache, Intel UHD Graphics 600. The perfect combination of performance, power consumption, and value helps your device handle multitasking smoothly and reliably with four processing cores to divide up the work.
  • 14" HD Display: 14.0-inch diagonal, HD (1366 x 768), micro-edge, anti-glare. See your digital world in a whole new way. Enjoy movies and photos with the great image quality and high-definition detail of 1 million pixels.
  • Memory & Storage: 4 GB LPDDR4x & 64 GB eMMC Storage. Adequate high-bandwidth RAM to smoothly run multiple applications and browser tabs all at once. An embedded multimedia card provides reliable flash-based storage.
  • Ports:2 x USB 3.0 Type-A,1 x USB 3.0 Type-C,1 x HDMI,1 x Headphone Jack
  • Chrome OS: Chromebook is a computer for the way the modern world works, with thousands of apps. Enjoy the seamless simplicity that comes with Google Chrome and Android apps, all integrated into one laptop. It’s fast, simple, and secure.

Choose unified Headless or Headless Shell

Unified Headless (recommended for browser fidelity)

Chrome’s current unified mode uses the same browser implementation as regular, visible Chrome. The practical choice is --headless; --headless=new also selects this mode. It is the better fit for high-fidelity end-to-end tests and browser-extension tests because the test exercises the real Chrome code path.

Chrome 112 introduced the unified implementation. Since Chrome 132, --headless=old no longer selects a legacy mode and reports an error instead.

Headless Shell (lighter, reduced feature set)

The old implementation is available as a separate chrome-headless-shell binary. Its smaller dependency footprint can suit screenshotting or scraping when the reduced functionality is sufficient. Do not add --headless=old to a modern Chrome command; install and invoke the shell binary when you specifically need that behavior.

Run a one-off headless test from the command line

The executable name depends on your operating system and installation. On Linux, a typical invocation is:

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

Chrome’s documented platform forms include:

  • Linux: google-chrome --headless (the binary may instead be named chrome).
  • macOS: open -a "Google Chrome" --args --headless.
  • Windows Command Prompt: start chrome --headless.

These commands start a browser process but do not navigate or assert anything. Add a URL and an operation when you want a useful result.

Dump the rendered DOM

chrome --headless --dump-dom https://example.com

--dump-dom prints the serialized DOM after Chrome has parsed the document and run its scripts. It is therefore different from downloading the original response HTML: client-rendered content can appear in the dump.

Capture a screenshot

chrome --headless --screenshot --window-size=412,892 https://example.com

Chrome writes screenshot.png in the current working directory. --window-size=WIDTH,HEIGHT controls the viewport used for the capture; it does not automatically make the page full length.

Print a PDF

chrome --headless --print-to-pdf https://example.com

The result is output.pdf. Add --no-pdf-header-footer to suppress the default header and footer. Older Chrome versions may require the former spelling --print-to-pdf-no-header, so check the flags supported by the Chrome version installed in your runner.

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

Control loading and virtual time

Set a capture timeout

chrome --headless --timeout=10000 --screenshot https://example.com

--timeout=MS limits how long Chrome waits before proceeding with a DOM dump, screenshot or PDF. It is a capture wait limit, not a replacement for synchronization in an application test. A page can still be loading when the artifact is produced.

Fast-forward timer-driven code

chrome --headless --virtual-time-budget=5000 --dump-dom https://example.com

--virtual-time-budget=MS advances page code that relies on timers. This can make time-dependent captures more repeatable, but it does not replace an assertion that waits for the application’s actual ready condition.

Capture Chrome scheme pages

For a chrome:// URL, add --allow-chrome-scheme-url. The CLI reference lists this switch from Chrome 123 onward.

Virtual screens

Multi-display scenarios can use Chrome’s virtual headless screens with --screen-info and DevTools Protocol commands such as Emulation.addScreen. Puppeteer exposes the capabilities needed to drive these scenarios. Use them only when your test genuinely depends on more than one display; ordinary viewport testing needs --window-size or a framework viewport setting.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
ASUS 2026 15" FHD IPS Chromebook, Intel Processor Up to 2.80GHz, 4GB DDR4, 128GB Storage, HDMI, Super-Fast WiFi, Chrome OS, Pastel Blue, Renewed
  • Intel Processor Up to 2.80GHz, 4GB DDR4, 128GB Storage
  • 15" FHD IPS Display, Intel UHD Graphics
  • 1x USB Type C, 1 x USB Type A, 1x Headphone/Microphone Combo Jack, HDMI
  • Super Fast WiFi and Bluetooth, Integrated Webcam
  • Chrome OS, AC Charger Included, Pastel Blue

Run tests with Puppeteer

Puppeteer launches unified Headless by default when you set headless: true. This complete example navigates to a page, checks its title and closes Chrome even when an assertion fails:

import assert from 'node:assert/strict';
import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({ headless: true });
try {
  const page = await browser.newPage();
  await page.setViewport({ width: 1280, height: 800 });
  await page.goto('https://example.com', { waitUntil: 'networkidle2' });
  assert.equal(await page.title(), 'Example Domain');
  await page.screenshot({ path: 'test-shot.png', fullPage: true });
} finally {
  await browser.close();
}

Use headless: false locally when you need to watch the test or inspect it with visible developer tools. Puppeteer also accepts headless: 'shell' when you intentionally want the separate Headless Shell behavior. Keep the mode choice explicit in shared test configuration so a developer’s debugging run and CI run do not silently exercise different browser implementations.

Make Puppeteer waits application-specific

Prefer a condition that represents readiness, such as a visible result element, over an arbitrary sleep:

await page.goto('https://example.com/app', { waitUntil: 'domcontentloaded' });
await page.waitForSelector('[data-testid="results"]', { visible: true });
const count = await page.locator('[data-testid="results"] article').count();

The exact locator API depends on your Puppeteer version. The important distinction is that browser launch mode only removes the window; it does not tell your test when asynchronous application work is complete.

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

Run tests with Selenium WebDriver

Selenium enables Headless through Chrome options. The JavaScript pattern below is deliberately explicit about cleanup:

import { Builder } from 'selenium-webdriver';
import chrome from 'selenium-webdriver/chrome.js';

const options = new chrome.Options().addArguments('--headless');
const driver = await new Builder()
  .forBrowser('chrome')
  .setChromeOptions(options)
  .build();

try {
  await driver.get('https://example.com');
  const title = await driver.getTitle();
  if (title !== 'Example Domain') {
    throw new Error(`Unexpected title: ${title}`);
  }
} finally {
  await driver.quit();
}

Imports and option-builder syntax vary among Selenium language bindings. Keep the same conceptual setting—add the --headless Chrome argument—and follow the binding’s current documentation for driver installation and package setup.

Rank #4
Lenovo Chromebook 2-in-1 - Lightweight Laptop - Google Gemini - Intel® N150 CPU - 14" WUXGA IPS Touchscreen Display - 4GB RAM - 128GB UFS Storage - Integrated Intel® Graphics - Luna Grey
  • THE BETTER WAY TO LAPTOP – Imagine a Chromebook that’s as flexible as your day: thin and lightweight with built-in Google apps and stress-free security.
  • TAKE HITS KEEP MOVING – Sleek, light, and built to last- the Chromebook 2-in-1 is just 0.69” thick and 3.3lbs. Enjoy long-lasting battery life, fast charging, and military-grade durability for nonstop productivity wherever life takes you.
  • PERFORMANCE THAT MATCHES YOUR HUSTLE – Fuel your ideas with an Intel Core processor and 128GB storage. Boot up in under 10 seconds to start the day powerfully efficient.
  • FLEX YOUR CREATIVITY ANYWHERE, ANYTIME – Create, work, or unwind your way with a versatile 2-in-1 design. Flip easily between laptop, tent, and tablet modes with a responsive touchscreen built for flexibility.
  • BRILLIANT VIEWS AND IMMERSIVE AUDIO – See, hear, and create with awesome clarity. The WUXGA display brings rich detail to your work and play, while audio tuned by Waves MaxxAudio provides immersive, balanced sound.

Extension tests

Use unified Headless for extensions and pass --headless=new when your framework or test convention requires the explicit form. The former Headless implementation did not support loading extensions. Verify that the extension path, permissions and browser version used by CI match your local test.

Put Headless Chrome in CI safely

  1. Install a compatible Chrome build. The browser, framework package and (for Selenium) driver must be compatible with the image. Do not assume that a locally installed browser exists on a clean worker.
  2. Select the mode in code. Set Puppeteer’s headless: true or add Selenium’s --headless argument rather than relying on an interactive desktop session.
  3. Make readiness deterministic. Wait for a selector, URL change, network condition or application signal that represents test readiness.
  4. Save diagnostics. On failure, retain a screenshot, DOM dump, browser console output and WebDriver or Puppeteer logs where your CI system can publish them.
  5. Close every browser. Use try/finally (or the test runner’s teardown hook) so a failed assertion does not leave Chrome processes consuming the worker.
  6. Keep security changes deliberate. Do not add --no-sandbox as a routine Headless fix. If a locked-down image requires a special configuration, address that image’s permissions and document the exception instead of copying an unrelated workaround.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Common failures and fixes

“Chrome binary not found”

Cause: the CI image does not contain Chrome, or the framework is looking in a different location. Fix: install the supported browser in the image or configure the framework’s executable path; print the resolved path and version in the job log.

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.

The command exits with an unknown option

Cause: a flag belongs to a different Chrome version or to another tool. Fix: run the installed binary’s help output, remove obsolete switches such as --headless=old, and use the current unified mode.

The screenshot is blank or missing application data

Cause: capture happened before client-side rendering, a request failed, authentication was absent, or the page is blocked in CI. Fix: wait for a concrete ready selector, check response and console logs, provide the required test credentials or cookies through your framework, and save a DOM dump to distinguish a rendering problem from an application problem.

Tests pass locally but time out in CI

Cause: slower resources, different DNS or network access, a missing dependency, or a test that relies on a fixed sleep. Fix: inspect the CI artifact and logs, wait on application state rather than elapsed time, and set a timeout appropriate to the worker without hiding genuine hangs.

PDF headers differ between machines

Cause: Chrome versions use different flag spellings or print defaults. Fix: pin or report the browser version, use --no-pdf-header-footer on current versions, and fall back to --print-to-pdf-no-header only where the installed version requires it.

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

An extension does not load

Cause: the test selected the former Headless implementation or supplied an invalid extension path. Fix: use unified Headless (--headless=new), verify the path and permissions, and confirm the extension supports the tested Chrome version.

Performance, reliability and cost decisions

  • Use the CLI for artifacts. DOM dumps, screenshots and PDFs are quick inspection tools and smoke checks, but the CLI alone does not provide a test assertion or interaction model.
  • Use Puppeteer or Selenium for behavior. They control navigation and interaction and let you synchronize with application state.
  • Choose the shell only for a known reduced requirement. Its lighter runtime can be useful for simple capture or scraping; unified Headless avoids fidelity surprises when extensions or complex browser behavior matter.
  • Control concurrency. Each browser consumes CPU, memory and file descriptors. Start with one browser per worker, measure the workload, then increase parallelism while watching queue time and failures.
  • Pin what matters. Record Chrome, framework and driver versions in CI logs. Browser flags and framework APIs evolve, so validate the syntax against the versions you actually deploy.

Or skip the browser setup

For a screenshot rather than an interactive test, ScreenshotNeo provides a single website-screenshot API request. It accepts the cookie or consent banner like a visitor, then removes more than 60 known consent platforms, newsletter popups and chat widgets before capture; each step can be turned off. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers.

See the ScreenshotNeo API documentation for all options. A cURL request is:

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

The same call in Python:

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)

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

ScreenshotNeo also has an MCP server with take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.

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.

Frequently Asked Questions

Does headless Chrome run JavaScript?

Yes. Headless Chrome executes page scripts; --dump-dom reflects the parsed and script-modified DOM rather than only the original response HTML.

Can I see the browser while a headless test runs?

No. Use Puppeteer’s headless: false for a visible debugging session, then restore true for unattended runs.

Is --headless=new required?

It explicitly selects unified Headless, but current Chrome also uses unified mode with --headless. Do not use --headless=old; obtain chrome-headless-shell if you specifically need the separate shell.

Does headless mode make tests faster?

The supplied Chrome guidance gives no general performance statistic. Runtime depends on the page, browser version, worker resources and test concurrency.

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

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.