📣 Requestly API Client – Free Forever & Open Source. A powerful alternative to Postman. Try now ->

Selenium tests on Chrome using ChromeDriver: Tutorial

Rohit Rajpal
Learn how to set up and use Selenium ChromeDriver to run automated tests on Chrome with configuration steps, features, and troubleshooting tips.
Selenium tests on Chrome using ChromeDriver Tutorial

Selenium interacts with Chrome through ChromeDriver, a standalone executable that translates Selenium commands into actions performed in the browser. For testers, this setup is essential not only for running local tests but also for scaling executions on cloud environments.

Selenium ChromeDriver also unlocks Chrome-specific features such as headless execution, custom browser profiles, performance logging, and integration with Chrome DevTools Protocol. However, since ChromeDriver is tightly coupled with the installed version of Chrome, version mismatches and configuration errors are frequent issues.

This tutorial explains how to download, configure, and use ChromeDriver effectively, while covering advanced features and common challenges.

What is Selenium ChromeDriver?

ChromeDriver is an executable maintained by the Chromium team that allows Selenium to control the Chrome browser. Selenium commands are sent to ChromeDriver, which interprets them using the WebDriver protocol and communicates with Chrome through browser APIs.

It is built specifically for Chrome and other Chromium-based browsers. This gives testers access to features such as headless execution, browser profiles, extensions, geolocation simulation, and performance logging that go beyond standard Selenium commands.

Since ChromeDriver versions are tied to Chrome releases, maintaining compatibility is essential. Testers must install the correct driver version to avoid failures caused by mismatched updates.

How to Download ChromeDriver for Selenium

ChromeDriver must match the version of Chrome installed on the system. If the versions are mismatched, Selenium may fail to start the browser or throw session errors. Downloading the correct version depends on whether your Chrome browser is version 115 or above, or 114 and below.

Steps to Download ChromeDriver Version 115 and Above

From Chrome version 115 onward, ChromeDriver is distributed through the Chrome for Testing (CfT) initiative. The older download links no longer provide updated binaries.

Here are the steps:

  • Check your installed Chrome version: Open Chrome and go to chrome://settings/help.
  • Visit the Chrome for Testing download page: https://googlechromelabs.github.io/chrome-for-testing.
  • Locate the section for your Chrome version.
  • Download the driver binary for your operating system (Windows, macOS, Linux).
  • Extract the downloaded archive and place the executable in a directory accessible by your system path.

Steps to Download ChromeDriver Version 114 and Below

For Chrome versions 114 and earlier, ChromeDriver binaries are available on the original Chromium download site.

Here are the steps:

  • Confirm your installed Chrome version from chrome://settings/help.
  • Visit the official Chromium ChromeDriver site: https://chromedriver.chromium.org/downloads.
  • Find the release matching your Chrome version.
  • Download the driver for your operating system.
  • Extract the executable and move it to a location included in your system path.

Example: Suppose Chrome version 116 is installed. The corresponding driver can be downloaded from the Chrome for Testing page under version 116. On macOS, the downloaded chromedriver-mac-x64.zip should be extracted and placed in /usr/local/bin so it can be called directly without specifying the path in the test code.

Configuring ChromeDriver

After downloading ChromeDriver, Selenium must be able to locate the executable during test execution. Configuration can be done in two ways: by setting it as a system environment variable or by specifying the path directly in the code.

1. Using Environment Variable

Setting ChromeDriver in the system path allows it to be accessed globally without adding its location in every test script. This is the preferred method for long-term setup.

  • On Windows: Add the ChromeDriver folder path to the Path variable under System Environment Variables.
  • On macOS or Linux: Move the binary to /usr/local/bin or update the .bashrc or .zshrc file to export the path.

Once configured, Selenium can invoke ChromeDriver without extra configuration in code.

2. Using System.setProperty Method

If environment variables are not set, Selenium requires the driver path explicitly in the test code. This method is often used in quick tests or temporary setups.

Example in Java:

				
					import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class ConfigExample {
    public static void main(String[] args) {
        System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.example.com");
        driver.quit();
    }
}
				
			

This approach works immediately but can become repetitive if used in multiple scripts. For larger projects, environment variables are more efficient.

Chrome-Specific Functionalities in Selenium

Selenium can run tests across different browsers, but ChromeDriver unlocks functionality that is unique to Chrome and Chromium-based browsers. These features help testers go beyond simple navigation and assertions.

1. ChromeDriver Basics

Every test starts with launching Chrome through ChromeDriver. It establishes the WebDriver session and listens for commands from Selenium, which are then executed in Chrome.

				
					WebDriver driver = new ChromeDriver();
