Table of Contents
- Challenges with UI Test Automation
- What is the Page Object Model?
- Implementing Page Object Model with Selenium
- Types of Page Object Models
- Page Object Model Best Practices
- Page Object Model Tools and Frameworks
- Page Object Model – Best Practices and Tips
- Page Factory in Selenium
- Should You Adopt Page Object Model?
- Conclusion
Automated testing is crucial for delivering high quality software quickly. However, building and maintaining test automation suites is challenging – 55% of organizations cite the inability to reuse tests across projects as a key limitation. The Page Object Model (POM) pattern tackles this exact problem for UI test automation.
This comprehensive guide will teach you how to leverage the power of Page Object Model and Page Factory in Selenium to write resilient, reusable and maintainable automated tests.
Challenges with UI Test Automation
Let‘s first understand why UI testing is complex:
- Frequent UI changes – With agile development, the application UI evolves rapidly
- Complex test code – UI tests often have convoluted code that interacts with many elements
- Flaky tests – 30% of UI test failures are caused by flakiness making tests unreliable
- Hard to maintain – With complex code and frequent UI changes, tests are difficult to maintain
These challenges slow down delivery cycles, waste precious testing time and affect software quality.
The Page Object Model approach provides solutions to these exact pain points.
What is the Page Object Model?
The Page Object Model (POM) is a design pattern that creates an abstraction layer between test code and application UI.
Here is how it works:
For each unique web page in the application, there is a corresponding Page Class. This class encapsulates the UI locators and methods interacting with page elements. Tests then use the methods exposed by Page Classes instead of directly accessing UI elements.

Image credit: Tom Hombergs on Medium
So why is this useful?
Benefits of the Page Object Model
Here are the major advantages of using the Page Object Model approach:
1. Improves test code maintainability
- 60% reduction in script maintenance effort according to a Capability Assurance study
- Changes required in fewer places since UI map separated from tests
- Promotes reuse across multiple tests
2. Resilient to UI changes
- Only Page Class needs to be updated on UI change
- No updates required in test methods
- 35% faster resolution of test failures due to UI changes
3. Forces modularity
- Each Page Class has focused functionality
- Logical grouping of user interactions
- Promotes independent test creation
4. Facilitates collaboration
- Separates test code from UI implementation
- Enables parallel development between dev and QA teams
- Promotes collective ownership
5. Optimizes execution
- Operations can be performed faster since element locators initialized only once
- Statelessness prevents stale element references
- Conditional waits optimize performance
Overall, Page Object Model saves significant time, effort and leads to robust test automation.
Implementing Page Object Model with Selenium
Let‘s explore how to implement effective Page Objects with Selenium WebDriver using Java:
1. Identify unique pages
Analyze the application workflow and carve out logical pages. These should represent distinct UI layouts mapped to core user journeys.
For a banking app these could be:
- Login Page
- Accounts Summary Page
- Funds Transfer Page
- New Account Page
2. Create Page Class for each unique page
Here is how the Login Page class would look:
public class LoginPage {
WebDriver driver;
//Locator for username input field
@FindBy(id = "username")
WebElement username;
//Locator for password input field
@FindBy(id = "password")
WebElement password;
//Locator for login button
@FindBy(id = "login-button")
WebElement loginButton;
//Constructor to initialize driver
public LoginPage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
//Method to login with username and password
public void login(String un, String pw) {
username.sendKeys(un);
password.sendKeys(pw);
loginButton.click();
}
}
Here we initialize locators, encapsulate interactions and expose the login method.
3. Build reusable page methods
Page methods should be:
-
Task-focused – Perform cohesive action e.g. login(), addToCart()
-
Parameterized – Take inputs if needed to vary runtime data
-
Reusable – No test assertions, designed for cross-test use
4. Make tests use page methods
The test class creates Page objects and calls the encapsulated page methods:
public class LoginTests {
WebDriver driver;
LoginPage loginPage;
@BeforeTest
public void setup() {
driver = new FirefoxDriver();
loginPage = new LoginPage(driver);
}
@Test
public void validLogin() {
//Use login() method instead of complex UI code
loginPage.login("john123", "pass456");
Assert.assertTrue(driver.getCurrentURL().contains("/home"))
}
}
This improves maintainability as tests focus on validation while Pages handle interactions.
Let‘s discuss some advanced Page Object Model implementations.
Types of Page Object Models
There are some extensions of the Page Object pattern that solve additional test automation challenges:
1. Layered Page Objects
Here page objects are grouped across layers for better abstraction based on what they represent – web elements, logical components like forms or mini workflows:

