Series Navigation
← Part 2: Project Setup — Maven, Dependencies and Your First Test
→ Part 4: Locators — ID, Name, XPath, CSS and Beyond
Why Do Browser Drivers Exist?
Browsers are written in C++. Your Selenium test is written in Java. They cannot talk directly. Browser drivers are the bridge.
Java Test Code
│
│ HTTP (JSON Wire Protocol / W3C WebDriver Protocol)
▼
ChromeDriver.exe ← written by Google's Chrome team
│
│ Chrome DevTools Protocol (CDP)
▼
Chrome Browser
Each browser has its own driver maintained by the browser's own team:
| Browser | Driver | Maintained By |
|---|---|---|
| Chrome | ChromeDriver | Google Chrome Team |
| Firefox | GeckoDriver | Mozilla |
| Edge | EdgeDriver (msedgedriver) | Microsoft |
| Safari | SafariDriver | Apple (built into macOS) |
| Internet Explorer | IEDriverServer | Selenium Project |
The Version Mismatch Problem
ChromeDriver must match your Chrome browser version exactly. Chrome auto-updates, so this breaks constantly:
Chrome 85 → needs ChromeDriver 85
Chrome 86 → needs ChromeDriver 86 ← Chrome updated, test breaks
Chrome 87 → needs ChromeDriver 87
Without automation, every Chrome update requires you to:
- Check your Chrome version
- Go to chromedriver.chromium.org
- Download the matching driver
- Replace the old file
- Update the path in your code
This breaks CI pipelines at 2am when Chrome updates silently.
WebDriverManager — The Solution
WebDriverManager (by Bonigarcia) detects your browser version and downloads the matching driver automatically at runtime:
// Before WebDriverManager — manual path management
System.setProperty("webdriver.chrome.driver", "C:/drivers/chromedriver_85.exe");
WebDriver driver = new ChromeDriver();
// After WebDriverManager — one line, works forever
WebDriverManager.chromedriver().setup();
WebDriver driver = new ChromeDriver();
What happens when you call .setup():
1. Detect Chrome version installed on this machine (e.g. Chrome 86)
2. Check local cache: ~/.m2/repository/webdriver/...
3. If not cached → download ChromeDriver 86 from chromedriver.chromium.org
4. Set the system property automatically
5. Done — driver is ready to use
WebDriverManager for All Browsers
import io.github.bonigarcia.wdm.WebDriverManager;
// Chrome
WebDriverManager.chromedriver().setup();
WebDriver driver = new ChromeDriver();
// Firefox
WebDriverManager.firefoxdriver().setup();
WebDriver driver = new FirefoxDriver();
// Edge
WebDriverManager.edgedriver().setup();
WebDriver driver = new EdgeDriver();
// Safari (macOS only — no driver download needed)
WebDriver driver = new SafariDriver();
// Opera
WebDriverManager.operadriver().setup();
WebDriver driver = new OperaDriver();
ChromeOptions — Configuring Chrome Behaviour
ChromeOptions lets you control how Chrome launches:
ChromeOptions options = new ChromeOptions();
// Window settings
options.addArguments("--start-maximized"); // open maximized
options.addArguments("--window-size=1920,1080"); // exact size (for headless)
options.addArguments("--incognito"); // incognito mode
// Disable UI elements that interfere with tests
options.addArguments("--disable-notifications"); // block notification popups
options.addArguments("--disable-infobars"); // hide "automated" info bar
options.addArguments("--disable-extensions"); // disable all extensions
options.addArguments("--disable-popup-blocking"); // allow popups in tests
// Performance
options.addArguments("--no-sandbox"); // required in Linux/Docker
options.addArguments("--disable-dev-shm-usage"); // required in Docker
// Headless mode (no visible browser window)
options.addArguments("--headless"); // run without UI
options.addArguments("--disable-gpu"); // required for headless on some systems
// Ignore SSL certificate errors
options.addArguments("--ignore-certificate-errors");
options.setAcceptInsecureCerts(true);
WebDriver driver = new ChromeDriver(options);
Controlling Download Behaviour
ChromeOptions options = new ChromeOptions();
Map<String, Object> prefs = new HashMap<>();
// Set custom download directory
prefs.put("download.default_directory", "/tmp/downloads");
// Don't show download dialog
prefs.put("download.prompt_for_download", false);
// Don't open PDFs in browser
prefs.put("plugins.always_open_pdf_externally", true);
options.setExperimentalOption("prefs", prefs);
WebDriver driver = new ChromeDriver(options);
FirefoxOptions — Configuring Firefox
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.firefox.FirefoxProfile;
// Basic Firefox options
FirefoxOptions options = new FirefoxOptions();
options.addArguments("--width=1920");
options.addArguments("--height=1080");
options.setHeadless(true); // headless mode
// Firefox profile for custom settings
FirefoxProfile profile = new FirefoxProfile();
// Accept untrusted certificates
profile.setAcceptUntrustedCertificates(true);
profile.setAssumeUntrustedCertificateIssuer(false);
// Custom download folder
profile.setPreference("browser.download.dir", "/tmp/downloads");
profile.setPreference("browser.download.folderList", 2);
profile.setPreference("browser.helperApps.neverAsk.saveToDisk",
"application/pdf,application/octet-stream");
options.setProfile(profile);
WebDriverManager.firefoxdriver().setup();
WebDriver driver = new FirefoxDriver(options);
EdgeOptions — Configuring Microsoft Edge
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeOptions;
EdgeOptions options = new EdgeOptions();
options.addArguments("--start-maximized");
options.addArguments("--disable-notifications");
options.setCapability("acceptInsecureCerts", true);
WebDriverManager.edgedriver().setup();
WebDriver driver = new EdgeDriver(options);
DesiredCapabilities (Legacy — Still Used in Selenium Grid)
DesiredCapabilities is the older way to configure browsers, still used when connecting to Selenium Grid or cloud providers (BrowserStack, Sauce Labs):
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.net.URL;
DesiredCapabilities caps = new DesiredCapabilities();
caps.setBrowserName("chrome");
caps.setVersion("86.0");
caps.setPlatform(Platform.WINDOWS);
caps.setCapability("resolution", "1920x1080");
// Connect to remote Selenium Grid or cloud
WebDriver driver = new RemoteWebDriver(
new URL("http://hub:4444/wd/hub"),
caps
);
Browser Driver Factory — Clean Architecture
Rather than duplicating browser setup code, create a factory:
// src/test/java/com/yourname/selenium/base/DriverFactory.java
package com.yourname.selenium.base;
import io.github.bonigarcia.wdm.WebDriverManager;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeOptions;
public class DriverFactory {
public static WebDriver createDriver(String browserName) {
switch (browserName.toLowerCase()) {
case "chrome":
return createChromeDriver();
case "firefox":
return createFirefoxDriver();
case "edge":
return createEdgeDriver();
default:
throw new IllegalArgumentException(
"Browser not supported: " + browserName +
". Supported: chrome, firefox, edge"
);
}
}
private static WebDriver createChromeDriver() {
WebDriverManager.chromedriver().setup();
ChromeOptions options = new ChromeOptions();
options.addArguments("--start-maximized");
options.addArguments("--disable-notifications");
options.addArguments("--disable-infobars");
options.addArguments("--no-sandbox");
options.addArguments("--disable-dev-shm-usage");
return new ChromeDriver(options);
}
private static WebDriver createFirefoxDriver() {
WebDriverManager.firefoxdriver().setup();
FirefoxOptions options = new FirefoxOptions();
options.addArguments("--width=1920", "--height=1080");
return new FirefoxDriver(options);
}
private static WebDriver createEdgeDriver() {
WebDriverManager.edgedriver().setup();
EdgeOptions options = new EdgeOptions();
options.addArguments("--start-maximized");
return new EdgeDriver(options);
}
}
Use it in BaseTest:
@BeforeMethod
public void setUp() {
// Read browser from config.properties or system property
String browser = System.getProperty("browser",
config.getProperty("browser", "chrome"));
WebDriver driver = DriverFactory.createDriver(browser);
driverThreadLocal.set(driver);
}
Now run tests on different browsers without changing code:
mvn test -Dbrowser=chrome
mvn test -Dbrowser=firefox
mvn test -Dbrowser=edge
What's Next
In Part 4 we go deep on locators — the most critical skill in Selenium. We cover ID, Name, XPath, CSS selectors, link text, and how to choose the right strategy for every situation.
Discussion
Loading...Leave a Comment
All comments are reviewed before appearing. No links please.