Selenium WebDriver Page Factory Model Examples

Page Factory Model is an inbuilt Page Object Model concept for Selenium WebDriver but Page Object Model is much optimized. In this Selenium WebDriver Page Factory Model Examples post you’ll learn the concept of separation of Page Object Repository and Test Methods i.e. Test Cases Methods. Moreover, with the help of PageFactory class, we use annotations @FindBy to find Web Element and you can use initElements method to initialize web elements.@FindBy can accept below attributes to identify the web Elements.

  • ID
  • NAME
  • CLASS NAME
  • PARTIAL LINK TEXT
  • TAGNAME
  • CSS
  • XPATH

We’ll discuss above points with brief examples, let’s look into below codes to understand How to Implement Selenium WebDriver Page Factory Model in selenium WebDriver Frameworks.The Page Factory Class help us to write clean Java Code and Reusable Functions in Test Methods. By this Page Factory Model it is easy to code, Easy to understand the code or Test Cases and easy to understand the flow of the Test Cases execution.Selenium WebDriver Page Factory Model ExamplesFollow below project folder structure to create Page Factory Framework in Selenium Projects. I’m creating three packages under project.

  • Com.selenium.portal.utility
  • Com.selenium.portal.pages
  • Com.selenium.portal.Tests
ALSO READ  How to Get HTML Source of WebElement in Selenium WebDriver using Python

Step 1: Create JAVA project in Eclipse.
Step 2: Configure Selenium + Require JAR files using Configure Build Path.
Step 3: Add TestNG Library from Configure Build Path screen.
Step 4: Create Above three packages under src folder.

Now let’s see each Packages Class Files, Create WebdriverInstance.java class under Com.selenium.portal.utility package, from this class we’re using driver instance and Writing results to log using @AfterMethod method and taking screenshot for failed tests.

WebdriverInstance.java

package com.selenium.portal.utility;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Properties;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.Alert;
import org.openqa.selenium.Keys;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.ITestResult;
import org.testng.Reporter;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeMethod;
import com.aventstack.extentreports.ExtentReports;
import com.aventstack.extentreports.ExtentTest;
import com.aventstack.extentreports.Status;
import com.aventstack.extentreports.reporter.ExtentHtmlReporter;
import com.aventstack.extentreports.reporter.configuration.ChartLocation;
public class WebdriverInstance {
public static WebDriver driver;
public static ExtentReports extent;
public static Properties property;
public static ExtentHtmlReporter htmlReports;
public static ExtentTest test;
String fileName = System.getProperty("user.dir")+"/test-output/TestResults.html";
public void openBrowser() throws IOException {
property = new Properties();
FileInputStream orFile = new FileInputStream("E:\Eclipse_Oxygen\selenium\OR.properties");
property.load(orFile);
System.setProperty("webdriver.gecko.driver",property.getProperty("geckodriver"));
driver = new FirefoxDriver();
//ExtentReports details
htmlReports= new ExtentHtmlReporter(fileName);
extent = new ExtentReports();
extent.attachReporter(htmlReports);
htmlReports.config().setReportName("HYPERCITY REGRESSION TESTING");
htmlReports.config().setTestViewChartLocation(ChartLocation.TOP);
//Using extent set system information
extent.setSystemInfo("OS", "Windows 7");
extent.setSystemInfo("Browser", "Firefox 56V");
extent.setSystemInfo("Environment","QA");
extent.setSystemInfo("Server", "10.0.7.179");
}
//A Method provides information about, and access to, a single method on a class or interface
@BeforeMethod
public void afterMethod(Method results){
test=extent.createTest(results.getName());
test.log(Status.INFO, results.getName() + " Test is started");
}
@AfterTest
public void afterTest() {
extent.flush();
}
public String validatePageTitle() {
return  driver.getTitle();
}
@AfterMethod
public void verifyTestResults(ITestResult results) {
if(results.getStatus()==ITestResult.FAILURE) {
test.log(Status.FAIL, results.getName() + " Test case is Failed because of below reason");
test.log(Status.FAIL, results.getThrowable());
}else if(results.getStatus()==ITestResult.SKIP) {
test.log(Status.SKIP, results.getName() + " Test Case execution is skipped because");
test.log(Status.SKIP, results.getThrowable());
}else {
test.pass(results.getName() + " Test Case is PASS");
}
}
public void takeScreenShot() throws IOException {
File screenShot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
File screenShotName = new File(System.getProperty("user.dir")+"/Screenshots/"+driver.getTitle()+"_"+".png");
FileUtils.copyFile(screenShot, screenShotName);
}
}

