A low-code platform blending no-code simplicity with full-code power 🚀
Get started free
March 3, 2025
•
9
min read

Java Headless Browser: A Complete Guide

George Miloradovich
Researcher, Copywriter & Usecase Interviewer
Table of contents

Key Takeaways:

  • What is a Headless Browser? A browser that processes web content programmatically without a visual interface.
  • Benefits for Java Projects:
    • Speed: Runs 2–15x faster by skipping visual rendering.
    • Efficiency: Uses less memory and CPU, ideal for parallel testing.
    • Automation: Great for tasks like testing, scraping, and performance monitoring.
  • Popular Tools: Selenium WebDriver and HtmlUnit are widely used for Java automation.

Quick Comparison: Headless vs. Regular Browsers

Feature Headless Mode Regular Mode
Execution Speed Faster (2–15x) Standard
Memory Usage Lower Higher
Visual Debugging Not available Available
CI/CD Integration Well-suited Less flexible

In this guide, you’ll learn how to set up Java headless browsers, configure tools like Selenium and HtmlUnit, and optimize automation workflows for speed and reliability.

Headless Browser Testing in Selenium WebDriver with Java

Selenium WebDriver

Getting Started with Java Headless Browsers

Here's how you can set up a Java headless browser using the right tools and configurations.

Required Software

To get started, you'll need the following:

  • Java Development Kit (JDK): Install the latest stable version and make sure to set up the environment variables properly.
  • Selenium WebDriver: Download version 4.6.0 or later from Selenium's official website.
  • Browser Drivers: For Chrome, download the ChromeDriver that matches your browser's version. Place the driver in a dedicated directory for easy access.

Once you have these, integrate them into your project using Maven or Gradle.

Setting Up Maven/Gradle

Maven

If you're using Maven, create a new project and include the following dependencies in your pom.xml file:

<dependencies>
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>4.6.0</version>
    </dependency>

    <dependency>
        <groupId>org.htmlunit</groupId>
        <artifactId>htmlunit</artifactId>
        <version>4.10.0</version>
    </dependency>

    <dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>7.6.1</version>
        <scope>test</scope>
    </dependency>
</dependencies>

You'll also need to set the system property for the ChromeDriver in your code:

System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");

This ensures that Selenium can locate the ChromeDriver when running tests.

Why Use Headless Browsers?

Headless browsers are perfect for automated testing and web scraping. For instance, Optimizely managed to cut their testing time drastically - from 8 hours to just 1 hour - by using parallel testing with tools like BrowserStack Automate.

"Selenium automates browsers. That's it!" - Selenium

"HtmlUnit is a 'GUI-Less browser for Java programs'. It models HTML documents and provides an API that allows you to invoke pages, fill out forms, click links, etc... just like you do in your 'normal' browser." - HtmlUnit

Selenium WebDriver Setup Guide

Setting up Selenium WebDriver in headless mode can significantly improve testing performance. Chrome's headless mode, introduced in version 59, allows automated testing without a graphical interface, making it faster and more efficient.

Configuring Chrome for Headless Mode

To enable headless mode in Chrome, use the ChromeOptions class. Below are two ways to set it up:

ChromeOptions options = new ChromeOptions();
options.addArguments("--headless");
WebDriver driver = new ChromeDriver(options);

Or, alternatively:

ChromeOptions options = new ChromeOptions();
options.setHeadless(true);
WebDriver driver = new ChromeDriver(options);

Key Differences: Headless vs. Regular Browsers

Once your headless browser is ready, you can begin automating tasks. Here's a quick comparison of headless and regular browsers:

Feature Headless Mode Regular Mode
Execution Speed 2–15x faster Standard
Memory Usage Lower Higher
Resource Consumption Lower Higher
Visual Debugging Not available Available
CI/CD Integration Well-suited Less flexible

This comparison highlights why headless browsers are ideal for automation workflows, especially in CI/CD pipelines.

Tips for Effective Headless Testing

When working with headless browsers, keep these tips in mind:

  • Set proper window dimensions and use explicit waits to ensure elements load correctly and handle AJAX calls effectively.
  • Use screenshots for validation since visual debugging isn't an option.
  • Be aware that headless mode might not catch visual issues.

"Although PhantomJs in itself is not a test framework, it's a really good canary in a coal mine to give you some confidence; if your tests are passing, you can have a high degree of confidence that your code is ok." - Rob Friesel, Author of PhantomJS CookBook

Core Commands for Automation

Here are some essential commands to get started with Selenium automation:

// Navigate to a URL
driver.get("https://your-website.com");

// Locate and interact with elements
WebElement element = driver.findElement(By.id("elementId"));
element.sendKeys("test input");

