Explore partnership opportunities with testRigor Learn More
Turn your manual testers into automation experts!Request a Demo

Page Object Model (POM) – Why and When Should You Use It?

Weekly Newsletter
Receive weekly testRigor newsletters packed with insights on test automation, codeless testing, and the latest advancements in AI.

Software applications are becoming increasingly complex as innovation and evolution advance. It is increasingly challenging to maintain reliable and scalable test automation. As applications evolve, the once-small, manageable automated test suites become complex, difficult to maintain, update, and debug. One of the most effective design patterns for solving these challenges is the Page Object Model (POM).

Key Takeaways:
  • A Page Object Model (POM) is a popular design pattern in test automation that enhances test maintenance and reduces code duplication.
  • There are areas within your web app’s UI that your tests interact with. A page object will model only these areas as objects within the test code, reducing duplicated code.
  • The benefit of a page object is that if the UI changes, only the code within it needs to be updated. Tests don’t need to change.
  • Teams can organize their test automation code using POM by separating test logic from UI element locators and interactions.
  • Automated tests are easier to manage, especially in large web applications undergoing frequent UI changes, thanks to the separation of test logic using POM.

In this article, we’ll explore what the Page Object Model is, why it is important, when it should be used, its advantages and limitations, and best practices for implementing it effectively.

What is the Page Object Model?

A Page Object Model (or POM) is a design pattern used in test automation (mostly Selenium) in which each web page or a significant component of a page is represented as a separate class. This class contains web element locators, methods that interact with those elements, and business actions to be performed on the page.

It is an object repository for storing and organizing page elements. Instead of writing UI locators and interaction logic directly inside test scripts, we encapsulate them in this page’s classes or objects.

For example, consider a login page containing the following components:
  • Username field
  • Password field
  • Login button

Using POM, a LoginPage class is created containing all these elements and their related actions.

Without POM, you would have to access the fields and components of the login page using their IDs as follows:
driver.findElement(By.id("username")).sendKeys("user");
driver.findElement(By.id("password")).sendKeys("password");
driver.findElement(By.id("login")).click();
On the other hand, with POM, you define a LoginPage class that can be instantiated, and you can directly access its fields and methods as seen in the code below:
LoginPage loginPage = new LoginPage(driver);
loginPage.enterUsername("user");
loginPage.enterPassword("password");
loginPage.clickLogin();

As you can see, the above code is cleaner and more readable. If you have such a code in your test script, it will become easier to maintain and adapt as applications grow and evolve.

The advantage of using POM is that it reduces code redundancy and complexity, makes code more extensible, and improves test script maintenance by acting as an interface for the page under test. To simplify the POM concept, we create a class file for each web page. The class file contains web elements available on the web page that can later be used by test scripts to execute different operations.

POM Explanation with an Example

Let us understand the POM concept with a detailed example.

Take a look at the line of code below that is often used in Selenium without a POM applied.
driver.findElement(By.id("user_email_login")).sendKeys("[email protected]")

As you can see, there is no separation between the locators and actions on web elements.

In the POM, the above code will be changed to have two separate sections, one for Identification methods and the second for Operational methods. So, the above statement is divided into separate sections within the class.

So if you have an application with these web pages: login, home, customer, and transaction. In real time, a separate class is created for each page, like loginClass, homeClass, and so on. All the web elements locators are defined in one section, and operations to be performed on them are defined in another section.

Note: You can also choose to create separate classes, one for Identification methods and the second for Operational methods, for each web page, like loginLocatorsClass and loginClassMethods.

Hence, the above line of code using Page Object Model looks like the following:
By emailId = By.id("user_email_login");
public void enterEmailId() {
  driver.findElement(emailId).sendKeys("[email protected]");
}

What If You Avoid Using POM?

To see what happens if you avoid using POM, let’s take the same example as above:
driver.findElement(By.id("user_email_login")).sendKeys("[email protected]")
There are various problems with this approach:
  • There is no clear separation between the test method and the application under test (AUT)’s locators (id’s in this example); both are used together in a single method. If the AUT’s UI changes its identifiers, layout, or how a login is input and processed, the test itself must also be changed.
  • If we need to use the same web element in another place, we have to locate it again. Essentially, this means developing the same code again and again. The code is not reusable, leading to duplicate and unreadable code.
  • Suppose the same locator is used in multiple script files, and this locator gets changed at some point. It is then a tedious task to update this locator in all script files, especially if the project is large and complex. Imagine if multiple locators are changed? It leads to a lot of wasted time and effort.

