Skip to content

Lesson 03 · Page Object Model & Design

Beyond the 1Z0-830 exam

The single most important pattern for maintainable UI tests is the Page Object Model (POM): wrap each screen in a class that hides its locators behind intention-revealing methods. Tests then read in business terms, and a markup change touches one class instead of dozens of tests. This is what the module's green lab demonstrates.

Objectives

After this lesson you will be able to:

  • Explain the Page Object Model and the problem it solves.
  • Write a page object that encapsulates locators and exposes actions.
  • Return the next page object to model navigation.
  • Reduce duplication with component objects.

The problem POM solves

Without page objects, selectors leak into every test:

java
// ❌ Brittle: every test repeats locators. Change #login-btn → 30 tests break.
driver.findElement(By.id("username")).sendKeys("ada");
driver.findElement(By.id("password")).sendKeys("secret");
driver.findElement(By.id("login-btn")).click();

A page object

Encapsulate the page's structure and behavior in a class. The test speaks intent, not selectors:

java
public class LoginPage {
    private static final String USERNAME = "#username";   // locators in ONE place
    private static final String PASSWORD = "#password";
    private static final String SUBMIT   = "#submit";

    private final Browser browser;
    public LoginPage(Browser browser) { this.browser = browser; }

    public DashboardPage loginAs(String user, String pass) {
        browser.type(USERNAME, user);
        browser.type(PASSWORD, pass);
        browser.click(SUBMIT);
        return new DashboardPage(browser);   // return the page you land on
    }
}
java
// ✅ The test reads as a sentence and knows nothing about selectors:
DashboardPage dash = new LoginPage(browser).loginAs("ada", "secret");
assertThat(dash.isLoaded()).isTrue();

This is exactly the lab's design — LoginPage.loginAs returns a DashboardPage, and the test never names a CSS selector.

Return the next page

A method that navigates should return the page object for the destination. That models the flow and lets tests chain across screens with compile-time safety:

java
HomePage home = new LoginPage(browser)
    .loginAs("ada", "secret")   // → DashboardPage
    .openMenu()                 // → MenuComponent
    .goHome();                  // → HomePage

Fail fast on the wrong page

The lab's loginAs throws if the URL isn't /dashboard after submit. A page object should assert it landed where expected, so a misstep fails there — not three actions later with a confusing stale-element error.

Components for reuse

A header, nav bar, or modal that appears on many pages is a component object — a smaller page object composed into pages:

java
public class HeaderComponent {
    private final Browser browser;
    public HeaderComponent(Browser b) { this.browser = b; }
    public void search(String q) { browser.type("#search", q); browser.click("#go"); }
    public boolean isLoggedIn()  { return browser.text("#user").length() > 0; }
}

Pages expose the component (page.header().search("widgets")), so the search logic lives once.

Gotcha — keep assertions out of page objects (mostly)

A page object models interaction; the test owns the assertions about expected outcomes. Sprinkle verification (assertThat(...)) through page objects and you get tests that can't express their own intent and fail in confusing places. The exception: a page object may assert it loaded correctly (a precondition), as the lab does.

Key Takeaways

  • The Page Object Model hides locators behind intention-revealing methods — tests read in domain terms.
  • Locators live in one place; a markup change updates the page object, not every test.
  • A navigating method should return the next page object to model the flow.
  • Extract repeated UI (headers, modals) into component objects.
  • Keep assertions in tests; page objects may only assert they loaded correctly.

Lesson Quiz

Lesson Quiz · Page Object Model & Design0 / 5
  1. The core benefit of the Page Object Model is…

    • AFaster browsers
    • BLocators/actions are encapsulated, so a UI change touches one class instead of many tests
    • CIt removes the need for waits
    • DIt generates test data
  2. A page-object method that submits a form and navigates should ideally return…

    • Avoid
    • BThe page object for the destination page
    • CThe raw WebDriver
    • DA boolean only
  3. Where should the assertions about expected outcomes live?

    • AInside every page object method
    • BIn the test (page objects may only assert they loaded correctly)
    • CIn the browser config
    • DNowhere
  4. A header/nav reused across many pages is best modeled as…

    • ACopy-pasted into each page object
    • BA component object composed into pages
    • CA separate test class
    • DA static utility with hard-coded selectors everywhere
  5. Why keep CSS selectors out of test bodies?

    • AThey're slow to type
    • BSelectors in tests duplicate page structure; a change breaks many tests instead of one page object
    • CTests can't use strings
    • DIt's a compiler rule

Next: Stable UI Tests. This module's lab is in labs/src/main/java/com/jse21/m18_ui/.