Page Object Model and Page Factory using Selenium WebDriver

Page Object Model (POM) and Page Factory using Selenium WebDriver

Table of Contents

What is the Page Object Model?

Page Object Model (POM) is a design principle, mostly used in test automation that creates Object Repository for web UI elements. It creates a separate Object Repository to store object locators. Under this model, for each web page, there should be a separate page class.

The page class will have all object locators and most action methods preferably for the corresponding page. The main advantage of the model is that it reduces code duplication and improves test maintenance, making it easier to manage and update test scripts as the application evolves.

By learning this approach in a Selenium WebDriver course, you can gain practical insights into structuring your test automation framework more effectively, ensuring better scalability and cleaner code. Page Object Model (POM) can be used in any kind of framework like a data-driven, keyword-driven, modular, hybrid framework, etc. 

Why POM?

Page Object Model has become the most popular test automation design pattern around the testing industry nowadays. POM facilitates as to concentrate the AUT rather than fixing the automation suite to perform the test. In-Page Object Model the information of the object is managed outside the test script, more than making it easy to understand the test script.

Advantages of the Page Object Model?

  • Makes test code more readable
  • Helps in quickly automating test cases
  • Test cases are easy to maintain
  • Testing new functionality becomes extremely easy.
  • It makes test script maintenance very easy
  • The code becomes less and optimized
  • It avoids writing the duplicate locators for same WebElement which is the main issue that occurs in other frameworks
  • We can develop our tests faster
  • Can re-use earlier created objects for one test in another test
  • You don’t need to change our test logic if UI changes, all we need to do is just we need amend the relevant Page Object(s) to reflect the changes- the test code remains the same.
  • The Page Object Model approach makes test automation programmer more friendly, durable and comprehensive
  • The main advantage in POM is our page Object Repository is Independent of Automation Tests. Keeping the separate repository for every page objects helps us to use this repository for different purposes with different frameworks like we integrate this repository with other tools like NUnit, JUnit, etc.

How to implement POM?

Simple POM:

It is a basic structure of Page Object Model (POM) where all the Web Elements of Application Under Test (AUT) and the Web Elements whose methods are operated are maintained inside a class file. A task like verification should be separate as a part of Test Methods. 

Page Object Model (POM) and Page Factory using Selenium WebDriver

Below are the steps to create a POM without Page Factory 

1) We will create a Java Class for every web page in the application.

2) In each Java Class, declare all the Web Elements as variable.

3) Implement corresponding methods acting on the variables.

The design pattern can be implemented using 2 layers:

  • Page Layer will have the pages of the application as individual Java Class. Each Class will have WebElements declared as variables and the actions that are performed as methods.
  • Test Layer will hold the application test cases and its verification part.

Let’s take an example of a simple scenario:

  1. Open the URL of an application.
  2. Type the Email Address and password data.
  3. Click on the Login button.

Page Layer

HomePage: The page opens when the URL is entered and this is where we enter the data for login.

Steps To Create POM With Real-Time Examples

Step 1: Create a Java Class for two web Pages

In this example, we will access 2 web pages, “Home” and “Search” pages. Hence, we will create Java classes under Package Name com.automation.pages

Package Name: com.automation.pages

FaceBookHomePage.java

Step 2: Create WebElements as variables using ‘By’ Class:

  • Email, Password, Login button field on the HomePage.

Step 3: Create methods for the actions performed on WebElements:

  • Type action on the EmailAddress field.
  • Type action on the Password field.
  • Click action on the Login button.

FaceBookHomePage.java

package com.automation.pages;

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

public class FaceBookHomePage {
WebDriver driver;
 
By EmailId = By.xpath("//div[contains(@name,'email')]");
By Password = By.xpath("//div[contains(@name,'pass')]");
By LoginButton = By.xpath("//div[contains(@id,'u_0_b')]");

public void typeEmail(String emailId) {
     driver.findElement(EmailId).sendKeys(emailId);
    }
    public void typePassword(String passwordtext) {
     driver.findElement(Password).sendKeys(passwordtext);
    }
    
    public void clickContinue() {
     driver.findElement(LoginButton).click();
    }
    
    public FaceBookHomePage(WebDriver driverFromPreviousClass) {
     this.driver = driverFromPreviousClass;
    }

}

Test Layer