The page object model is explicitly used to handle the above scenarios, which we may encounter quite frequently.

Why Should You Use POM?

The following are the reasons why POM is used:
  • Improved Maintainability: This is one of the primary reasons for using POM. In traditional automation frameworks, there are locators scattered across multiple test scripts, and hence, when a UI element changes, every test using that element should be updated.
    With POM, locators are stored in one place, and hence changes needed are to be made only once. This decreases the maintenance effort significantly.
    For example, if the login button ID changes from id="login" to id="signin", you only need to update the locator in the page object class.
  • Better Code Reusability: Most applications have common actions such as logging in, searching for products, navigating menus, or filling forms that are performed repeatedly. Instead of duplicating these actions across test cases, you can have reusable methods using POM that can be used across hundreds of tests.
  • Enhanced Readability: Using POM in test scripts increases the reliability. Consider the following example showing the traditional approach and using POM:
    Traditional Approach POM Approach
    driver.findElement(By.id("user")).sendKeys("admin");
    driver.findElement(By.id("pass")).sendKeys("password");
    driver.findElement(By.id("login")).click();
    loginPage.login("admin", "password");
    If you compare the two approaches, the second approach is much easier to understand, even for non-technical stakeholders.
  • Better Scalability: As applications grow, the number of automated tests increases rapidly. If automation is not properly organized, it becomes difficult to manage.
    When architecture uses POM, each page has its own class, tests remain independent, and new pages can be added efficiently. These make applications easily scalable.
  • Reduced Test Maintenance Costs: Frequent UI updates are common in Agile and DevOps environments. As a result, a small UI change may break dozens of tests. However, if POM is used, you only need to update once, and it fixes multiple tests automatically.
  • Lazy Initialization: This is a load concept in POM. It will not find web elements until the element is used. Lazy initialization helps in performance optimization, where object creation can be deferred until just before we need it. The key reason for doing this is that you can often avoid creating the object if you don’t need it.
  • Page Chaining: Using POM, there is better coordination between pages, which helps in a concept called Page Chaining to make test steps more readable and, therefore, maintainable. Suppose after login, you are moved to another web page named AccountDetailsPage. Using the login method, you can return an object of AccountDetailsPage.
See example below:
public class LoginPage {

  public WebDriver driver;

  public LoginPage(WebDriver driver) {
    this.driver = driver;
  }

  public AccountDetailsPage login(String username, String password) {
    driver.findElement(By.id("username")).sendKeys(username);
    driver.findElement(By.id("pwd")).sendKeys(password);
    driver.findElement(By.id("loginBtn")).click();
    return new AccountDetailsPage(driver);
  }
}

Sample Project Structure for POM

Here is a sample project structure of the page object model. Here, each web page is represented as a Java class file.

When Should You Use POM?

Although POM is extremely useful to developers, it is not always necessary. Here are some of the ideal scenarios for using POM:
  • Medium to Large Applications: If your application contains multiple pages, complex workflows, or reusable components, POM provides tremendous value.
    For example, POM can be used for test automation in E-commerce platforms, banking applications, healthcare systems, and enterprise SaaS products.
  • Long-Term Automation Projects: If the automation is to be maintained for a long time in terms of months or years, POM is useful in keeping the framework sustainable. In this case, the long-term projects benefit from easier updates, better collaboration, and reduced technical debt.
  • Large QA Teams: When you have a large QA team with multiple engineers contributing to the same automation project, consistency is critical. In this case, POM is helpful as it creates a standardized structure that everyone can follow.
    With POM, large QA teams have easier onboarding, better collaboration, and cleaner code reviews.
  • Frequently Changing Applications: Application UI is frequently updated when it is under active development. POM minimizes the impact of these changes by centralizing locator and page interaction definitions.
  • CI/CD Environments: POM creates reliable test suites that integrate well with CI/CD tools such as Jenkins, GitHub Actions, GitLab CI/CD, and Azure DevOps. It helps these pipelines with stable and maintainable automation.

Best Practices for Implementing POM

