Selenium
02 / 02

Page Object Model, Grid & Reliability

Page Object Model, Grid & Reliability

Page Object Model

public class LoginPage {
  private final WebDriver driver;
  private final By emailField = By.id("email");
  private final By passwordField = By.id("password");
  private final By submitButton = By.cssSelector("button[type=submit]");

  public LoginPage(WebDriver driver) { this.driver = driver; }

  public DashboardPage loginAs(String email, String password) {
    driver.findElement(emailField).sendKeys(email);
    driver.findElement(passwordField).sendKeys(password);
    driver.findElement(submitButton).click();
    return new DashboardPage(driver);
  }
}

// Test — reads like a business workflow, no raw locators scattered around
@Test
void userCanLogIn() {
  DashboardPage dashboard = new LoginPage(driver).loginAs("user@example.com", "pass123");
  assertTrue(dashboard.isWelcomeMessageVisible());
}
// When the UI changes, only LoginPage needs updating — not every test
// that happens to touch the login form.

Headless Mode & CI

ChromeOptions options = new ChromeOptions();
options.addArguments("--headless=new");
options.addArguments("--no-sandbox");         // often needed in Docker/CI
WebDriver driver = new ChromeDriver(options);

// Screenshot on failure — automate this in a test's teardown/failure hook
File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
Files.copy(screenshot.toPath(), Paths.get("failure.png"));

Selenium Grid

Selenium Grid runs tests in parallel across multiple machines/browsers/OS combinations, coordinated through a central hub — essential for a cross-browser test matrix that would take far too long sequentially on one machine. Pinning specific, tested browser/driver version combinations (rather than always "latest") is standard practice, since each vendor's own WebDriver implementation can behave subtly differently across versions.

SPA Synchronization

Client-side route changes in a single-page app often don't trigger the kind of navigation event Selenium waits on for driver.get() — content updates asynchronously after JS runs. Wait for a specific resulting element/condition with ExpectedConditions rather than assuming a URL change alone means the new content is ready.

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free