Why framework design enables scalability in Selenium Java - Automation Benefits in Action
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import java.time.Duration; // Page Object for Login Page class LoginPage { private WebDriver driver; private WebDriverWait wait; private By usernameField = By.id("username"); private By passwordField = By.id("password"); private By loginButton = By.id("loginBtn"); public LoginPage(WebDriver driver) { this.driver = driver; this.wait = new WebDriverWait(driver, Duration.ofSeconds(10)); } public void enterUsername(String username) { wait.until(ExpectedConditions.visibilityOfElementLocated(usernameField)).sendKeys(username); } public void enterPassword(String password) { wait.until(ExpectedConditions.visibilityOfElementLocated(passwordField)).sendKeys(password); } public void clickLogin() { wait.until(ExpectedConditions.elementToBeClickable(loginButton)).click(); } } // Page Object for Dashboard Page class DashboardPage { private WebDriver driver; private WebDriverWait wait; private By welcomeMessage = By.id("welcomeMsg"); public DashboardPage(WebDriver driver) { this.driver = driver; this.wait = new WebDriverWait(driver, Duration.ofSeconds(10)); } public boolean isWelcomeMessageDisplayed() { return wait.until(ExpectedConditions.visibilityOfElementLocated(welcomeMessage)).isDisplayed(); } } public class LoginTest { private WebDriver driver; private LoginPage loginPage; private DashboardPage dashboardPage; @BeforeClass public void setUp() { driver = new ChromeDriver(); driver.manage().window().maximize(); driver.get("https://example.com/login"); loginPage = new LoginPage(driver); dashboardPage = new DashboardPage(driver); } @Test public void testValidLogin() { loginPage.enterUsername("validUser"); loginPage.enterPassword("validPass123"); loginPage.clickLogin(); // Verify URL String expectedUrl = "https://example.com/dashboard"; WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); wait.until(ExpectedConditions.urlToBe(expectedUrl)); Assert.assertEquals(driver.getCurrentUrl(), expectedUrl, "URL after login should be dashboard URL"); // Verify welcome message Assert.assertTrue(dashboardPage.isWelcomeMessageDisplayed(), "Welcome message should be visible on dashboard"); } @AfterClass public void tearDown() { if (driver != null) { driver.quit(); } } }
This test uses the Page Object Model (POM) design pattern to separate page details from test logic, making the framework scalable and easy to maintain.
The LoginPage class contains locators and methods for interacting with the login page. The DashboardPage class contains methods to verify elements on the dashboard.
The test class LoginTest initializes the browser, opens the login page, performs login steps, and asserts the expected URL and presence of a welcome message.
Explicit waits ensure the test waits for elements or URL changes, avoiding flaky tests.
Assertions from TestNG verify the expected outcomes clearly.
This design allows easy addition of new tests or pages without changing existing code, enabling scalability.
Now add data-driven testing with 3 different sets of valid username and password combinations