// Capture a screenshot
File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(screenshot, new File("./screenshot.png"));

For stable tests, maximize the browser window after loading the page and set the zoom level to 100%. This ensures consistent element placement and improves test reliability.

sbb-itb-23997f1

HtmlUnit Implementation Guide

HtmlUnit

HtmlUnit is a lightweight tool designed for Java automation tasks where visual rendering isn't necessary. It's a solid option for streamlining processes that don't require a full browser interface.

HtmlUnit Features

HtmlUnit brings a range of capabilities to the table, making it a practical choice for headless automation:

Feature Category Capabilities
Protocol Support Handles HTTP, HTTPS, and full SSL
Authentication Supports Basic and NTLM authentication
JavaScript Works with advanced AJAX libraries and event handling
Request Handling Supports methods like POST, GET, HEAD, and DELETE
Network Options Includes proxy server support and custom header settings
Browser Emulation Simulates browsers like Chrome, Firefox, and Edge

Its headless nature speeds up test execution, making it a great fit for continuous integration pipelines.

"HtmlUnit is a 'GUI-Less browser for Java programs'. It models HTML documents and provides an API that allows you to invoke pages, fill out forms, click links, etc... just like you do in your 'normal' browser." - HtmlUnit

HtmlUnitDriver Setup Steps

Getting started with HtmlUnitDriver is simple:

  1. Add Dependencies For Maven projects, include the following dependency:
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>htmlunit3-driver</artifactId>
        <version>4.29.0</version>
    </dependency>
    
  2. Configure Driver and Enable JavaScript Here's an example of setting up HtmlUnitDriver with JavaScript support:
    final HtmlUnitDriverOptions driverOptions = new HtmlUnitDriverOptions(BrowserVersion.FIREFOX);
    driverOptions.setCapability(HtmlUnitOption.optThrowExceptionOnScriptError, false);
    HtmlUnitDriver driver = new HtmlUnitDriver(driverOptions);
    

This setup is quick and efficient, making it a smart choice for tests focused on performance rather than full browser emulation.

While HtmlUnit isn't ideal for testing complex JavaScript-heavy front-end applications, it shines in tasks like basic web scraping, API testing, and automated form submissions. The latest release (version 4.10.0 as of February 22, 2025) improves JavaScript handling and adds more features, keeping HtmlUnit relevant in modern automation workflows.

Advanced Features and Methods

Advanced tools and techniques can take your Java headless browser automation to the next level, making testing and scraping tasks more efficient and effective.

Taking Screenshots

Capturing full-page screenshots is a common need for debugging or documentation. Tools like aShot simplify this process and provide high-quality results.

// Using Selenium WebDriver with aShot  
WebDriver driver = new ChromeDriver(options);  
Screenshot screenshot = new AShot()  
  .shootingStrategy(ShootingStrategies.viewportPasting(1000))  
  .takeScreenshot(driver);  
ImageIO.write(screenshot.getImage(), "PNG", new File("full-page-screenshot.png"));

Here are some recommended settings to ensure consistency:

Parameter Recommended Value Purpose
Screen Width 1920px Standard desktop resolution
Screen Height 1080px Ensures consistent capture
Image Format PNG Maintains lossless quality
DPI 96 Standard screen density

Once screenshots are set up, the next step is managing sessions for smoother automated workflows.

Managing Login Sessions

Session management is essential for maintaining state across automated interactions, especially in scenarios requiring authentication. You can save and reuse cookies to streamline this process:

// Save cookies after successful login  
Set<Cookie> cookies = driver.manage().getCookies();  
FileWriter writer = new FileWriter("cookies.json");  
new Gson().toJson(cookies, writer);  
writer.close();

// Load cookies for subsequent sessions  
FileReader reader = new FileReader("cookies.json");  
Cookie[] cookies = new Gson().fromJson(reader, Cookie[].class);  
for (Cookie cookie : cookies) {  
  driver.manage().addCookie(cookie);  
}

For applications with two-factor authentication (2FA), generating one-time passwords (OTPs) programmatically can simplify the process:

// Generate OTP using secret key  
Authenticator authenticator = new Authenticator();  
String otp = authenticator.getTOTPCode(System.getenv("2FA_SECRET_KEY"));

Speed and Efficiency Tips

To improve performance and reduce execution time, consider these strategies:

  • Resource Management: Disable unnecessary features to save memory and speed up execution.
ChromeOptions options = new ChromeOptions();  
options.addArguments("--disable-gpu");  
options.addArguments("--disable-dev-shm-usage");  
options.addArguments("--no-sandbox");
  • Handling AJAX Content: Use explicit waits to ensure dynamic elements are fully loaded before interacting with them.
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));  
wait.until(ExpectedConditions.presenceOfElementLocated(By.id("dynamic-content")));
  • Parallel Execution: Run tests simultaneously to save time.
