Base page class pattern in Selenium Java - Build an Automation Script
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; import java.time.Duration; // BasePage class holds common driver and wait public class BasePage { protected WebDriver driver; protected WebDriverWait wait; public BasePage(WebDriver driver) { this.driver = driver; this.wait = new WebDriverWait(driver, Duration.ofSeconds(10)); } protected WebElement waitForVisibility(By locator) { return wait.until(ExpectedConditions.visibilityOfElementLocated(locator)); } protected WebElement waitForClickable(By locator) { return wait.until(ExpectedConditions.elementToBeClickable(locator)); } } // LoginPage class extends BasePage and contains login page actions public class LoginPage extends BasePage { private By usernameInput = By.id("username"); private By passwordInput = By.id("password"); private By loginButton = By.id("loginBtn"); public LoginPage(WebDriver driver) { super(driver); } public void enterUsername(String username) { WebElement userField = waitForVisibility(usernameInput); userField.clear(); userField.sendKeys(username); } public void enterPassword(String password) { WebElement passField = waitForVisibility(passwordInput); passField.clear(); passField.sendKeys(password); } public void clickLogin() { WebElement loginBtn = waitForClickable(loginButton); loginBtn.click(); } } // Test class to automate the login test case import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; public class LoginTest { private WebDriver driver; private LoginPage loginPage; @BeforeEach public void setUp() { driver = new ChromeDriver(); driver.manage().window().maximize(); driver.get("https://example.com/login"); loginPage = new LoginPage(driver); } @Test public void testSuccessfulLogin() { loginPage.enterUsername("testuser"); loginPage.enterPassword("Test@1234"); loginPage.clickLogin(); // Wait for URL to contain '/dashboard' boolean urlContainsDashboard = new WebDriverWait(driver, Duration.ofSeconds(10)) .until(d -> d.getCurrentUrl().contains("/dashboard")); Assertions.assertTrue(urlContainsDashboard, "URL should contain '/dashboard' after login"); } @AfterEach public void tearDown() { if (driver != null) { driver.quit(); } } }
The BasePage class holds the WebDriver and WebDriverWait objects. It provides common methods to wait for element visibility and clickability. This avoids repeating wait code in every page class.
The LoginPage class extends BasePage and contains locators and actions specific to the login page. It uses the wait methods from BasePage to ensure elements are ready before interacting.
The LoginTest class sets up the ChromeDriver, opens the login page URL, and uses the LoginPage methods to perform login steps. It then waits for the URL to contain '/dashboard' and asserts this condition to verify successful login.
This structure follows the Page Object Model and uses explicit waits for reliability. It keeps code clean, reusable, and easy to maintain.
Now add data-driven testing with 3 different username and password combinations