Page Object Model and Page Factory

Introduction

The Page Object Model (POM) and Page Factory are design patterns in test automation that enhance code maintainability and readability. POM abstracts web pages into objects, promoting reusability, while Page Factory streamlines the initialization of elements, fostering efficient test script development.

What is the Page Object Model in Selenium?

Page Object Model is a design pattern widely used in Selenium automation testing. The primary goal of POM is to create an abstraction layer between the test scripts and the web pages under test. In simpler terms, each web page in the application is represented as a Java class, encapsulating the locators and methods associated with that page.

Advantages of Page Object Model:

  1. Code Reusability: With POM, web elements and their corresponding methods are encapsulated within page classes. This makes it easy to reuse code across different test scripts.

  2. Enhanced Readability: The separation of concerns in POM enhances code readability. Test scripts focus on high-level actions, while page classes handle the implementation details.

  3. Easy Maintenance: Any changes in the UI can be accommodated by updating the corresponding page class, avoiding the need to modify multiple test scripts.

  4. Improved Collaboration: POM facilitates collaboration between developers and testers as they work on distinct components of the automation framework.

Implementing POM in Selenium Project:

Let's walk through a basic example of implementing POM in a Selenium project using Java.

Sample Project Structure for POM:

  • src/main/java/pages: Package containing page classes

  • src/test/java/tests: Package containing test scripts

  • src/test/resources: Configuration files, test data, etc.

Example: LoginPage.java

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

public class LoginPage {
    private WebDriver driver;

    // Locators
    private By usernameField = By.id("username");
    private By passwordField = By.id("password");
    private By loginButton = By.id("loginButton");

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

    // Methods
    public void enterUsername(String username) {
        driver.findElement(usernameField).sendKeys(username);
    }

    public void enterPassword(String password) {
        driver.findElement(passwordField).sendKeys(password);
    }

    public void clickLoginButton() {
        driver.findElement(loginButton).click();
    }
}

Example: LoginTest.java

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.Test;

public class LoginTest {
    @Test
    public void loginTest() {
        WebDriver driver = new ChromeDriver();
        driver.get("https://example.com");

        LoginPage loginPage = new LoginPage(driver);
        loginPage.enterUsername("user123");
        loginPage.enterPassword("pass456");
        loginPage.clickLoginButton();

        // Additional assertions and test steps
    }
}

What is Page Factory in Selenium?

While POM provides a structured approach, Page Factory takes it a step further by introducing the concept of annotations. Page Factory is an extension of POM and is used to initialize page objects and elements automatically.

Implementing Page Factory in Selenium Project:

Let's extend our previous example to incorporate Page Factory.

Sample Project Structure for Page Factory:

Example: LoginPage.java with Page Factory

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;

public class LoginPage {
    private WebDriver driver;

    // Locators using Page Factory annotations
    @FindBy(id = "username")
    private WebElement usernameField;

    @FindBy(id = "password")
    private WebElement passwordField;

    @FindBy(id = "loginButton")
    private WebElement loginButton;

    // Constructor with Page Factory initialization
    public LoginPage(WebDriver driver) {
        PageFactory.initElements(driver, this);
    }

    // Methods
    public void enterUsername(String username) {
        usernameField.sendKeys(username);
    }

    public void enterPassword(String password) {
        passwordField.sendKeys(password);
    }

    public void clickLoginButton() {
        loginButton.click();
    }
}

Difference between Page Object Model & Page Factory in Selenium:

Certainly! Let's present the differences between Page Object Model (POM) and Page Factory in Selenium in a table format for a clearer comparison:

FeaturePage Object Model (POM)Page Factory
Initialization of ElementsManual initialization of elements in the constructor.Automated initialization using PageFactory.initElements(driver, this).
Boilerplate CodeRequires explicit code for element initialization.Reduces boilerplate code; elements are initialized automatically.
AnnotationsDoes not use annotations for element identification.Leverages annotations such as @FindBy for element identification.
Code ReadabilityCode may be more verbose due to explicit initialization.Code is cleaner and more readable with automated initialization.
FlexibilityProvides flexibility in choosing when and how to initialize elements.Promotes consistency by standardizing element initialization.
Ease of MaintenanceMay require updates across multiple constructors if element locators change.Centralized initialization reduces the impact of changes to locators.
Initialization ControlDevelopers have control over when and how elements are initialized.Initialization is automated, reducing manual intervention.

By adopting these design patterns, Selenium practitioners can build scalable and efficient automation frameworks that stand the test of time, ensuring the success of their testing endeavors.

Conclusion

In conclusion, adopting the Page Object Model and Page Factory methodologies in test automation leads to cleaner, modular code and improved test script maintainability. These design patterns contribute to a more scalable and sustainable automated testing framework, enabling teams to easily adapt to changes and deliver high-quality software.