Here we implement Test Cases in this class.

We create another package, com.automation.test, and create a Java Class here (MainClass.java).

Steps To Create Test Cases:

  1. Initialize the driver and provide the URL to open the application.
  2. Create an object of the PageLayer Class and pass the parameter as a driver instance.
  3. By using the object created we call the methods in the PageLayer Class to perform actions/verification.
  4. Close the driver.
package com.automation.test;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

import com.automation.pages.FaceBookHomePage;
//import com.automation.pages.HomePage;

public class MainClass {
WebDriver driver;

@BeforeTest
public void SetDriver() {
System.setProperty("webdriver.gecko.driver","F:\\drivers\\geckodriver.exe");  
    WebDriver driver = new FirefoxDriver();
    driver.manage().window().maximize();
    driver.get("https://www.facebook.com/");
}
 
@Test
public void verifyLogin() {

FaceBookHomePage home = new FaceBookHomePage(driver);
home.typeEmail("[email protected]");// Give your Mail Id
home.typePassword("abtyhh@12345");// Give your Password
home.clickContinue();

}

@AfterTest
public void CloseDriver() {
driver.quit();
}

}

What Is Pagefactory?

In Selenium the PageFactory Class is an extension to the Page Object design pattern. It is used to initialize the Page Object elements or instantiate the Page Objects itself. Annotations can also be created for elements as the describing properties may not always be descriptive to tell one object from the other. It is also used to initialize the elements of the Page class without having to use ‘FindElement’ or ‘FindElements’. To supply descriptive names of target objects to improve the code readability annotations can be used. To support the PageObject pattern, WebDriver’s support library which contains a factory class. The important feature of Page Factory is the Cache feature that will store all frequently used WebElement in the cache. 

Let us know more clarity on the term PageFactory

  1. It provides an alternate way of creating an object repository in terms of syntax and semantics for the web elements on a page.
  2. It uses a different strategy to initialize the web elements.
  3. For UI web elements the object repository could be built by
  • POM without PageFactory and
  • POM with PageFactory

Let us consider a simple test scenario  

Step 1: Create a TestBase class. In this, we create an object of WebDriver, maximize browser, implementing waits, launching URL, etc. In the below program, we have a taken chrome browser and set the System Property to launch a chrome browser.

TestBase.java (BASE CLASS)

  1. Create a Package tests
  2. Create a Class TestBase.Java
package tests;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

import org.openqa.selenium.WebDriver;
//import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeSuite;

public class TestBase {
public static WebDriver driver = null;

@BeforeSuite
public void initialize() throws IOException{

System.setProperty("webdriver.gecko.driver","F:\\drivers\\geckodriver.exe");  
        driver = new FirefoxDriver();
        //To maximize browser
                driver.manage().window().maximize();
        //Implicit wait
         driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
//To open facebook
                driver.get("https://www.facebook.com");

}

@AfterSuite
//Test cleanup
public void TestClean()
    {
        TestBase.driver.quit();
    }

}

Step 2: Create classes for each page (Eg. Facebook Login Page,  Facebook Inbox Page) to hold the element locators and their methods. Usually, we will create page objects for all available pages in the AUT. For each page, we create a separate class with a constructor and we will identify all the locators and keep them in one class so that we can reuse the locators in multiple methods. It is easy to do the maintenance, if there is any change in the UI, we can simply change on one Page.

Here, I create java files (FacebookLoginPage.java and FacebookInboxPage.java) for the corresponding pages (Facebook Login Page, and Facebook Inbox Page) to hold element locators and their methods.

FBHomePage.java (Webpage 1)

  1. Create a package pages
  2. Create a class FbHomePage
package pages;

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

public class FbHomePage {
WebDriver driver;

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

    //Using FindBy for locating elements
//@FindBy(how=How.XPATH, using="//div[text()='Settings']") WebElement profileDropdown;
@FindBy(how=How.XPATH, using="//div") WebElement profileDropdown;

@FindBy(how=How.XPATH, using="//text()[.='Log Out']/ancestor::span[1]") WebElement logoutLink;
//@FindBy(how=How.XPATH, using="///div[text()='Good morning, Testing!']") WebElement loggedInUserNameText;

    
// Defining all the Methods that can be performed in the Facebook home page

