Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Workflow:SeleniumHQ Selenium Page Object Pattern Testing

From Leeroopedia
Revision as of 11:01, 16 February 2026 by Admin (talk | contribs) (Auto-imported from workflows/SeleniumHQ_Selenium_Page_Object_Pattern_Testing.md)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Knowledge Sources
Domains Testing, Test_Architecture, Page_Objects
Last Updated 2026-02-11 23:00 GMT

Overview

End-to-end process for structuring browser automation tests using the Page Object pattern with Selenium PageFactory, enabling maintainable, reusable, and readable test code through declarative element location and lazy-loading proxies.

Description

This workflow describes how to use Selenium built-in Page Object support (PageFactory and associated annotations) to create maintainable test suites. The Page Object pattern encapsulates page-specific locators and interactions into dedicated classes, separating test logic from page structure. Selenium PageFactory automates the initialization of page objects by creating lazy-loading proxy objects for annotated WebElement fields that defer element lookup until first interaction.

Key outputs:

  • Page Object classes that encapsulate page structure and behavior
  • Lazy-loading element proxies that locate elements on demand
  • Reusable page interaction methods that can be shared across tests
  • Maintainable test code where locator changes are isolated to page objects

Scope:

  • Covers PageFactory, @FindBy annotations, and FieldDecorator pattern
  • Applies primarily to Java bindings (other languages have similar but distinct patterns)
  • Includes caching, chained locators, and custom decorators

Usage

Execute this workflow when building a test suite that covers multiple pages or complex user flows, and you want to keep locator definitions separate from test assertions. This pattern is the recommended approach when page structures may change over time or when the same page interactions are needed across multiple test scenarios.

Execution Steps

Step 1: Define Page Object Classes

Create a Java class for each distinct page or significant page component in the application under test. Each class encapsulates the locators and interaction methods for that page.

What happens:

  • A page object class is created with WebElement fields for each interactive element
  • Fields are annotated with @FindBy to specify the locator strategy (ID, CSS, XPath, class name, link text)
  • Public methods expose meaningful page interactions (login, search, addToCart) rather than raw element operations
  • The constructor typically accepts a WebDriver instance for any direct driver interactions needed

Key considerations:

  • @FindBy supports all WebDriver locator strategies: id, css, xpath, className, linkText, partialLinkText, name, tagName
  • @FindAll (OR logic) combines multiple @FindBy annotations to match elements found by any strategy
  • @FindBys (AND logic) chains multiple @FindBy annotations to narrow matches sequentially
  • The How enum maps strategy names to By factory methods for programmatic configuration

Step 2: Initialize Page Objects with PageFactory

Use PageFactory.initElements() to create an instance of the page object class with all WebElement fields wrapped in lazy-loading proxy objects.

What happens:

  • PageFactory.initElements(driver, PageClass.class) instantiates the class via reflection
  • The constructor is resolved: first tries a WebDriver-accepting constructor, then a no-arg constructor
  • A DefaultElementLocatorFactory is created from the driver instance
  • A DefaultFieldDecorator iterates over all fields in the class and its superclasses
  • Each WebElement or List of WebElement field is replaced with a proxy that defers element lookup

Key considerations:

  • PageFactory uses Java reflection and Proxy to create lazy-loading element wrappers
  • Fields that are not WebElement or List of WebElement are left untouched
  • An existing instance can be initialized with PageFactory.initElements(driver, existingInstance)
  • Custom FieldDecorator implementations can override the default proxy behavior

Step 3: Configure Element Caching

Optionally annotate WebElement fields with @CacheLookup to cache the element reference after the first lookup, avoiding repeated DOM queries for stable elements.

What happens:

  • Without @CacheLookup, every method call on the proxy triggers a new findElement call
  • With @CacheLookup, the first lookup result is stored and reused for subsequent calls
  • This improves performance for elements that do not change between interactions

Key considerations:

  • Only use @CacheLookup for elements that are always present and never re-rendered
  • Dynamic content, elements in SPAs that re-render, or elements that may become stale should NOT be cached
  • StaleElementReferenceException will occur if a cached element is removed from the DOM

Step 4: Implement Page Interaction Methods

Write public methods on the page object that combine element interactions into meaningful business operations. These methods form the API that test classes use.

What happens:

  • Methods use the proxied WebElement fields to perform clicks, text entry, and state queries
  • Complex interactions (multi-step forms, drag-and-drop, modal handling) are encapsulated in single method calls
  • Methods return the appropriate page object for the next expected state (enabling fluent navigation chains)
  • Assertions and test logic remain outside the page object class

Key considerations:

  • Page objects should not contain assertions; they return data that tests assert against
  • Navigation methods should return the target page object type for method chaining
  • Waits for dynamic content should be handled within page object methods
  • Thread safety can be enforced using ThreadGuard to detect cross-thread WebDriver access

Step 5: Write Tests Using Page Objects

Create test classes that instantiate page objects and call their interaction methods, keeping test code focused on business logic and assertions rather than DOM mechanics.

What happens:

  • Test setup creates a WebDriver and initializes the first page object
  • Test methods call page object methods to perform user flows
  • Assertions verify the expected state using values returned by page object methods
  • Test teardown calls driver.quit() to clean up the browser session

Key considerations:

  • Tests read like business scenarios rather than technical element manipulation scripts
  • When page HTML structure changes, only the affected page object needs updating
  • Page objects can be shared across test suites for consistent interaction patterns
  • The AbstractFindByBuilder base class enables custom annotation processing for specialized locator strategies

Execution Diagram

GitHub URL

Workflow Repository