Back to Top

Page Object Model (POM) in Selenium

Updated 16 July 2021

Selenium doesn’t inherently comes with any feature which provide any object management where we can manage the object information for a page and keep this object information outside the test script. Yes, it’s true, we can write the entire script for a page without a page object model and this could run through. This may state less pain to maintain the script only if we have limited test-cases(say 5-10). Considering if we have thousands of test-cases, is it easy to maintain the test script? We can’t change the whole test-script once the AUT goes certain changes or some modifications (which generally happens down the road).

So if the object info of a page change (the probability of which is higher) as the AUT undergoes changes with different release cycle, the impact of that change on the automation suite level is very high since the object info in the script is hard coded.

Why POM?

POM has nowadays become popular test automation design pattern around the testing industry. POM facilitates as to concentrate on testing the AUT rather than fixing the automation suite (the changed objects) to perform the test. In POM the Object information is managed outside the test script, thus making easy to understand the test script.

Advantages of POM

  1. It makes ease in maintaining the code (flow in the UI is separated from verification)
  2. Makes code readable (Methods get more realistic names)
  3. Makes the code reusable (object repository is independent of test cases)
  4. The Code becomes less and optimised

Implementation of POM

Let us consider a simple test scenario where we have an app with a login page, an account page and, say, home page.

The scenario be like

Start your headless eCommerce
now.
Find out More
  • We go to the app url
  • Validate the app page is correct (home page)
  • We go to the login page and fill the form with a valid id and password
  • We validate if the account page opens

Now here we are dealing we three pages the home page, the login and the account page. Accordingly we create 3 POM classes, be like :

  • HomePage.java
  • LoginPage.java
  • MyAccountPage.java

Also we create a test class with the test script and names it as

  • TestLogin.java

HomePage.java

package pageModel;

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

public class HomePage	{
	WebDriver driver;
	By homeHeading = By.xpath("//table//tr[3][@class='heading3']");
	By loginButton = By.id("login");
	public	HomePage(WebDriver driver)	{
		this.driver = driver;
	}
	//get the heading (the main heading which is present at the home page)
	public String getHomeHeading()	{
		String heading = driver.findElement(homeHeading).getText();
		return	heading;
	}
	public HomePage clickLoginButton()	{
		driver.findElement(loginButton).click();
		return	this;
	}
}

LoginPage.java

package pageModel;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class LoginPage	{
	WebDriver driver;
	By username = By.id("email");
	By password = By.name("email");
	By submitButton = By.cssSelector("input[type='submit']");
	public	LoginPage(WebDriver driver)	{
		this.driver = driver;
	}
	public LoginPage usernameAs(String email)	{
		driver.findElement(username).sendKeys(email);
		return	this;
	}
	public LoginPage passwordAs(String pass)	{
		driver.findElement(password).sendKeys(pass);
		return	this;
	}
	public void	submit(){
		driver.findElement(submitButton).click();
	}
}

MyAccountPage.java

package pageModel;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class MyAccountPage	{
	WebDriver driver;
	// Declaring the xpath for the heading in By class
	By pageHeading = By.xpath("//table//tr[3][@class='heading3']");
	
	public	MyAccountPage(WebDriver driver)	{
		this.driver = driver;
	}
	//get the heading (username for which the account belongs to)
	public String getHeading()	{
		String heading = driver.findElement(pageHeading).getText();
		return	heading;
	}
}

TestLogin.java

package test;
import org.junit.Assert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

import pageModel.*;

public class TestLogin {
	WebDriver driver;	
	@BeforeTest
	public void setUp() throws Exception {
	// setting the driver executable for chrome browser
		String chrome_path = System.getProperty("user.dir")+"/chromedriver";
		driver = new ChromeDriver();				// created a new instance for chrome driver
		driver.manage().window().maximize(); 
	}
	
	@AfterTest
	public void tearDown() throws Exception {
	    driver.quit();
	}

	@Test(priority=1)
	public void test() throws InterruptedException{
		driver.get("http://192.168.1.164:8080/home.html");
//		validate if we are at the home page
		String homeHeading = new HomePage(driver).getHomeHeading() ;
		Assert.assertEquals(homeHeading, "This is HOMEPAGE", "not at the home page");
//		redirect to the login page
		new HomePage(driver).clickLoginButton();
//		fill the login form
		new LoginPage(driver)
		.usernameAs("[email protected]")
		.passwordAs("secret")
		.submit();
//		check if redirected to account page with user name [email protected]
		String accountHeading = new HomePage(driver).getHomeHeading() ;
		Assert.assertEquals(accountHeading, "Welcome [email protected] ", "not at the account page");
	}
}

Now, if the AUT undergoes any change at the login page or at any page we just need to change the page object. Thus we don’t need to change our  test script again and again (even for the new release or built). The project structure will look like :

image

. . .

Leave a Comment

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


1 comments

  • Kc Elma
  • Back to Top

    Message Sent!

    If you have more details or questions, you can reply to the received confirmation email.

    Back to Home