A headless browser is a browser without a visible window. It does everything a normal browser does — renders HTML, executes JavaScript, handles CSS — but there's no screen output. Think of it like cooking with your eyes closed. The food still gets cooked, you just can't see it happening.
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
public class HeadlessExample {
public static WebDriver createHeadlessChrome() {
ChromeOptions options = new ChromeOptions();
// New headless mode (Chrome 112+)
options.addArguments("--headless=new");
// Required for Docker / CI environments
options.addArguments("--no-sandbox");
options.addArguments("--disable-dev-shm-usage");
// Set window size — headless has no default size
options.addArguments("--window-size=1920,1080");
// Disable GPU — not needed in headless
options.addArguments("--disable-gpu");
return new ChromeDriver(options);
}
public static void main(String[] args) {
WebDriver driver = createHeadlessChrome();
driver.get("https://your-app.com");
System.out.println("Title: " + driver.getTitle());
System.out.println("URL: " + driver.getCurrentUrl());
// Screenshots still work in headless mode!
// Great for debugging failures
driver.quit();
}
}// Firefox headless
FirefoxOptions ffOptions = new FirefoxOptions();
ffOptions.addArguments("--headless");
ffOptions.addArguments("--width=1920");
ffOptions.addArguments("--height=1080");
WebDriver driver = new FirefoxDriver(ffOptions);| Use Headless When | Use Headed When |
|---|---|
| Running in CI/CD pipelines (Jenkins, GitHub Actions) | Developing and debugging tests locally |
| Running in Docker containers | Investigating a failing test visually |
| Executing regression suites (speed matters) | Testing visual/UI layout issues |
| Running tests overnight or in batch | Demoing tests to stakeholders |
| Server has no display (Linux CI) | Working with complex drag-and-drop interactions |
| You want maximum parallel capacity | First-time writing a test — see what's happening |
Use --headless=new, not the old --headless flag. The old headless mode had many differences from regular Chrome. The new mode (Chrome 112+) uses the same rendering engine, so tests behave identically in headless and headed.
Some tests fail only in headless mode. Common causes: the default window size is 800x600 (elements are off-screen), or JavaScript timers behave differently. Always set --window-size=1920,1080 in headless mode.
Q: What is headless testing? When do you use it?
A: Headless testing means running a browser without a visible UI. The browser still renders pages and executes JavaScript, but nothing is displayed on screen. We use it in CI/CD pipelines where there's no monitor — Jenkins runs our tests in headless Chrome inside Docker. It's 2-3x faster than headed mode and uses less memory. We use "—headless=new" (Chrome 112+) which behaves identically to regular Chrome. For local development, we use headed mode so we can see what's happening. We make headless configurable via a system property so the same test runs both ways.
Key Point: Headless = browser without a window. Use --headless=new for CI/CD. Use headed for local debugging. Make it configurable, never hardcoded.