Image credit: Angle Grinder Blog
2. PageFactory Pages
PageFactory introduces @FindBy annotations and initElements method to initialize locators avoiding redundancy.
3. Angular Page Objects
Specialized JavaScript based page objects for testing Angular applications.
So which variant makes most sense? It depends on application tech stack, team skills and scope of testing among other factors.
Page Object Model Best Practices
Here are some key best practices to implement page object pattern effectively:
- Have only one instance of a page e.g. singleton pages
- Idealize statelessness across page methods
- Parameterize inputs variables for reusability
- Nullify page instance references after usage
- Implement lazy element initialization
- Externalize environment data into config files
- Follow naming conventions for uniformity
Page Object Model Tools and Frameworks
There are some popular open-source frameworks that facilitate easier page object implementations:
1. Selenium PageObject:
- Native Ruby binding shipped with Selenium WebDriver
- Includes PageFactory for annotating elements
- Helper methods like on_page?()
2. FluentLenium:
- Java fluent interface for concise Page Objects
- Browser invocation and assertion features
- Integrates with JUnit and TestNG
3. WebDriverIO:
- JavaScript based bindings natively in Node.js
- Supports synchronous and async test scripts
- Active community, support for CI/CD
So in summary, Page Object Model is a versatile pattern that can be implemented across languages and test runners.
Page Object Model – Best Practices and Tips
Let‘s round up some key best practices to keep in mind:
Keep Pages lightweight
Pages should only contain element locators and interactions, not assertions or Conditional logic
Ideally make Pages stateless
Statelessness prevents stale element references and improves reusability
Parameterization aids reusability
Constructor and method inputs parameters promote reuse of Pages across tests
Nullify object references
Set page instance variables to null post usage to prevent memory leaks
Lazy load elements
Use annotations like @FindBy to lazy load locators only when referenced
Follow naming conventions
Use consistent locator naming schemes across the framework
Page Factory in Selenium
An extension of Page Object Model in Selenium is the Page Factory. This uses a special PageFacotry class to instantiate page objects in an optimized way.
Here is an example Page implemented using Page Factory:
@FindBy(id = "username") WebElement username;
@FindBy(id = "password") WebElement password;
public LoginPage() {
PageFactory.initElements(driver, this);
}
public void login() {
username.sendKeys("test");
password.sendKeys("1234");
}
The key advantages Page Factory provides:
- Removes need to use
findElementexplicitly - Annotates locators for readability
- Lazy element initialization
So in summary, combine Page Factory with POM for optimal test automation framework.
Should You Adopt Page Object Model?
The Page Object Model brings invaluable benefits:
✔ 60% faster automation suite maintenance
✔ 35% quicker test failure diagnosis due to UI changes
✔ Enables 20% or more reusable test code
✔ 25% increased collaboration between dev and QA
So if you are dealing with:
- Frequent regression test failures
- High maintenance overhead
- Lack of code reuse
- Challenges in test data management
Page Object Model can drastically improve these aspects of UI test automation.
Conclusion
Here are the key highlights:
- Page Object Model creates separation between test logic and UI
- For each unique page have a Page Class encapsulating elements and interactions
- Page methods should be reusable across tests
- Tests should invoke Page methods instead of complex UI code
- Page Factory provides annotation based elements for cleaner tests
- Adoption leads to easier test maintenance with 60%+ savings in effort
So leverage the power of this pattern to boost productivity, reuse and reliability of your UI test automation initiatives.