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