TechBeamersTechBeamers
  • Learn ProgrammingLearn Programming
    • Python Programming
      • Python Basic
      • Python OOP
      • Python Pandas
      • Python PIP
      • Python Advanced
      • Python Selenium
    • Python Examples
    • Selenium Tutorials
      • Selenium with Java
      • Selenium with Python
    • Software Testing Tutorials
    • Java Programming
      • Java Basic
      • Java Flow Control
      • Java OOP
    • C Programming
    • Linux Commands
    • MySQL Commands
    • Agile in Software
    • AngularJS Guides
    • Android Tutorials
  • Interview PrepInterview Prep
    • SQL Interview Questions
    • Testing Interview Q&A
    • Python Interview Q&A
    • Selenium Interview Q&A
    • C Sharp Interview Q&A
    • PHP Interview Questions
    • Java Interview Questions
    • Web Development Q&A
  • Self AssessmentSelf Assessment
    • Python Test
    • Java Online Test
    • Selenium Quiz
    • Testing Quiz
    • HTML CSS Quiz
    • Shell Script Test
    • C/C++ Coding Test
Search
  • Python Multiline String
  • Python Multiline Comment
  • Python Iterate String
  • Python Dictionary
  • Python Lists
  • Python List Contains
  • Page Object Model
  • TestNG Annotations
  • Python Function Quiz
  • Python String Quiz
  • Python OOP Test
  • Java Spring Test
  • Java Collection Quiz
  • JavaScript Skill Test
  • Selenium Skill Test
  • Selenium Python Quiz
  • Shell Scripting Test
  • Latest Python Q&A
  • CSharp Coding Q&A
  • SQL Query Question
  • Top Selenium Q&A
  • Top QA Questions
  • Latest Testing Q&A
  • REST API Questions
  • Linux Interview Q&A
  • Shell Script Questions
© 2024 TechBeamers. All Rights Reserved.
Reading: Page Object Model (POM) and Page Factory Guide in Selenium Java
Font ResizerAa
TechBeamersTechBeamers
Font ResizerAa
  • Python
  • SQL
  • C
  • Java
  • Testing
  • Selenium
  • Agile Concepts Simplified
  • Linux
  • MySQL
  • Python Quizzes
  • Java Quiz
  • Testing Quiz
  • Shell Script Quiz
  • WebDev Interview
  • Python Basic
  • Python Examples
  • Python Advanced
  • Python OOP
  • Python Selenium
  • General Tech
Search
  • Programming Tutorials
    • Python Tutorial
    • Python Examples
    • Java Tutorial
    • C Tutorial
    • MySQL Tutorial
    • Selenium Tutorial
    • Testing Tutorial
  • Top Interview Q&A
    • SQL Interview
    • Web Dev Interview
  • Best Coding Quiz
    • Python Quizzes
    • Java Quiz
    • Testing Quiz
    • ShellScript Quiz
Follow US
© 2024 TechBeamers. All Rights Reserved.
Selenium Tutorial

Page Object Model (POM) and Page Factory Guide in Selenium Java

Last updated: Apr 14, 2024 7:37 pm
By Meenakshi Agarwal
Share
19 Min Read
Page Object Model and Page Factory Guide in Selenium Java
SHARE

Understanding the Page Object Model (POM) and Page Factory in Selenium is important for writing efficient and maintainable automation scripts. POM helps you keep web elements and actions in a structured way, making your code more concise. Page Factory eases up the creation of page elements, resulting in cleaner and less code. Learning these concepts is essential when you are working on a large project. Hence, this tutorial aims to equip you with the skills needed to improve the effectiveness and reliability of your automation tests.

Contents
The Concept of Page Object ModelBenefits of the Page Object ModelHow to Apply POM in ProjectsDemo Selenium Project for POMStep1. Create Page ClassesStep2. Create a Test ClassStep3. Run the TestThe Concept of Page FactoryBenefits of the Page FactoryDemo Selenium Project for Page FactoryPage Object Model (POM) vs Page Factory in SeleniumMore Resources to Learn Selenium at TechBeamers