@Test(threadPoolSize = 3, invocationCount = 10)  
public void parallelTest() {  
  // Your test code here  
}

For JavaScript-heavy applications, HtmlUnit offers a faster alternative to full browser emulation. Benchmarks show that HtmlUnit can process tasks up to 60% faster than headless Chrome for basic web scraping tasks .

These advanced methods not only expand what you can achieve but also help you work more efficiently.

Problem-Solving Guide

Common Problems and Fixes

Here’s how to tackle frequent automation challenges with explicit waits and proper browser settings.

Element Interaction Issues

Encountering ElementClickInterceptedException? This often happens when elements are hidden or not fully loaded. Fix it by adjusting browser options and using explicit waits:

ChromeOptions options = new ChromeOptions();
options.addArguments("--headless");
options.addArguments("--disable-gpu");
options.addArguments("--window-size=1920,1200");
options.addArguments("--ignore-certificate-errors");

WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
wait.until(ExpectedConditions.elementToBeClickable(By.id("target-element")));

Dynamic Content Handling

For JavaScript-heavy applications, increase wait times to account for AJAX responses. Single-page applications, in particular, may need up to 30 seconds for all content to load during the initial render.

Debugging Strategies

When working without a visual interface in headless mode, rely on these methods to debug effectively:

  • Screenshot Capture: Use driver.getScreenshotAs(OutputType.FILE) to capture the current state.
  • Page Source Analysis: Retrieve the page source with driver.getPageSource().
  • Console Log Capture: Access browser console logs using driver.manage().logs().get(LogType.BROWSER).

Incorporate these debugging tools into your CI/CD pipeline to strengthen your test automation process.

CI/CD Integration Steps

Once you’ve resolved common issues, integrate your headless tests into a CI/CD workflow for seamless quality checks.

Environment Configuration

Set up your test environment with optimized Chrome settings:

ChromeOptions options = new ChromeOptions();
options.addArguments("--no-sandbox");
options.addArguments("--disable-dev-shm-usage");
options.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation"));

Test Execution Strategy

Run parallel tests to improve efficiency:

@Test(threadPoolSize = 3, invocationCount = 10)
public void parallelTests() {
    ThreadLocal<WebDriver> driver = new ThreadLocal<>();
    driver.set(new ChromeDriver(options));
    try {
        // Test implementation
    } finally {
        driver.get().quit();
    }
}

Resource Management

Prevent memory leaks by ensuring proper cleanup after each test:

@AfterMethod
public void cleanup() {
    if (driver != null) {
        driver.quit();
        driver = null;
    }
}

Add detailed logging for better troubleshooting:

private static final Logger logger = LoggerFactory.getLogger(TestClass.class);

try {
    // Test execution
} catch (Exception e) {
    logger.error("Test failed: " + e.getMessage());
    File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
    FileUtils.copyFile(screenshot, new File("error-" + System.currentTimeMillis() + ".png"));
    throw e;
}

These steps will help you build a dependable and efficient test automation framework.

Conclusion

Summary

Headless browsers have reshaped Java testing by slashing infrastructure costs by 40% and reducing testing time from 3 days to just 8 hours . Their combination of speed, efficiency, and dependability has made them a key part of modern development workflows.

Here are some standout benefits:

  • Performance: Runs 2–15× faster compared to traditional browsers .
  • Resource Efficiency: Uses less memory and CPU, allowing for parallel testing.
  • CI/CD Integration: Identifies 15% more bugs before production deployment .

If you're looking to deepen your understanding, check out the resources below.

Additional Resources

Boost your knowledge with these helpful tools and guides:

Official Documentation

  • Selenium WebDriver Documentation – Step-by-step browser automation guides.
  • HtmlUnit User Guide – Detailed API usage and examples.
  • Chrome DevTools Protocol – Insights into headless Chrome features.

Advanced Tools and Libraries

  • undetected-chromedriver – Helps bypass bot detection.
  • selenium-stealth – Enables sophisticated fingerprint manipulation.
  • webdrivermanager – Simplifies driver management automation.

One success story worth mentioning is a fintech startup that adopted Puppeteer for their testing automation. Their results? A 60% boost in test coverage and a massive drop in testing time - from 3 days to just 8 hours per release .

Both Selenium WebDriver and HtmlUnit offer reliable and scalable options for Java automation. With native headless modes now available in Chrome (since version 59) and Firefox (since version 56) , setting up automated testing and web scraping has never been more straightforward.

Related Blog Posts

Related Blogs

Use case

Backed by