Bird
Raised Fist0
Selenium Javatesting~15 mins

Why POM creates maintainable test code in Selenium Java - Automation Benefits in Action

Choose your learning style10 modes available
Verify login functionality using Page Object Model
Preconditions (2)
Step 1: Open the login page URL
Step 2: Enter 'testuser@example.com' in the email input field
Step 3: Enter 'Test@1234' in the password input field
Step 4: Click the login button
Step 5: Wait for the dashboard page to load
✅ Expected Result: User is successfully logged in and dashboard page is displayed
Automation Requirements - Selenium WebDriver with Java
Assertions Needed:
Verify that the dashboard page URL is correct after login
Verify that a logout button is visible on the dashboard page
Best Practices:
Use Page Object Model to separate page locators and actions from test logic
Use explicit waits to wait for elements
Use meaningful method names in page classes
Keep test code clean and readable
Automated Solution
Selenium Java
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 org.openqa.selenium.chrome.ChromeDriver;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import java.time.Duration;

// Page Object for Login Page
class LoginPage {
    private WebDriver driver;
    private WebDriverWait wait;

    private By emailField = By.id("email");
    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 enterEmail(String email) {
        wait.until(ExpectedConditions.visibilityOfElementLocated(emailField)).sendKeys(email);
    }

    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 logoutButton = By.id("logoutBtn");

    public DashboardPage(WebDriver driver) {
        this.driver = driver;
        this.wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    public boolean isLogoutButtonVisible() {
        return wait.until(ExpectedConditions.visibilityOfElementLocated(logoutButton)).isDisplayed();
    }
}

public class LoginTest {
    private WebDriver driver;
    private LoginPage loginPage;
    private DashboardPage dashboardPage;

    @BeforeEach
    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 testSuccessfulLogin() {
        loginPage.enterEmail("testuser@example.com");
        loginPage.enterPassword("Test@1234");
        loginPage.clickLogin();

        // Verify URL contains /dashboard
        new WebDriverWait(driver, Duration.ofSeconds(10))
            .until(ExpectedConditions.urlContains("/dashboard"));
        assertTrue(driver.getCurrentUrl().contains("/dashboard"), "Dashboard URL should be displayed");

        // Verify logout button is visible
        assertTrue(dashboardPage.isLogoutButtonVisible(), "Logout button should be visible on dashboard");
    }

    @AfterEach
    public void tearDown() {
        if (driver != null) {
            driver.quit();
        }
    }
}

This test uses the Page Object Model (POM) to keep the code clean and maintainable.

LoginPage class holds locators and actions for the login page. It uses explicit waits to wait for elements before interacting.

DashboardPage class holds locators and checks for the dashboard page.

The test testSuccessfulLogin uses these page objects to perform login and verify results. This separation means if the login page changes, only LoginPage needs updating, not the test itself.

Explicit waits avoid flaky tests by waiting for elements properly.

Assertions check the URL and visibility of logout button to confirm successful login.

This structure makes the test easy to read, maintain, and extend.

Common Mistakes - 3 Pitfalls
Hardcoding locators directly in the test method
Using Thread.sleep() instead of explicit waits
Mixing test logic and UI interaction code
Bonus Challenge

Now add data-driven testing with 3 different sets of login credentials (valid and invalid).

Show Hint

Practice

(1/5)
1. What is the main reason the Page Object Model (POM) helps create maintainable test code?
easy
A. It runs tests faster by using parallel execution.
B. It separates page structure from test logic, making updates easier.
C. It requires less code to write tests.
D. It automatically fixes broken tests.

Solution

  1. Step 1: Understand POM structure

    POM organizes code by separating page details (locators, actions) from test steps.
  2. Step 2: Identify maintenance benefit

    This separation means if the page changes, only the page object needs updating, not all tests.
  3. Final Answer:

    It separates page structure from test logic, making updates easier. -> Option B
  4. Quick Check:

    Separation of concerns = easier maintenance [OK]
Hint: Remember: POM separates page and test code for easy updates [OK]
Common Mistakes:
  • Thinking POM speeds up test execution
  • Believing POM reduces code amount drastically
  • Assuming POM auto-fixes test failures
2. Which of the following is the correct way to define a WebElement in a Page Object class using Selenium Java?
easy
A. WebElement button = driver.findElement(By.name);
B. WebElement button = driver.findElement("submit");
C. WebElement button = driver.findElement(By.id("submit"));
D. WebElement button = driver.findElement(By.id);

Solution

  1. Step 1: Recall correct syntax for locating elements

    In Selenium Java, findElement requires a By locator like By.id("value").
  2. Step 2: Check each option

    WebElement button = driver.findElement(By.id("submit")); uses By.id with a string, which is correct. Others miss the locator type or string.
  3. Final Answer:

    WebElement button = driver.findElement(By.id("submit")); -> Option C
  4. Quick Check:

    Use By.id("value") for locating elements [OK]
Hint: Use By.id("value") or By.name("value") with findElement [OK]
Common Mistakes:
  • Omitting the locator type (By.id, By.name)
  • Passing locator type without string
  • Using findElement with just a string
3. Given the following Page Object method, what will be the output when calling loginPage.getTitle() if the page title is "Welcome Page"?
public class LoginPage {
  WebDriver driver;
  public LoginPage(WebDriver driver) {
    this.driver = driver;
  }
  public String getTitle() {
    return driver.getTitle();
  }
}
medium
A. "Welcome Page"
B. "Login Page"
C. null
D. Throws NullPointerException

Solution

  1. Step 1: Understand getTitle() method

    The method returns the title of the current page from the WebDriver.
  2. Step 2: Given page title is "Welcome Page"

    Calling getTitle() returns the actual page title string, which is "Welcome Page".
  3. Final Answer:

    "Welcome Page" -> Option A
  4. Quick Check:

    driver.getTitle() returns current page title [OK]
Hint: driver.getTitle() returns the current page title string [OK]
Common Mistakes:
  • Confusing method return with page object name
  • Assuming method returns null or exception without driver
  • Thinking getTitle() returns page URL
4. Identify the error in this Page Object method and how to fix it:
public void clickLogin() {
  WebElement loginBtn = driver.findElement(By.id);
  loginBtn.click();
}
medium
A. loginBtn should be declared as WebElement[] instead of WebElement.
B. click() method cannot be called on WebElement.
C. driver.findElement should be replaced with driver.findElements.
D. By.id is missing the locator string; fix by adding the id value.

Solution

  1. Step 1: Check findElement syntax

    By.id requires a string argument like By.id("loginBtn"), but here it is missing.
  2. Step 2: Fix the locator

    Add the id string inside By.id, e.g., By.id("loginBtn") to correctly locate the element.
  3. Final Answer:

    By.id is missing the locator string; fix by adding the id value. -> Option D
  4. Quick Check:

    By.id("value") needs a string argument [OK]
Hint: Always provide locator string inside By.id("value") [OK]
Common Mistakes:
  • Omitting the locator string in By.id
  • Using findElements when only one element needed
  • Thinking click() is invalid on WebElement
5. How does using the Page Object Model (POM) save time when the website under test changes its layout or element locators?
hard
A. Only the Page Object classes need updates, not all test scripts.
B. Tests automatically adapt without any code changes.
C. POM uses AI to detect and fix locator changes.
D. Test scripts are deleted and rewritten faster.

Solution

  1. Step 1: Understand POM's separation of concerns

    POM keeps locators and page actions inside Page Object classes, separate from test logic.
  2. Step 2: Effect of website changes

    If locators or layout change, only the Page Object classes need updating, so tests remain unchanged.
  3. Final Answer:

    Only the Page Object classes need updates, not all test scripts. -> Option A
  4. Quick Check:

    Update page objects, keep tests stable [OK]
Hint: Update page objects only when UI changes, not all tests [OK]
Common Mistakes:
  • Believing tests auto-update without code changes
  • Thinking POM uses AI or automation to fix locators
  • Assuming tests must be rewritten after UI changes
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard