Page Object Model (POM)


Page Object Model is an object design pattern implementations of Page factory in Selenium, where web pages are represented as java classes, and the various elements on the page are defined as a method on the PO classes. All reusable methods are stored in libraries

  • Page Object Model is one of the implementations of java design pattern call Page Factory.
  • In selenium, we create Page Object Modal class to develop and store the re-usable methods. These methods are nothing but Page Objects
  • Page Objects are nothing but web elements present on the web page like Buttons, links, tabs, textbars.

  • We have to create page object class for every page present in the application, if the application is a single page application (spa) we have to create page object classes for each tab.
  • Page Object Model class contains 3 components.
    • Web element present on webpage and declared as private.
    • Page Factory Constructor, it will be helpful to initialize the web elements present in the class
    • Methods, which are used to access the webelement declared in the page object class.

In this tutorial, we are going to create a simple framework for google page with Selenium Webdriver.

Reading QR Code from the website using Webdriver

Page Object Class

Page Object class contains all the page object(web elements) for a particular page. For every page present in the application, we have to write the Page Object class.

Page Object class name should end with PO so that it will be easy for the user to identify the class.

Steps to Create :

  • Create a Java project in eclipse and add all selenium webdriver jars
  • Create a package called po some people also prefer objectrepository without space
  • Create a Class called GooglePO, which is Page Object Class. This class will store all the web elements present in the Google Page
  • Once we have created the PO class, we have to add webelements to the class.
Different ways to create Page Object (Web element in PO class):
1. @FindBy :

@FindBy helps selenium testers to find the element on the webpage, to declare elements in PO class we can use @FindBy with following syntax.


												@FindBy(locator = "locator value")
												public WebElement elementName;
												
												// method 1 using FindBy
												@FindBy(name="q")
												public WebElement searchBar;
												public GooglePO(WebDriver driver) {
													PageFactory.initElements(driver, this);
												}
												
												

The disadvantage with this way is, we cannot use varying value at the place of locator value, it always should be constant String.

Xpath in Selenium


2. Static Method way

We can create methods for the web elements using java static methods which return web element, static method way provides us the flexibility to use varying locators, this method accepts driver as parameter.


												public static WebElement methodName(WebDriver driver){
													return driver.findElement(By.locator(locator value));
												}
												
												
												// method 2 using static method
												public static WebElement searchButton(WebDriver driver){
													return driver.findElement(By.xpath("//input[contains(@value,'Search')]"));
												}
												

The disadvantage this way is when the user runs the test cases in parallel, there is a chance to fail because we are using static methods. Only one copy of static methods exist per class.


3. Non-Static method way :

To help multi-threading/ parallel execution we have to use non-static methods to create page objects, We have to write constructor in these classes and constructor should accept driver as parameter. Using this driver we have to assign a global driver present in the PO class


												// method 2 using non static method
												public WebElement methodName(){
													return driver.findElement(By.locator(locator value));
												}
												
												// method 2 using non static method
												public WebElement logoOnSearchResult(){
													return driver.findElement(By.xpath("//h1/a[@id='logo']"));
												}
												

Complete PO class looks like below program

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

												public class GooglePO {
													private WebDriver driver;
													
													// method 1 using FindBy
													@FindBy(name="q")
													public WebElement searchBar;
													public GooglePO(WebDriver driver) {
														// this is for non static method way
														this.driver = driver;
														PageFactory.initElements(driver, this);
													}
													
													// method 2 using static method
													public static WebElement searchButton(WebDriver driver){
														return driver.findElement(By.xpath("//input[contains(@value,'Search')]"));
													}
													
													// method 2 using non static method
													public WebElement logoOnSearchResult(){
														return driver.findElement(By.xpath("//h1/a[@id='logo']"));
													}
												}
												


Test class in Page Object Modal :
1. Create packed called test

2. Create a Java Class called GoogleSeachTest

3. Open Firefox browser by setting the geckodriver.exe path to the system variable


												// set  gecko driver.exe file path
												System.setProperty("webdriver.gecko.driver", "C:/~/geckodriver.exe");
												// create object for browser
												WebDriver driver = new FirefoxDriver();
												


4. Navigate to google.com


												driver.get("https://google.com");
												


5. Create an object for GooglePO class, in which we have stored our page object (web elements), pass driver as a parameter


												GooglePO gp = new GooglePO(driver);
												


6. (method 1) With the help of GooglePO class object access the element created by the @FindBy


												gp.searchBar.sendKeys("POM test");
												


7. (method 2) We can access static member using the Class name, access the searchButton using GooglePO class name.


												GooglePO.searchButton(driver).click();
												


8. (method 3) Acces non-static method using GooglePO class object


												gp.logoOnSearchResult().click();
												

The complete program of Test class looks like below.

												import org.openqa.selenium.WebDriver;
												import org.openqa.selenium.firefox.FirefoxDriver;
												import po.GooglePO;

												public class GoogleSeachTest {
													public static void main(String[] args) {
														// set  gecko driver.exe file path
														System.setProperty("webdriver.gecko.driver", "C:/~/geckodriver.exe");
														// create object for browser
														WebDriver driver = new FirefoxDriver();
														// navigate to google
														driver.get("https://google.com");
														
														// create object for GooglePO class
														GooglePO gp = new GooglePO(driver);
														// access searchBar page object  from GooglPO PO class
														gp.searchBar.sendKeys("POM test");
														
														// accessing static method
														GooglePO.searchButton(driver).click();
														
														// access non static method using object of GooglePO class
														gp.logoOnSearchResult().click();
													}
												}
												

Handling Custom Dropdowns in selenium


Project structure
pom-selenium-webdriver

Capture screenshots for framework in selenium

Page object with Variable

We can also use a variable for writing the page object (web element) in selenium, but the only issue is you cannot customize much incase of variables.

Below example only to showcase that we can also use a variable for page object but do not use it in the framework.


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

										public class POWithVariable {
											WebDriver driver;
											public POWithVariable(WebDriver driver) {
												this.driver = driver;
											}
											// variable as page objects
											public WebElement searchBar =  driver.findElement(By.name("q"));
											public WebElement searchButton =  driver.findElement(By.xpath("//input[contains(@value,'Search')]"));
											public WebElement logo =  driver.findElement(By.xpath("//h1/a[@id='logo']"));
										}
										

this.driver = driver;

We have used this.driver = driver; code couple of times in this page, but what does that mean.

this keyword point the object of the class created by the constructor, as this global driver Webdriver driver; is not initialized.

We want to initialize 'global level driver' value with the help of the user, so we accept driver value in the constructor with a parameter of driver, and we set 'constructor level driver' value to the 'global level driver', so that we can use the 'global level driver' in all the methods or where ever required

In the next tutorial, we will learn fully featured Page Object Model Framework

Hybrid Inheritance in Java and Selenium

Comment / Suggestion Section
Point our Mistakes and Post Your Suggestions
  • yogesha
    can explain about robot framework...for freshers we know all the concepts ,but we don't know how to implement all this things for the real time projects so can you please upload the videos about robot framework by taking example as any real time application..
    Reply
  • kauser
    can you explain other frameworks...like bdd 
    Reply
    • karthiq [admin]
      I have created a tutorial for BDD but which not upto mark, I am working on it.
      
      Soon I will make it better.
      Reply