driver.get("https://www.google.com");
System.out.println(driver.getTitle());
driver.quit();
				
			

This code launches Chrome, opens Google, prints the page title, and closes the browser. Even in this simple example, ChromeDriver is the piece that translates Selenium’s high-level commands into Chrome’s native actions. Without it, Selenium would not be able to control the browser.

2. Chrome Headless Mode

Headless mode runs Chrome without rendering the graphical interface. This reduces overhead and is essential for test environments where a display is not available, such as Docker containers or CI/CD servers.

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

This command runs Chrome invisibly but still executes all actions like navigation, clicks, and form submissions. Testers use headless mode for speed, parallel execution, and when running tests on infrastructure that cannot open a visible browser. However, it should be used carefully, as some UI issues are only visible in non-headless mode.

3. ChromeOptions

ChromeOptions is a flexible class that allows customization of browser startup. It lets testers pass arguments, set preferences, and configure capabilities. This is crucial for building stable environments where unwanted pop-ups, prompts, or inconsistent window sizes could affect test reliability.

				
					ChromeOptions options = new ChromeOptions();
options.addArguments("--start-maximized");
options.addArguments("--disable-notifications");
WebDriver driver = new ChromeDriver(options);
				
			

Here Chrome opens maximized and with notifications disabled. This matters in testing because inconsistent window sizes or notification pop-ups could cause element locators to fail. Testers often use ChromeOptions to create predictable environments for UI validation.

4. Browser Profiles

Chrome profiles store cookies, bookmarks, history, and extensions. By loading a specific profile, testers can simulate real users who already have data in their browser, such as logged-in sessions or installed add-ons.

				
					ChromeOptions options = new ChromeOptions();
options.addArguments("user-data-dir=/path/to/custom/profile");
WebDriver driver = new ChromeDriver(options);
				
			

This example opens Chrome with a given profile. It helps validate scenarios like “Remember me” login flows, session persistence, or testing how extensions interact with an application. For testers working on applications with strong personalization, profiles are essential for realistic coverage.

5. Handling Pop-ups and Alerts

JavaScript alerts, confirms, and prompts interrupt automation if not handled. ChromeDriver provides APIs to interact with them so that tests continue smoothly.

				
					Alert alert = driver.switchTo().alert();
System.out.println(alert.getText());
alert.accept();
				
			

This switches to the alert, prints its message, and accepts it. Without this handling, Selenium would throw an exception. Pop-up handling is critical in flows such as payment confirmations or unsaved changes prompts.

6. Executing JavaScript

Some actions are not fully supported by Selenium APIs, such as scrolling into view, triggering events, or reading hidden properties. In such cases, ChromeDriver allows JavaScript execution inside the page context.

				
					JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("window.scrollBy(0,500)");
				
			

This scrolls the page down by 500 pixels. Testers use this when dealing with infinite scrolls, lazy-loaded content, or dynamic UI elements that are not visible until scrolled into view. It provides flexibility where Selenium’s built-in methods are limited.

7. Performance Logging

Modern applications rely heavily on network requests. ChromeDriver can capture performance logs that record network activity, console output, and timing information.

				
					LoggingPreferences logs = new LoggingPreferences();
logs.enable(LogType.PERFORMANCE, Level.ALL);

ChromeOptions options = new ChromeOptions();
options.setCapability("goog:loggingPrefs", logs);

WebDriver driver = new ChromeDriver(options);
				
			

This enables the collection of performance logs. Testers can later analyze them to verify API calls, response times, or errors logged in the browser console. For example, checking if all images load correctly or if third-party scripts delay rendering.

8. Chrome DevTools Protocol (CDP)

CDP provides deeper access to Chrome’s internals. Through CDP, testers can intercept network requests, throttle bandwidth, capture console logs, and mock geolocation. Selenium 4 integrates CDP directly.

				
					DevTools devTools = ((HasDevTools) driver).getDevTools();
devTools.createSession();
devTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty()));
				
			

This snippet starts a DevTools session and enables network tracking. With CDP, testers can block certain domains, monitor API calls, or debug issues that are not visible through normal Selenium APIs. It brings automation closer to developer-level debugging.

9. Geolocation

Applications like maps, delivery services, or ride-sharing rely on geolocation. ChromeDriver can override the location so that testers can validate location-specific features without physically moving.

				
					Map<String, Object> coordinates = new HashMap<>();
coordinates.put("latitude", 37.7749);
coordinates.put("longitude", -122.4194);
coordinates.put("accuracy", 1);

((ChromeDriver) driver).executeCdpCommand("Emulation.setGeolocationOverride", coordinates);
				
			

This sets the browser location to San Francisco. When the application requests geolocation, it receives this simulated data. It allows testing of geo-restricted content, location-based pricing, or region-specific features.

10. Extensions

Some workflows require browser extensions, such as password managers or ad blockers. ChromeDriver allows installing extensions at runtime so testers can verify application behavior with them.

				
					ChromeOptions options = new ChromeOptions();
options.addExtensions(new File("/path/to/extension.crx"));
WebDriver driver = new ChromeDriver(options);
				
			

This loads Chrome with the specified extension. It is valuable for testing compatibility with commonly used tools or validating enterprise workflows that depend on custom extensions.

Running Selenium Tests on Chrome

After downloading and configuring ChromeDriver, tests can be executed on Chrome in two main environments: a local browser on the tester’s machine or a real browser hosted on a cloud testing service such as BrowserStack Automate. Both approaches have specific use cases and limitations that testers should understand.

1. Local Chrome Browser

Running tests on a locally installed Chrome browser is the most common starting point. It allows quick feedback and is useful for debugging scripts before scaling them to larger environments.

				
					import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class LocalChromeTest {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.example.com");
        System.out.println("Page Title: " + driver.getTitle());
        driver.quit();
    }
}
				
			

This example launches the locally installed Chrome, navigates to the given site, prints the title, and closes the browser. Local execution is simple but has limitations: it runs only on the machine’s operating system, with one version of Chrome, and does not replicate real device conditions like mobile browsers or older OS versions.

2. Real Chrome Browser via Automate

For broader coverage, tests can run on real browsers hosted in the cloud. BrowserStack Automate, for example, provides access to thousands of real devices and Chrome versions without requiring local setup. This ensures applications are tested under conditions closer to real-world usage.

				
					import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.net.URL;

public class CloudChromeTest {
    public static void main(String[] args) throws Exception {
        ChromeOptions options = new ChromeOptions();
        WebDriver driver = new RemoteWebDriver(
            new URL("https://username:accesskey@hub-cloud.browserstack.com/wd/hub"), 
            options
        );
        driver.get("https://www.example.com");
        System.out.println("Page Title: " + driver.getTitle());
        driver.quit();
    }
}
				
			

This script runs on a cloud-hosted Chrome browser. Instead of using the local ChromeDriver binary, it connects to the remote hub URL provided by the service. The advantage is the ability to run tests across multiple OS and Chrome combinations, validate responsiveness on different devices, and identify environment-specific bugs early.

Running tests locally is useful for development and quick debugging, while real-browser testing on services like Automate ensures coverage across versions, platforms, and devices that are difficult to maintain in-house.

Best Practices for Using Selenium ChromeDriver

Working with ChromeDriver becomes easier and more reliable when certain practices are followed. These practices reduce flakiness in tests, improve maintainability, and ensure compatibility across Chrome versions and environments. Below are the most important practices to adopt:

1. Keep ChromeDriver and Chrome Browser in Sync

ChromeDriver versions are tied to specific Chrome browser versions. A mismatch often leads to “session not created” errors. Always ensure the ChromeDriver version matches the browser installed. For projects running on multiple environments, consider using a driver manager library like WebDriverManager that automatically resolves the correct version.

				
					import io.github.bonigarcia.wdm.WebDriverManager;
WebDriverManager.chromedriver().setup();
WebDriver driver = new ChromeDriver();
				
			

This removes the manual effort of downloading and configuring ChromeDriver, and it avoids common version mismatch errors.

2. Use ChromeOptions for Stability and Control

Passing custom arguments through ChromeOptions helps stabilize tests. For example, disabling notifications, using incognito mode, or launching in headless mode can make tests more predictable.

				
					ChromeOptions options = new ChromeOptions();
options.addArguments("--disable-notifications");
options.addArguments("--incognito");
WebDriver driver = new ChromeDriver(options);
				
			

This ensures the test session is not interrupted by browser pop-ups or cached data from earlier runs.

3. Clean Up Browser State Between Tests

Carrying over cookies, sessions, or cached data between tests can create false positives. Configure tests to start with a fresh state by using incognito mode or clearing data explicitly.

				
					driver.manage().deleteAllCookies();
				
			

This guarantees each test runs independently without unintended influence from earlier executions.

4. Avoid Hard-Coded Waits

Hard-coded Thread.sleep() calls slow down tests and make them flaky. Instead, use Selenium’s explicit waits (WebDriverWait) that pause execution only until the expected condition is met.

				
					WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
