Page Object Model | POM
Creating Selenium test cases can result in an unmaintainable project. One of the reasons is that too many duplicated code is used. Duplicated code could be caused by duplicated functionality and this will result in duplicated usage of locators. The disadvantage of the duplicated code is that the project is less maintainable. If some locator will change, you have to walk through the whole test code to adjust locators where necessary. By using the page object model (POM) we can make non-brittle test code and reduce or eliminate duplicate test code. Besides that, it improves readability and allows us to create interactive documentation. Last but not least, we can create tests with fewer keystrokes. An implementation of the page object model can be achieved by separating the abstraction of the test object and the test scripts.
To learn more about Page Object Model and POM in Selenium please refer to our latest article Page Object Model Design Pattern
Note: We will follow the same example which we have used in First Test Case. Let's assume it our base test case and implement the Page Object Model (POM) in it.
How to do it...
-
Create a 'New Package' file and name it as 'pageObjects', by right click on the Project and select New > Package. We will be creating different packages for Page Objects, Utilities, Test Data, Test Cases and Modular actions. It is always recommended to use this structure, as it is easy to understand, easy to use and easy to maintain.
-
Create a 'New Class' file and refer the name to the actual page from the test object, by right click on the above-created Package and select New > Class. In our case, it is Home Page and LogIn Page.
-
Now create a Static Method for each Element (Object) in the Home Page. Each method will have an Argument (driver) and a Return value (element).
package pageObjects;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
public class Home_Page {
private static WebElement element = null;
public static WebElement lnk_MyAccount(WebDriver driver){
element = driver.findElement(By.id("account"));
return element;
}
public static WebElement lnk_LogOut(WebDriver driver){
element = driver.findElement(By.id("account_logout"));
return element;
}
}
Driver is being passed as an Argument so that Selenium is able to locate the element on the browser (driver).
Element is returned, so that an Action can be performed on it.
Method is declared as Public Static, so that it can be called in any other method without instantiate the class.
Follow the same rule for creating LogIn Page class.
package pageObjects;
import org.openqa.selenium.*;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
public class LogIn_Page {
private static WebElement element = null;
public static WebElement txtbx_UserName(WebDriver driver){
element = driver.findElement(By.id("log"));
return element;
}
public static WebElement txtbx_Password(WebDriver driver){
element = driver.findElement(By.id("pwd"));
return element;
}
public static WebElement btn_LogIn(WebDriver driver){
element = driver.findElement(By.id("login"));
return element;
}
}
- Create a 'New Class' and name it as POM_TC by right click on the 'automationFramework' Package and select New > Class. We will be creating all our test cases under this package.
Now convert your old First Test Case into the new Page Object Model test case.
package automationFramework;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
// Import package pageObject.*
import pageObjects.Home_Page;
import pageObjects.LogIn_Page;
public class PageObjectModel {
private static WebDriver driver = null;
public static void main(String[] args) {
driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("https://www.store.demoqa.com");
// Use page Object library now
Home_Page.lnk_MyAccount(driver).click();
LogIn_Page.txtbx_UserName(driver).sendKeys("testuser_1");
LogIn_Page.txtbx_Password(driver).sendKeys("Test@123");
LogIn_Page.btn_LogIn(driver).click();
System.out.println(" Login Successfully, now it is the time to Log Off buddy.")
Home_Page.lnk_LogOut(driver).click();
driver.quit();
}
}
You will notice that once you type Home_Page in your test script and the moment you press dot, all the methods in the Home Page will display. We can expose methods in order to reduce duplicated code. We are able to call these methods multiple times. This will ensure a better maintainable test code, because we only have to make adjustments and improvements in one particular place.
Your Project explorer window will look like this now.
It is advisable to maintain Page Objects Repository in the same way QTP maintains its Repository. Please visit Selenium Object Repository section to learn more.