In this post, we’ll present a step-by-step tutorial on the page object model in Selenium, a standard design pattern for solving real-time problems.
In the world of test automation, Selenium RC and WebDriver were the de facto web UI automation tools for testers. These tools are open source and available for free use. Many QA engineers aspire to create their private keyword and data-driven test suites using these tools.
Introduction to Page Object Model (POM)
Nowadays, the page object model is a new test automation buzzword. It was brought to address the multiple bottlenecks that exist in the old tools. Let’s now move to know more about the page object model.
Why Page Object Model?
There have been several problems with the traditional automation methods (as referred to above).
1- The most common is script maintenance which gets complex as the test suite grows.
2- Next, when some locator changes, we check the whole source code to adjust locators.
3- Another problem is the duplicate code due to the lack of reusability in the old code.
4- The latter also leads to the duplicity of locators making the test code inefficient.
5- Finally, the unnecessary code increases the maintenance for the entire project.
As said in the beginning, the Page Object Model is a design pattern that addresses all the above issues. It allows easy test case maintenance and reduces duplicate code. It is becoming the most widely used UI automation concept across the Selenium community.
Another aspect of using the Page Object Model is that the big IT companies ask questions about it during testing job interviews. So we suggest to all budding test engineers that they first read this tutorial. And then refer to one of the most popular posts providing 100+ Selenium Interview Questions.
If you plan to prepare for a Selenium online skill test, first try the Selenium WebDriver Quiz on our site to gain confidence. Both these posts receive interest from hundreds of visitors daily. Let’s begin understanding our main topic, the page object model with a full-blown example.
What is the Page Object Model (POM)?
1- Page Object Model is a design pattern to define container classes for web elements that behave as object repositories.
2- In this model, each page has its private page object class to access UI locators.
3- The Page class maps all elements of the corresponding web page as its private members. Also, it defines public methods to manage operations on these objects.
4- To increase readability – it allows the method name to be set as per the task they are performing. For example, we can use a method name like waitForLoginSuccess() which waits until it gets a success message for the login operation.
Advantages
The page object model brings several advantages over the traditional automation approach.
1- You can segregate the UI operations from functional flows. This makes the code clean and easy to manage.
2- It lets the test cases be written independently of the object repository. So the same object repository can be re-used for a different purpose. For example, you can use the POM-based repository for functional testing with TestNG/JUnit and acceptance testing with JBehave/Cucumber.
3- Here, we have reusable page methods in the POM classes so that you can focus on code optimization.
4- You can use more sensible method names which can be easily mapped to the UI actions. For example – if you click the login button and move to the dashboard page. Then you can give the method name as ‘gotoDashboard()’.
How to Implement the Page Object Model?
POM Sample Application
We’ll give you a live example of a page object model class to automate the test cases. Following is the summary of the use case.
1- For the demo, we’ll use a dummy site that is openly available for selenium testing. You can select a Selenium demo site from our blog.
2- The above URL has a landing home page that lists the links for chapters ranging from 1 to 8.
3- Clicking the chapter links, you can navigate to other pages.
4- In this demo, we’ll automate a basic function workflow.
7- We’ll use the homepage and chapter 1-2 links to create the page objects and the test case class files.
Steps to Create the POM Application
1- In the first step, we’ll create Java files for the corresponding pages to hold element locators and their methods.
– HomePage.java
– ChapterFirstPage.java
– ChapterSecondPage.java
2- Secondly, we’ll define a base test case class to define our test case scenario.
– TestBase.java
3- Finally, we’ll prepare a test case class to implement the basic workflow. This class will import the base test class and extend its functionality.
– MyTest.java
Next are the coding snippets you will use to create a working page object model application.
STEP-(1)
package com.techbeamers.page; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; public class HomePage { private WebDriver driver; @FindBy(linkText = "Chapter1") WebElement chapter1; @FindBy(linkText = "Chapter2") WebElement chapter2; @FindBy(linkText = "Chapter3") WebElement chapter3; public HomePage(WebDriver driver) { this.driver = driver; } // Method-1. public ChapterFirstPage clickChapterFirst() { chapter1.click(); return PageFactory.initElements(driver, ChapterFirstPage.class); } // Method-2. public ChapterSecondPage clickChapterSecond() { chapter2.click(); return PageFactory.initElements(driver, ChapterSecondPage.class); } // Method-3. public void clickChapterThird() { chapter3.click(); } }
STEP-(2)
package com.techbeamers.page; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.ui.Select; public class ChapterFirstPage { private WebDriver driver; @FindBy(id = "secondajaxbutton") WebElement secondajax; @FindBy(xpath = "//select[@id='selecttype']") WebElement dropdown; @FindBy(id = "verifybutton") WebElement verifybutton; public ChapterFirstPage(WebDriver driver) { this.driver = driver; } // Method-1. public ChapterFirstPage clickSecondAjaxButton() { secondajax.click(); return PageFactory.initElements(driver, ChapterFirstPage.class); } // Method-2. public ChapterFirstPage clickSecondAjaxButton1(String data1) { System.out.println(data1); return PageFactory.initElements(driver, ChapterFirstPage.class); } // Method-3. public ChapterFirstPage selectDropDown(String value) { new Select(dropdown).selectByVisibleText(value); return PageFactory.initElements(driver, ChapterFirstPage.class); } // Method-4. public ChapterFirstPage verifyButton() { verifybutton.click(); return PageFactory.initElements(driver, ChapterFirstPage.class); } }
STEP-(3)
package com.techbeamers.page; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; public class ChapterSecondPage { private WebDriver driver; @FindBy(xpath = "//input[@name='but2']") WebElement but2; @FindBy(xpath = "//input[@id='random']") WebElement random; @FindBy(linkText = "Index") WebElement index; public ChapterSecondPage(WebDriver driver) { this.driver = driver; } // Method-1. public ChapterSecondPage clickRandom() { random.click(); return PageFactory.initElements(driver, ChapterSecondPage.class); } // Method-2. public ChapterSecondPage clickbut2() { but2.click(); return PageFactory.initElements(driver, ChapterSecondPage.class); } // Method-3. public HomePage clickIndex() { index.click(); return PageFactory.initElements(driver, HomePage.class); } // Method-4. public String getTest() { return index.getText(); } }
Using the above coding snippets, you can easily understand that element locators are declared with @FindBy annotation. Corresponding methods are also defined to separate them from each other.
The PageFactory class is used to create a run-time object of page classes like:
PageFactory.initElements(driver, HomePage.class);
Another important point is that whenever any page object method results in a new page navigation, it should return the object of the new page class. For example, when we click the <Index> link available on the <Chapter2> page, the corresponding method i.e. <clickIndex()> should return the <HomePage> object.
PageFactory.initElements(driver, HomePage.class);
Similarly in another example, if you click on <clickbut2()>, you get the same page object in return.
PageFactory.initElements(driver, ChapterSecondPage.class);
STEP-(4)
After creating the desired page object files, define the base class of the test scripts. Here, you can place the common functions related to the test cases. We’ve named this file as <TestBase.java>.
package com.techbeamers.util; import java.util.concurrent.TimeUnit; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.annotations.AfterSuite; import org.testng.annotations.BeforeSuite; import com.techbeamers.page.ChapterFirstPage; import com.techbeamers.page.ChapterSecondPage; import com.techbeamers.page.HomePage; public class TestBase { protected WebDriver driver; protected String baseUrl; protected HomePage homePage; protected ChapterSecondPage chapterSecond; protected ChapterFirstPage chapterFirstPage; // Method-1. @BeforeSuite public void setUp() { baseUrl = "http://book.theautomatedtester.co.uk/"; driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS); } // Method-2. @AfterSuite public void tearDown() throws Exception { driver.quit(); } }
STEP-(5)
In the last step, we’ll learn to prepare the test script by importing the TestBase class created in the previous step. Next, you’ll have to call the corresponding methods of the page objects as needed to automate the basic test case workflow. The test script’s code is chipped in below so that you can save it as the <MyTest.java> file.
package com.techbeamers.scripts; import org.openqa.selenium.support.PageFactory; import org.testng.Assert; import org.testng.annotations.Test; import com.techbeamers.page.HomePage; import com.techbeamers.util.TestBase; public class MyTest extends TestBase { // Test-0. @Test public void testPageObject() throws Exception { homePage = PageFactory.initElements(driver, HomePage.class); driver.get(baseUrl); chapterSecond = homePage.clickChapterSecond(); chapterSecond.clickbut2(); chapterSecond.clickRandom(); String data = chapterSecond.getTest(); homePage = chapterSecond.clickIndex(); chapterFirstPage = homePage.clickChapterFirst(); chapterFirstPage.clickSecondAjaxButton(); chapterFirstPage.clickSecondAjaxButton1(data); chapterFirstPage.selectDropDown("Selenium Core"); chapterFirstPage.verifyButton(); } }
Before You Leave
Hello, dear readers, we hope the above explanation of the Page Object Model has given you a fair idea about the topic. And now you should be able to use it in your working environments.
You must know that this is not an end to the knowledge and application of Selenium technology. There is much more to read and understand for each one of us. So, we’ll keep coming up with new things and concepts in the future.
Lastly, our site needs your support to remain free. Share this post on social media (Facebook/Twitter) if you gained some knowledge from this tutorial.
Enjoy testing,
TechBeamers.