Consider the following best practices when implementing POM:
  • Keep Page Objects Focused: Ensure each page class represents a single page or component. Avoid mixing functionality from multiple pages.
  • Use Meaningful Method Names: Use method names that reflect the purpose (business action) of the method. For example, if you are defining a method for submitting a login form, name it as submitLoginForm() and not clickButton().
  • Avoid Assertions in Page Classes: Include assertions in test classes, not in page objects that interact with the application.
  • Use Explicit Waits: Avoid hardcoded waits like Thread.sleep(5000); Instead, use the following:
    WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  • Reuse Components: Create reusable component classes for headers, navigation menus, dialog boxes, and sidebars to minimize duplication.
  • Follow the Single Responsibility Principle: Don’t turn page classes into utility classes. Each page object should have an individual purpose.

POM and Modern Test Automation

Modern automation tools continue to support POM concepts, although it is the most popular design pattern in Selenium-based frameworks.

Unlike traditional automation tools that require maintaining locators and page objects, AI-powered tools such as testRigor reduce the need for POM by allowing tests to be written using plain English and user-visible text.

For example:
enter "admin" into "Username"
enter "password" into "Password"
click "Login"
check that page contains "Welcome"

As you can see in the code above, tests rely on what users see rather than technical locators, thereby significantly reducing maintenance effort.

In this case,
  • No page classes are required.
  • No locator repositories are required.
  • UI changes often don’t require updating test code.
  • Business workflows become the primary reusable unit instead of page objects.
When teams want reusability, testRigor allows users to use reusable rules as follows:
rule login as user
   enter stored value "username" into "Username"
   enter stored value "password" into "Password"
   click "Login"
end rule
Then, you can use the above rule as follows:
run rule "login as user"

Common flows such as Login, Checkout, Create customer, and Submit order are extracted into reusable rules instead of page classes.

However, for teams using Selenium, Playwright, or other code-based automation frameworks, POM remains an important design pattern.

Conclusion

The POM is a foundational design pattern in UI test automation because it addresses one of the biggest challenges in automated testing: maintainability. By separating page interactions from test logic, POM creates cleaner, more reusable, and more scalable test frameworks.

POM is helpful to organizations that automate medium- to large-scale web applications to improve readability, reduce duplication, minimize maintenance costs, and support the long-term growth of their automation suites. While it may introduce some initial overhead, the long-term advantages often outweigh the setup effort.

However, POM is not a one-size-fits-all solution. Small projects, short-lived automation efforts, or modern AI-driven testing approaches may not require traditional page objects.

Therefore, teams should evaluate their project size, complexity, maintenance requirements, and tooling before deciding whether POM is the right fit. Combined with sound design principles and proper implementation, the POM remains one of the most effective design patterns for building reliable, maintainable automated testing frameworks.

Frequently Asked Questions (FAQs)

  • When should you use the Page Object Model?
    POM is best suited for medium to large web applications, long-term automation projects, applications with frequent UI changes, and teams managing extensive automated test suites.
  • Is POM suitable for small automation projects?
    While POM can be used in small projects, it may introduce unnecessary complexity when there are only a few pages and test cases. Simpler automation structures may be more appropriate for small-scale projects.
  • How does POM improve test maintenance?
    POM stores locators and page-specific actions in dedicated page classes. If a UI element changes, only the locator in the page object needs updating, reducing maintenance efforts across the entire test suite.
  • What is the difference between POM and traditional test automation?
    In traditional automation, locators and interaction logic are often embedded directly in test scripts. POM separates these concerns by moving page-related logic into dedicated classes, resulting in cleaner and more maintainable code.
  • Should page objects contain assertions?
    No. Page objects should focus on UI interactions and business actions. Assertions should typically remain in test classes to maintain a clear separation of responsibilities.
You're 15 Minutes Away From Automated Test Maintenance and Fewer Bugs in Production
Simply fill out your information and create your first test suite in seconds, with AI to help you do it easily and quickly.
Achieve More Than 90% Test Automation
Step by Step Walkthroughs and Help
14 Day Free Trial, Cancel Anytime
“We spent so much time on maintenance when using Selenium, and we spend nearly zero time with maintenance using testRigor.”
Keith Powe VP Of Engineering - IDT
Privacy Overview
This site utilizes cookies to enhance your browsing experience. Among these, essential cookies are stored on your browser as they are necessary for ...
Read more
Strictly Necessary CookiesAlways Enabled
Essential cookies are crucial for the proper functioning and security of the website.
Non-NecessaryEnabled
Cookies that are not essential for the website's functionality but are employed to gather additional data. You can choose to opt out by using this toggle switch. These cookies gather data for analytics and performance tracking purposes.