Selenium WebDriver
The original browser automation standard — a W3C protocol dominant in NZ enterprise Java teams and the foundation of thousands of regression suites.
1 The Hook — The NZ Bank Regression Slowdown
A major NZ bank had a regression suite of 2,000 Selenium tests. It took four hours to run, and on a "good" day, only 80% would pass. The other 20% failed because of network lag, slow page loads, or elements shifting by a few pixels. The automation team spent 70% of their week just "fixing tests" that weren't actually broken.
This is the classic Selenium struggle in large enterprises. Without a strict Page Object Model and robust Explicit Waits, Selenium suites become a liability rather than an asset. Mastering Selenium means mastering the art of handling the unknown.
Senior engineer insight
The biggest shift in my thinking with Selenium wasn't learning the API — it was realising that test flakiness is almost never a test problem, it's a timing contract problem. The browser is asynchronous, your assertions are synchronous, and the gap between them is where suites go to die. Once you treat every WebDriverWait as a formal contract — "this element will be in state X before I proceed" — your suite stabilises almost overnight.
The most common mistake: teams inherit a suite with implicit waits baked in at setup, then add explicit waits on top — creating a double-wait multiplier that makes already-slow tests pathologically unpredictable.
From the field
A Wellington-based fintech running open banking integrations had a Selenium suite of roughly 800 tests written over three years by four different developers. Each dev had a slightly different Page Object convention, two used implicit waits, one used Thread.sleep() everywhere, and nobody had documented which ChromeDriver version the CI agent was pinned to. The team assumed the suite was "basically working" — it consistently showed 85% green on Jenkins. What they hadn't noticed was that 15% of tests were silently skipped due to a misconfigured TestNG listener, not actually passing. When a new senior QA engineer audited the suite properly, the real pass rate was 61%. The fix wasn't more tests — it was three weeks of structural work: unified POM conventions, a single explicit-wait utility class, and WebDriverManager replacing the pinned binary. After that, the suite ran reliably at 96% green with no flaky-test triage Fridays.
2 The Rule — POM and Explicit Waits
Never interact with a page directly in your test script. Always use Page Objects to encapsulate UI details, and use Explicit Waits for every interaction.
Page Objects keep your tests readable when the UI changes. Explicit waits ensure your script doesn't try to click a button before it's actually ready to be clicked.
3 The Analogy — The Remote-Control Car
The Remote Control.
Selenium is like a remote-control car. You have the controller, but the car doesn't know where it's going. If you tell it to "turn left for 2 seconds," but the car is on grass instead of pavement, it might not turn enough. You have to constantly watch it and give it micro-adjustments (waits) to make sure it doesn't hit a wall.
4 Watch Me Do It — NZ Banking Login (Java)
Scenario: Testing a login flow using the Page Object Model in Java.
// 1. The Page Object
public class LoginPage {
WebDriver driver;
WebDriverWait wait;
By username = By.id("username");
By password = By.id("password");
By loginBtn = By.cssSelector(".btn-login");
public LoginPage(WebDriver driver) {
this.driver = driver;
this.wait = new WebDriverWait(driver, Duration.ofSeconds(10));
}
public void login(String user, String pass) {
wait.until(ExpectedConditions.visibilityOfElementLocated(username)).sendKeys(user);
driver.findElement(password).sendKeys(pass);
wait.until(ExpectedConditions.elementToBeClickable(loginBtn)).click();
}
}
// 2. The Test
@Test
public void testSuccessfulLogin() {
LoginPage loginPage = new LoginPage(driver);
loginPage.login("tester@resync.nz", "SecurePass123!");
Assert.assertTrue(driver.getCurrentUrl().contains("dashboard"));
}
5 Decision Tool — Why Selenium?
✅ Choose Selenium for...
- Existing Java/C# enterprise suites
- Teams with deep Java/TestNG expertise
- Massive cross-browser Grid setups
- Integrating with legacy Java reporting
❌ Switch to Playwright for...
- New projects (Greenfield)
- Modern JS/TS frontend teams
- Faster execution and better stability
- Built-in network mocking and tracing
6 Common Mistakes
🚫 Mixing Implicit and Explicit Waits
Don't: Use driver.manage().timeouts().implicitlyWait() AND WebDriverWait.
Actually: This causes unpredictable delays. Stick to 100% Explicit Waits for reliability.
🚫 Using Thread.sleep()
Don't: Thread.sleep(5000);
Do: wait.until(ExpectedConditions.visibilityOf(...));
Hard sleeps waste time. Explicit waits move as soon as the element is ready.
7 Now You Try — Maven Setup
To start a Selenium Java project, add this to your pom.xml:
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.18.1</version>
</dependency>
Pair it with WebDriverManager to handle browser drivers automatically:
WebDriverManager.chromedriver().setup();
WebDriver driver = new ChromeDriver();
Why teams fail here
- Locator rot: Tests anchored to auto-generated IDs or absolute XPaths break silently every sprint when frontend developers refactor markup — nobody notices until the CI pipeline turns red on a Friday afternoon.
- Driver version drift: The ChromeDriver binary on the CI server diverges from the Chrome version on developer laptops; tests pass locally, explode in the pipeline, and teams waste hours diagnosing what is actually a one-line WebDriverManager fix.
- State leakage between tests: Browser sessions are not properly torn down — cookies, local storage, or session tokens from test N bleed into test N+1, producing failures that only appear when tests run in a specific order.
- Treating Selenium as a black box: Teams script happy-path flows and declare the test "done" without asserting meaningful application state — the test clicks through the UI successfully while the underlying API silently returns a 500, and nobody knows until a customer calls.
Key takeaway
Selenium doesn't make your tests reliable — your architecture does; the framework just executes whatever contracts you've been disciplined enough to write.
8 Self-Check
Q1. What is the main disadvantage of an Absolute XPath?
It's extremely brittle. If a developer adds a single <div> anywhere in the hierarchy, the XPath breaks. Always use ID, Name, or Relative CSS/XPath locators.
Q2. What is Selenium Grid used for?
Parallel and Distributed testing. It allows you to run your tests across different machines and browser types simultaneously, significantly reducing the total run time of a large suite.
9 Interview Prep
"Explain the Page Object Model (POM)."
Answer: "POM is a design pattern that creates an object repository for UI elements. Each web page has a corresponding class that contains the locators and the actions that can be performed on that page. This separates the 'what to test' from the 'how to find it', making scripts more maintainable and reusable."
10 Next Step
You've seen the enterprise giant. Now, let's look at the tool that simplified JavaScript testing for developers: Cypress.