A Quick Guide to Page Object Model and Page Factory

In practical terms, the Page Object Model (POM) is a design pattern used in Selenium automation testing. It involves arranging your code to represent web pages as objects, encapsulating their elements and actions in dedicated classes. This approach improves the code structure, reusability, and maintainability, making it easier to manage and update test scripts as your web application evolves.

The Concept of Page Object Model

The Page Object Model, or POM, treats each webpage as a reusable object in your code. It stores UI elements and actions within these objects, separating them from test logic. This keeps tests clean, promotes DRY principles, and makes them easier to maintain and scale. Imagine organized code where UI changes only affect the page object, not every test!

Benefits of the Page Object Model

POM’s magic lies in separation! Each webpage becomes a dedicated object, housing its elements and actions. This offers 3 main benefits:

  • Maintainability: UI changes? Update the page object, not every test! No more brittle tests breaking with each tweak.
  • Code Clarity: Say goodbye to spaghetti code! Clean, separate classes for each page make your codebase easy to read and navigate.
  • Reusability: Write actions once, and use them everywhere! DRY principles shine as you reuse common interactions across tests, saving time and effort.
  • Reduce Redundancy: Minimizes code duplication, promoting cleaner and more efficient scripts.

POM keeps your tests organized, efficient, and scalable, making you a true automation champion!

For example – A non-POM class in your project can have a method A that has logic to directly interact with a webpage and fetch some data. The other methods of the class also need this data but they can’t access it as it was local to the function A. Moreover, there could be other classes requiring a similar function but end up duplicating the code. On the other hand, the classes in the page object model follow certain specifications and hence can overcome all the above issues we saw. Below is a diagram briefly capturing the differences between non-POM vs POM classes.

Non-page object model class vs page object model class

How to Apply POM in Projects