Now Create pages under com.selenium.portal.pages package, which will store all the web elements attributes means it’ll work as Object Repository class, Like Below.

ALSO READ  TypeError can't access dead object geckodriver

LoginPage.java

package com.selenium.portal.pages;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import com.selenium.portal.utility.WebdriverInstance;

public class Login extends WebdriverInstance {  

 //Using PageFactory model
 @FindBy(id="userNameId")
 static WebElement userName;

 @FindBy(id="passwordId")
 static WebElement password;

 @FindBy(id="submitID")
 static WebElement loginSubmit; 

 public Login() {
  PageFactory.initElements(driver, this);
 }

 public String validateLoginTitle() {   
  return  driver.getTitle();
 }

 public  void setUserName(String uName) {
  userName.sendKeys(uName);

 }
 public void setPassword(String passsword) {
  password.sendKeys(passsword);
 }

 public void clickOnLogin() {
  loginSubmit.submit();
 }

}

Now we need to write @Test under Com.selenium.portal.Tests package, Create a class and Name as LoginTest.Java, here we’re writing all possible test cases based on Login.java class object repository class as below.

ALSO READ  Selenium Introduction

LoginTest.java

package com.selenium.portal.Tests;
import java.io.IOException;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.aventstack.extentreports.Status;
import com.selenium.portal.pages.Login;
import com.selenium.portal.utility.WebdriverInstance;

public class LoginTest extends WebdriverInstance {

Login login;

@BeforeClass
public void setUp() throws IOException {
 openBrowser();
 takeScreenShot();
 login = new Login();

}

@Test(priority=1)
public void openAUTUrl() throws IOException {
 System.out.println("First Test");
 driver.get(property.getProperty("baseUrl"));
 takeScreenShot();

}

@Test(priority=2)
public void verifyPageTitleTest() {
 System.out.println("Second Test");
 test.log(Status.INFO, "Verifying the Page Title");
 String title = login.validateLoginTitle();
 Assert.assertEquals(title, property.getProperty("loginPage"));
 test.log(Status.PASS, "Login page title is matching with Expected Title");

}

@Test(priority=3)
public void loginTest() throws InterruptedException, IOException {
 System.out.println("Third Test");

 test.log(Status.INFO, "Entering Username and Password");
 System.out.println(property.getProperty("userName"));
 System.out.println(property.getProperty("passWord"));

 login.setUserName(property.getProperty("userName"));
 login.setPassword(property.getProperty("passWord"));
 Thread.sleep(5500);
 takeScreenShot();
 login.clickOnLogin();

}

@Test(priority=4)
public void userAccountTest() throws IOException {
 System.out.println("Fourth Test");

 test.log(Status.INFO, "Verify User Account screen is open");
 try {
  Thread.sleep(5500);
 } catch (InterruptedException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }

 String accountTitle = login.validatePageTitle();
 System.out.println(accountTitle);
 Assert.assertEquals(accountTitle, property.get("selectProgramTitle"));
 takeScreenShot();
 test.log(Status.PASS, "Select Program title is matching with Expected Title");
}

}


We’ll run the Tests with the help of testng.xml file and testng.xml file is

Now Right click and run your testng.xml file and it’ll start executing your all @Test method one by one.

Thank you for reading, if you like my post, please share with your friends and provide your valuable comments and don’t forget to implement this model in your project.

Rajesh K