    //  Method to click on Profile Dropdown
public void clickOnProfileDropdown(){
profileDropdown.click();
}
// Method to click on Logout link
public void clickOnLogoutLink(){
logoutLink.click();
}
// Method to verify LoggedIn Username Text
//public String verifyLoggedInUserNameText(){
//String userName = loggedInUserNameText.getText();
//return userName;
//}

}

FBLoginPage.java (Webpage 2)

package pages;

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

public class FbLoginPage {
WebDriver driver;

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

//Using FindBy for locating elements
@FindBy(how=How.XPATH, using="//input[@type='email'][@name='email']") WebElement emailTextBox;
@FindBy(how=How.XPATH, using="//input[@type='password'][@name='pass']") WebElement passwordTextBox;
//@FindBy(how=How.XPATH, using="//input[@type='submit'][@id='u_0_5']") WebElement signinButton;
@FindBy(how=How.ID, using = "u_0_b") WebElement signinButton;

    // Defining all the Methods that can be performed in the Facebook home page

    // Method to set Email in the email text box
public void setEmail(String strEmail){
emailTextBox.sendKeys(strEmail);
}
// Method  to set Password in the password text box
public void setPassword(String strPassword){
passwordTextBox.sendKeys(strPassword);
}
// Method to click on Login Button
public void clickOnLoginButton(){
signinButton.click();
}

}

Step 3: Create Test (Eg., FBLoginTest) as per the above pages. As per my test scenario which has mentioned above the scripts run as.

  1. Launch browser and open facebook.com
  2. Enter user credentials and do sign in
  3. Verify the loggedIn user name and do logout

FBLoginTest.java (Test Case 1)

package tests;

import org.openqa.selenium.support.PageFactory;
import org.testng.annotations.Test;

import pages.FbHomePage;
import pages.FbLoginPage;

public class FbLoginTest extends TestBase{
@Test
public void init() throws Exception{

//driver.get("https://www.facebook.com");
FbLoginPage loginpage = PageFactory.initElements(driver, FbLoginPage.class);
loginpage.setEmail("[email protected]");//Set your Username
loginpage.setPassword("xxxxyyyyzzzz");//Set your Password
loginpage.clickOnLoginButton();

FbHomePage homepage = PageFactory.initElements(driver, FbHomePage.class);
homepage.clickOnProfileDropdown();
homepage.verifyLoggedInUserNameText();
homepage.clickOnLogoutLink();
}

}

Step 4: Create testng.xml file

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Everjobs Suite">

<test name="Page Object Model">
<classes>
<class name="tests.TestBase" /> 
<class name="tests.FbLoginTest" /> 
</classes>
</test> 

</suite> <!-- Suite -->

Now, if AUT undergoes any change at the login page or any other page we just need to change the page object where we don’t need to change our test script again and again. Now your project structure will look like as below.

POM.PNG

Execute the testnG.xml file on the test suite and it will redirect to facebook.com webpage and enter all the credentials. It will then verify the username and then logout of the account. This is how we implement the Page Object Model with Page Factory.

Conclusion

The Page Object Model (POM) and Page Factory in Selenium WebDriver provide a structured, maintainable approach to building test automation frameworks. POM promotes a clean separation between the test code and the UI elements, enhancing readability and ease of maintenance by encapsulating web elements within dedicated page classes.

Using Page Factory further streamlines this process by initializing elements with annotations, making the code more efficient and reducing redundancy. Together, POM and Page Factory empower testers to create robust, scalable, and reusable test scripts, significantly improving the efficiency of Selenium WebDriver automation frameworks and ensuring that updates to UI elements require minimal changes to test scripts.

Call to Action

Ready to master the Page Object Model (POM) and Page Factory in Selenium WebDriver? Join H2K Infosys and elevate your automation testing skills with our expert-led training. Our course offers in-depth insights into structuring your Selenium tests with POM, using Page Factory for efficient element handling, and building a scalable automation framework. Gain hands-on experience and best practices from industry professionals, ensuring you’re well-equipped to tackle real-world automation challenges. Enroll today at H2K Infosys and bring your Selenium automation skills to a new level!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Share this article
Subscribe
By pressing the Subscribe button, you confirm that you have read our Privacy Policy.
Need a Free Demo Class?
Join H2K Infosys IT Online Training
Enroll Free demo class