You can get POM into your project in the following 3 steps:

  • Page Object Classes: Craft a class for each web page, housing element locators, and related actions. Think of them as dedicated objects representing their respective pages.
  • Element Locators: Store locators (like IDs or CSS selectors) within these classes, keeping them separate from test logic. This ensures changes only affect the page object, not the entire test suite.
  • Action Methods: Define methods within each class to interact with the elements. These methods encapsulate actions like clicking, entering text, or validating content.

    Remember, it’s all about separation and organization! By following these steps, you’ll unlock the power of POM for maintainable and efficient Selenium tests.

    Demo Selenium Project for POM

    For this demo project, we’ll be using the latest Selenium version 4, Java 17, and the latest / stable Google Chrome driver.

    Great! Let’s create a demo Selenium Java project using the Page Object Model for booking a flight from the Google Flights page. We’ll provide a simple example; please adjust it based on your specific needs and the actual structure of the web page.

    In this demo project, we have 2 page classes and a test class. The following is the UML class diagram for this. It will help you get clarity on what these classes are doing.

    Flight Booking Page Object Model Class Diagram

    To get the code built and run on your system, you should typically follow these steps.

    Step1. Create Page Classes

    Create a class for each page on the website. In this case, you may need a class for the Google Flights homepage and another for the flight booking page.

    The following is the first of the page classes you should create. It will simply launch the browser and open up the Google flight search page.

    // HomePage.java
    import org.openqa.selenium.By;
    import org.openqa.selenium.WebDriver;
    
    public class HomePage {
      private WebDriver wd;
    
      public HomePage(WebDriver wd) {
        this.wd = wd;
      }
    
      public void navigateToFlights() {
        wd.get("https://www.google.com/travel/flights");
      }
    }

    Now, create the 2nd class of the page object model. It has the main logic to set locations, and dates along with a method to search for the available flights.

    // FlightsPage.java
    import org.openqa.selenium.*;
    import java.time.Duration;
    import org.openqa.selenium.support.ui.*;
    import org.openqa.selenium.support.locators.RelativeLocator;
    
    public class FlightsPage {
      private WebDriver wd;
      private WebDriverWait wt;
    
      public FlightsPage(WebDriver wd) {
        this.wd = wd;
        this.wt = new WebDriverWait(wd, Duration.ofSeconds(10));
      }
    
      public WebElement setLocation(String location, String locPath) {
    
        // Find the input field
        WebElement locFld = new WebDriverWait(wd, Duration.ofSeconds(10))
          .until(ExpectedConditions.visibilityOfElementLocated(By.xpath(locPath)));
    
        // Clear existing content and set new value in the origin input field
        locFld.clear();
        locFld.sendKeys(location);
    
        // Wait for the dropdown suggestions to appear
        WebElement firstSuggestion = wt.until(ExpectedConditions.presenceOfElementLocated(RelativeLocator
          .with(By.className("zsRT0d"))
          .below(locFld)));
    
        // Click on the first suggestion
        firstSuggestion.click();
    
        return locFld;
      }
    
      public WebElement setDate(String dateStr, WebElement left) {
    
        try {
          // Wait for the date field to appear
          WebElement dateFld = wt.until(ExpectedConditions.presenceOfElementLocated(RelativeLocator
            .with(By.tagName("input"))
            .toRightOf(left)));
    
          // Click on the first suggestion
          dateFld.clear();
          dateFld.sendKeys(dateStr);
    
          return dateFld;
    
        } catch (Exception e) {
          // Handle the exception (e.g., log it) and return null or a default WebElement
          System.out.println("Element not found: " + e.getMessage());
          return null;
        }
      }
    
      public void searchFlight(String searchPath) {
    
        try {
          // Find the search button
          WebElement searchBtn = new WebDriverWait(wd, Duration.ofSeconds(2))
            .until(ExpectedConditions.visibilityOfElementLocated(By.xpath(searchPath)));
    
          // Click on the search
          searchBtn.click();
    
        } catch (Exception e) {
          // Handle the exception (e.g., log it)
          System.out.println("Search button not found: " + e.getMessage());
          // You may choose to throw a custom ex
          // Or handle it in another way as per your req.
        }
      }
    }

    You may have noticed that we have used the new Selenium 4 relative locators in the above code. This puts up a good example of their usage. You can try to use them in your other automation tasks.

    Step2. Create a Test Class

    Create a test class that utilizes the page classes to perform the desired actions. This class mainly consumes the methods present in the second Page class. It sets up the source and destination locations. After that, it checks out the departure and arrival dates. Finally, it finds and presses the “Search” button.

    // FlightBookingTest.java
    import org.openqa.selenium.*;
    import org.openqa.selenium.chrome.*;
    import java.time.LocalDate;
    import java.time.format.DateTimeFormatter;
    
    public class FlightBookingTest {
      public static void main(String[] args) {
        // Set the path to the ChromeDriver executable
        System.setProperty("webdriver.chrome.driver", "/opt/chromedriver/chromedriver");
    
        // Configure ChromeOptions to start with a maximized window
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--start-maximized");
    
        // Create a new instance of the ChromeDriver
        WebDriver wd = new ChromeDriver(options);
    
        try {
          // Instantiate the page classes
          HomePage homePage = new HomePage(wd);
          FlightsPage flightsPage = new FlightsPage(wd);
    
          // Open the Google Flights homepage
          homePage.navigateToFlights();
    
          // Perform flight search
          flightsPage.setLocation("Lucknow", "//*[@id='i21']/div[1]/div/div/div[1]/div/div/input");
          WebElement e1 = flightsPage.setLocation("New Delhi", "//*[@id='i21']/div[4]/div/div/div[1]/div/div/input");
    
          DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E, MMM d");
          LocalDate date1 = LocalDate.now().plusDays(2);
          String dateS1 = date1.format(formatter);
          System.out.println("Formatted Date 1: " + dateS1);
    
          LocalDate date2 = date1.plusDays(2);
          String dateS2 = date2.format(formatter);
          System.out.println("Formatted Date 2: " + dateS2);
    
          WebElement e2 = flightsPage.setDate(dateS1, e1);
          WebElement e3 = flightsPage.setDate(dateS2, e2);
    
          e3.sendKeys(Keys.RETURN);
          flightsPage.searchFlight("//span[text()='Done']");
          flightsPage.searchFlight("//span[text()='Search']");
          pause(5000);
    
        } finally {
    
          // Close the browser
          wd.quit();
        }
      }
    
      public static void pause(int ms) {
        // Pause for a moment before quitting (to check visually)
        try {
          Thread.sleep(ms);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }

    Step3. Run the Test

    You can use Eclipse, IntelliJ, VS code, or many other tools to set up and run this Page Object Model project. However, if you plan to compile and run it from the command line using javac, you’ll need to follow these steps:

    1. Download Selenium JARs:
      • Download the Selenium WebDriver JAR files from the official Selenium website.
      • Save the JAR files (e.g., selenium-java-x.x.x.jar) to a directory.
    2. Download ChromeDriver:
      • Download the ChromeDriver executable from the official ChromeDriver website.
      • Save the ChromeDriver executable to a directory.
    3. Directory Structure:
      • Make sure you have the following directory structure:
    Page Object Model Demo Project Dir Structure
    1. Compile and Run:
    • Open a terminal and navigate to your project directory.
    • Compile the Java files using the javac command:

    $ javac -cp ".:selenium-java-x.x.x.jar" FlightBookingTest.java HomePage.java FlightsPage.java

    • Replace selenium-java-x.x.x.jar with the actual name of the Selenium JAR file.
    • Run the Java class using the java command:

    $ java -cp ".:selenium-java-x.x.x.jar" FlightBookingTest

    Make sure to replace x.x.x it with the actual version number of the Selenium JAR file.

    This should compile and run your Selenium Java test from the command line without using any build tools.

    The Concept of Page Factory

    Page Factory in Selenium is a utility class that provides a simple way to initialize web elements in the Page Object Model (POM). It uses annotations like @FindBy to locate and initialize elements automatically. While using it, you don’t need to initialize the WebElement separately. It reduces a lot of your code and increases its maintainability.

    Page Factory supports different locators, such as IDs and CSS selectors. This is how you can use it to handle various scenarios. Its main purpose is to make the interaction with web elements as easy as possible. It ensures your Selenium test scripts are more concise and readable.

    Benefits of the Page Factory

    It brings several benefits which are as follows:

    • Reduced Boilerplate: Say goodbye to repetitive code for finding elements! Page Factory uses annotations @FindBy to automatically identify elements within your page object classes, no need to manually call find_element or find_elements.
    • Better Readability: By covering element locators within annotations, Page Factory makes your code more readable and self-documenting. You don’t need to hunt for locators throughout your test scripts, as they’re clearly defined within the page object class.
    • Dynamic Locator Support: Page Factory handles dynamic elements where values are constructed at runtime using placeholders ($name, {id}) within annotations. This makes your tests more adaptable, letting them work even if certain element details change.
    • Custom Annotations: Page Factory allows you to create custom annotations. Imagine creating an annotation for handling complex element identification logic, it streamlines your interactions with unique UI components.
    • Improved Page Load Handling: Page Factory offers an inbuilt init_elements method that waits for the page to load before initializing elements. This way, you can avoid run-time errors that may arise if elements aren’t ready yet.
    • Integration with Frameworks: Page Factory plays nicely with popular testing frameworks like Pytest and JUnit. Since it does so many things already, hence reduces the learning curve and improves compatibility.

    Demo Selenium Project for Page Factory

    We have modified the same project we used in the page object model test for the Page Factory as well. The test project had 3 files, now, these files are updated to use the Selenium Page Factory classes. You can compile and run the tests in the same manner as you did for the POM test project.

    1. HomePage.java

    Please note that there is no change in this file. So, you can use it as is.

    2. FlightsPage.java

    This file has changes for the page factory class. The locators have been specified using the FindBy annotations. As a result, we no longer needed to find them separately.

    import org.openqa.selenium.*;
    import java.time.Duration;
    import org.openqa.selenium.support.ui.*;
    import org.openqa.selenium.support.FindBy;
    import org.openqa.selenium.support.PageFactory;
    
    public class FlightsPage {
      private WebDriver wd;
      private WebDriverWait wt;
    
      @FindBy(xpath = "//*[@id='i21']/div[1]/div/div/div[1]/div/div/input")
      private WebElement orign;
    
      @FindBy(xpath = "//*[@id='i21']/div[4]/div/div/div[1]/div/div/input")
      private WebElement destn;
    
      @FindBy(className = "zsRT0d")
      private WebElement suggestion;
    
      public FlightsPage(WebDriver wd) {
        this.wd = wd;
        this.wt = new WebDriverWait(wd, Duration.ofSeconds(10));
        PageFactory.initElements(wd, this);
      }
    
      public void setOrign(String location) {
        orign.clear();
        orign.sendKeys(location);
        wt.until(ExpectedConditions.visibilityOf(suggestion)).click();
      }
    
      public void setDestn(String location) {
        destn.clear();
        destn.sendKeys(location);
        wt.until(ExpectedConditions.visibilityOf(suggestion)).click();
      }
    }

    3. FlightBookingTest.java

    This file has changed to adjust itself as per the new FlightsPage.java. It limited itself to set only the source and destination locations. Yet, you can enjoy checking out the application of Page Factory.

    import org.openqa.selenium.*;
    import org.openqa.selenium.chrome.*;
    
    public class FlightBookingTest {
      public static void main(String[] args) {
        // Set the path to the ChromeDriver executable
        System.setProperty("webdriver.chrome.driver", "/opt/chromedriver/chromedriver");
    
        // Configure ChromeOptions to start with a maximized window
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--start-maximized");
    
        // Create a new instance of the ChromeDriver
        WebDriver wd = new ChromeDriver(options);
    
        try {
          // Instantiate the page classes
          HomePage homePage = new HomePage(wd);
          FlightsPage flightsPage = new FlightsPage(wd);
    
          // Open the Google Flights homepage
          homePage.navigateToFlights();
    
          // Perform flight search
          flightsPage.setOrign("Lucknow");
          flightsPage.setDestn("New Delhi");
    
          pause(5000);
    
        } finally {
          // Close the browser
          wd.quit();
        }
      }
    
      public static void pause(int ms) {
        // Pause for a moment before quitting (for manual verification)
        try {
          Thread.sleep(ms);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }

    Page Object Model (POM) vs Page Factory in Selenium

    At this point, you already have enough details about both these concepts. However, let’s draw a simple comparison to lead your understanding a notch further.

    Page Object Model (POM) and Page Factory are tools for making web tests better. POM helps to organize things neatly, and Page Factory makes handling elements easier. Both work together to keep your code clean and effective, making testing simpler.

    Page Object Model (POM)

    • Purpose: POM helps organize your web automation code neatly. Each web page gets its class, making it easy to manage.
    • Structure: Every web page has a dedicated class with its elements and actions. This separation keeps your code clean and manageable.
    • Benefits: Makes your code readable, reusable, and easy to maintain. Changes to the webpage won’t mess up your test scripts.

    Page Factory

    • Purpose: Page Factory is like a helper for POM. It makes it easy to set up and use web elements in your page classes.
    • Structure: You use @FindBy annotations to tell Page Factory where to find your elements. It then takes care of setting them up for you.
    • Benefits: Keeps your code clean by handling the setup of elements. Reduces repetition and makes your page classes focused on what they do.

    Combining POM and Page Factory

    • POM and Page Factory work well together. POM helps organize your pages, while Page Factory takes care of setting up elements.
    • POM focuses on how your pages are structured, and Page Factory takes care of the nitty-gritty details of element setup.

    Summary

    • POM helps keep your automation code neat and organized by structuring pages.
    • Page Factory simplifies the process of setting up and using web elements in your page classes.
    • Together, they make your Selenium automation code readable, reusable, and easy to manage.

    More Resources to Learn Selenium at TechBeamers

    We have covered many key topics in Selenium and Java. So, keep learning and continue gaining more skills and experience. Identify the topics of your interest from the below list of trending tutorials.

    • What is Regression Testing? How to Do It? Provide Examples.
    • What is Penetration Testing? How to Do It? Provide Examples.
    • What is the Software Development Life Cycle (SDLC)?
    • What is the Software Testing Life Cycle (SDLC)?
    • How to Generate Report in Selenium Webdriver?
    • How to Generate Extent Report in Selenium?
    • How to Zoom In/Out in Selenium Webdriver Using Java?
    • Random API for Postman to Generate Random Inputs

    Happy Learning!

    You Might Also Like

    20 Demo Sites for Automation Testing

    Selenium 4 With Python Guide

    Selenium 4 Relative Locators Guide

    Selenium Version 4 Features – What’s New?

    How to Inspect Element in Safari, Android, and iPhone

    TAGGED:POM Design PatternSelenium Book a Flight
    Meenakshi Agarwal Avatar
    By Meenakshi Agarwal
    Follow:
    Hi, I'm Meenakshi Agarwal. I have a Bachelor's degree in Computer Science and a Master's degree in Computer Applications. After spending over a decade in large MNCs, I gained extensive experience in programming, coding, software development, testing, and automation. Now, I share my knowledge through tutorials, quizzes, and interview questions on Python, Java, Selenium, SQL, and C# on my blog, TechBeamers.com.
    Previous Article Selenium 4 With Python Guide Selenium 4 With Python Guide
    Next Article How to Connect Python with SQL Database? How to Connect to SQL Database in Python

    Popular Tutorials

    SQL Interview Questions List
    50 SQL Practice Questions for Good Results in Interview
    SQL Interview Nov 01, 2016
    Demo Websites You Need to Practice Selenium
    7 Sites to Practice Selenium for Free in 2024
    Selenium Tutorial Feb 08, 2016
    SQL Exercises with Sample Table and Demo Data
    SQL Exercises – Complex Queries
    SQL Interview May 10, 2020
    Java Coding Questions for Software Testers
    15 Java Coding Questions for Testers
    Selenium Tutorial Jun 17, 2016
    30 Quick Python Programming Questions On List, Tuple & Dictionary
    30 Python Programming Questions On List, Tuple, and Dictionary
    Python Basic Python Tutorials Oct 07, 2016
    //
    Our tutorials are written by real people who’ve put in the time to research and test thoroughly. Whether you’re a beginner or a pro, our tutorials will guide you through everything you need to learn a programming language.

    Top Coding Tips

    • PYTHON TIPS
    • PANDAS TIPSNew
    • DATA ANALYSIS TIPS
    • SELENIUM TIPS
    • C CODING TIPS
    • GDB DEBUG TIPS
    • SQL TIPS & TRICKS

    Top Tutorials

    • PYTHON TUTORIAL FOR BEGINNERS
    • SELENIUM WEBDRIVER TUTORIAL
    • SELENIUM PYTHON TUTORIAL
    • SELENIUM DEMO WEBSITESHot
    • TESTNG TUTORIALS FOR BEGINNERS
    • PYTHON MULTITHREADING TUTORIAL
    • JAVA MULTITHREADING TUTORIAL

    Sign Up for Our Newsletter

    Subscribe to our newsletter to get our newest articles instantly!

    Loading
    TechBeamersTechBeamers
    Follow US
    © 2024 TechBeamers. All Rights Reserved.
    • About
    • Contact
    • Disclaimer
    • Privacy Policy
    • Terms of Use
    TechBeamers Newsletter - Subscribe for Latest Updates
    Join Us!

    Subscribe to our newsletter and never miss the latest tech tutorials, quizzes, and tips.

    Loading
    Zero spam, Unsubscribe at any time.
    x