wait.until(ExpectedConditions.titleContains("Example"));
				
			

This improves both the reliability and performance of test execution.

5. Run on Real Devices and Multiple Versions

Local Chrome may not represent how your application behaves across all environments. Running tests on real devices with cloud services like BrowserStack ensures coverage across Chrome versions, operating systems, and hardware. This reduces the risk of bugs escaping into production.

Common Challenges and Troubleshooting with Selenium ChromeDriver

Even with the correct setup, testers often face issues while running Selenium tests with ChromeDriver. These problems usually arise from version mismatches, misconfiguration, or resource limitations.

1. Session Not Created Error

This occurs when the ChromeDriver version does not match the installed Chrome browser. The error message usually mentions the incompatible versions.

Fix: Update ChromeDriver to match the browser version. Using WebDriverManager can automate this and prevent mismatches.

				
					WebDriverManager.chromedriver().setup();
WebDriver driver = new ChromeDriver();
				
			

2. Chrome Crashes or Freezes During Tests

Chrome may crash if system resources are low or when running in headless mode without proper arguments.

Fix: Add arguments to stabilize headless execution.

				
					ChromeOptions options = new ChromeOptions();
options.addArguments("--disable-gpu");
options.addArguments("--no-sandbox");
options.addArguments("--disable-dev-shm-usage");
WebDriver driver = new ChromeDriver(options);
				
			

These options reduce GPU dependency and prevent shared memory issues in CI environments like Docker.

3. Element Not Interactable or Not Clickable

Sometimes Selenium locates an element but cannot interact with it because it is hidden, overlapped, or not yet loaded.

Fix: Use explicit waits and ensure the element is visible before interaction.

				
					WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement button = wait.until(ExpectedConditions.elementToBeClickable(By.id("submit")));
button.click();
				
			

4. Pop-Ups and Permission Alerts Blocking Execution

Unexpected alerts, notifications, or permission dialogs can block the test flow.

Fix: Disable them with ChromeOptions or handle them using Selenium’s Alert interface.

				
					ChromeOptions options = new ChromeOptions();
options.addArguments("--disable-notifications");
				
			

5. Path or Environment Variable Issues

If Selenium cannot locate ChromeDriver, tests fail before even launching Chrome.

Fix: Either set the system property in code or configure the path globally through environment variables.

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

6. Slow Execution or Timeouts

Tests may run slowly if multiple browser instances are open, unnecessary animations are running, or waits are poorly configured.

Fix: Optimize waits, close browsers after each test, and use headless execution where UI rendering is not required.

Why Run Selenium ChromeDriver Tests on Real Devices?

Local Chrome testing helps with debugging, but it does not represent how applications behave for actual users. Differences in browser versions, operating systems, device hardware, and mobile environments can introduce bugs that remain invisible in local setups.

Running tests on real devices ensures that applications are validated in conditions closer to real-world usage, reducing the risk of environment-specific failures.

BrowserStack Automate provides a cloud-based platform that enables Selenium tests to run on real Chrome browsers across thousands of devices and OS combinations. This removes the need to maintain an in-house lab and gives testers access to a wide coverage matrix instantly.

Key features of BrowserStack that support Selenium testing include:

  • 3,500+ Real Devices and Browsers: Access to a large variety of Chrome versions on Windows, macOS, Android, and iOS.
  • Parallel Test Execution: Run multiple Selenium tests at once to reduce overall test execution time.
  • CI/CD Integrations: Seamless integration with Jenkins, GitHub Actions, Azure DevOps, and other CI/CD tools.
  • Local Testing Support: Test applications hosted on local or staging servers before production release.
  • Debugging Tools: Access to video recordings, screenshots, and detailed logs to identify failures quickly.

Conclusion

Selenium ChromeDriver is essential for running automated tests on Chrome, whether for validating UI workflows, handling advanced browser features, or ensuring compatibility across Chrome versions. While local execution is useful for debugging and development, it cannot fully replicate the wide range of environments where end users access applications.

Running Selenium tests on real devices with BrowserStack ensures accuracy, scalability, and broader coverage. With access to thousands of Chrome versions across operating systems and devices, along with debugging tools and CI/CD integrations, BrowserStack helps teams deliver reliable applications faster while reducing the effort of maintaining in-house test infrastructure.

Written by
Rohit Rajpal
Rohit Rajpal is a B2B Content Strategist at BrowserStack, helping SaaS brands build AI-first strategies that drive authority and revenue. He writes about content, strategy, and the future of search in the zero-click era.

Related posts