
Extent Report in Page Object Modal
Page Object Model with Page Factory in Selenium and Generating Extent report.

Creating a Page Object Model with Page Factory in Selenium WebDriver:
Project Structure:

Step 1: Creating TestBase class. Here we create an object of WebDriver, maximize browser, implementing waits, launching URL and etc.,
In the below example program, I have taken chrome browser and set the System Property to launch chrome browser.
TestBase.java (BASE CLASS)
package tests;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Test;
import com.aventstack.extentreports.ExtentReports;
import com.aventstack.extentreports.ExtentTest;
import com.aventstack.extentreports.reporter.ExtentSparkReporter;
import com.aventstack.extentreports.reporter.configuration.Theme;
public class TestBase {
public static WebDriver driver = null;
public static ExtentSparkReporter spark = null;
public static ExtentReports extent = null;
public static ExtentTest logger = null;
@BeforeSuite
public void initialize() throws IOException{
extent = new ExtentReports();
spark = new ExtentSparkReporter(System.getProperty("user.dir") + "/test-output/RKExtentReport.html");
extent.attachReporter(spark);
extent.setSystemInfo("Host Name", "Testing Buddy");
extent.setSystemInfo("Environment", "Production");
extent.setSystemInfo("User Name", "Rahulkundu");
spark.config().setDocumentTitle("Title of the Report Comes here ");
// Name of the report
spark.config().setReportName("Name of the Report Comes here ");
// Dark Theme
spark.config().setTheme(Theme.STANDARD);
/*
String dateName = new SimpleDateFormat("yyyyMMddhhmmss").format(new Date());
TakesScreenshot ts = (TakesScreenshot) driver;
File source = ts.getScreenshotAs(OutputType.FILE);
// after execution, you could see a folder "FailedTestsScreenshots" under src folder
String destination = System.getProperty("user.dir") + "/Screenshots/" + screenshotName + dateName + ".png";
File finalDestination = new File(destination);
FileUtils.copyFile(source, finalDestination);*/
System.setProperty("webdriver.chrome.driver", System.getProperty("user.dir")+"\\src\\test\\java\\drivers\\chromedriver.exe");
ChromeOptions coptions = new ChromeOptions();
coptions.addArguments("--disable-notifications");
driver = new ChromeDriver(coptions);
//To maximize browser
driver.manage().window().maximize();
//Implicit wait
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
//To open facebook
driver.get("https://www.facebook.com/login");
}
@AfterSuite
//Test cleanup
public void TeardownTest()
{
TestBase.extent.flush();
TestBase.driver.quit();
}
}
Step 2: Creating classes for each page (Eg., Facebook Login Page, Facebook Inbox Page) to hold element locators and their methods. Usually, we create page objects for all available pages in the AUT. For each page, we create a separate class with a constructor. Identify all the locators and keep them in one class. It allows us to reuse the locators in multiple methods. It allows us to do easy maintenance, if there is any change in the UI, we can simply change on one Page.
Here, I create java files (FacebookLoginPage.java and FacebookInboxPage.java) for the corresponding pages (Facebook Login Page, and Facebook Inbox Page) to hold element locators and their methods.
FBHomePage.java (Webpage 1)
package pages;
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.How;
public class FBHomePage {
WebDriver driver;
public FBHomePage(WebDriver driver){
this.driver=driver;
}
//Using FindBy for locating elements
@FindBy(how=How.CLASS_NAME, using="x3ajldb") WebElement profileDropdown;
@FindBy(how=How.XPATH, using="//span[contains(.,'Log Out')]") WebElement logoutLink;
@FindBy(how=How.XPATH, using="//a[@aria-label='Rahul Kundu'][contains(.,'Rahul Kundu')]") WebElement loggedInUserNameText;
//Defining all the user actions (Methods) that can be performed in the Facebook home page
// This method to click on Profile Dropdown
public void clickOnProfileDropdown(){
//WebElement profileDropdown = driver.findElement(By.className("x3ajldb"));
profileDropdown.click();
}
//This method to click on Logout link
public void clickOnLogoutLink(){
logoutLink.click();
}
//This method to verify LoggedIn Username Text
public String verifyLoggedInUserNameText(){
String userName = loggedInUserNameText.getText();
return userName;
}
}
FBLoginPage.java (Webpage 2)
package pages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
public class FBLoginPage {
WebDriver driver;
public FBLoginPage(WebDriver driver){
this.driver=driver;
}
//Using FindBy for locating elements
@FindBy(how=How.XPATH, using="//input[contains(@name,'email')]") WebElement emailTextBox;
@FindBy(how=How.XPATH, using="//input[@type='password']") WebElement passwordTextBox;
@FindBy(how=How.XPATH, using="//button[@name='login']") WebElement signinButton;
// Defining all the user actions (Methods) that can be performed in the Facebook home page
// This method is to set Email in the email text box
public void setEmail(String strEmail){
emailTextBox.sendKeys(strEmail);
}
//This method is to set Password in the password text box
public void setPassword(String strPassword){
passwordTextBox.sendKeys(strPassword);
}
//This method is to click on Login Button
public void clickOnLoginButton(){
signinButton.click();
}
}
Step 3: Creating Test (Eg., FBLoginTest) based on above pages. As per my test scenario which was mentioned above, scripts run as follows.
- Launch browser and open facebook.com
- Enter user credentials and do signin
- Verify the loggedIn user name and do logout
FBLoginTest.java (Test Case 1)
package tests;
import org.openqa.selenium.support.PageFactory;
import org.testng.annotations.AfterTest;
import org.testng.annotations.Test;
import pages.FBHomePage;
import pages.FBLoginPage;
public class FbLoginTest extends TestBase{
@Test
public void init() throws Exception{
//driver.get("https://www.facebook.com");
logger = extent.createTest("To verify FB Login");
FBLoginPage loginpage = PageFactory.initElements(driver, FBLoginPage.class);
loginpage.setEmail("rahul.kundu1@gmail.com");
logger.createNode("Email id entered");
loginpage.setPassword("Rk@1991987");
logger.createNode("password entered");
loginpage.clickOnLoginButton();
logger.createNode("Click on login button");
logger = extent.createTest("To verify home page");
FBHomePage homepage = PageFactory.initElements(driver, FBHomePage.class);
homepage.clickOnProfileDropdown();
logger.createNode("Clicked on profile dropdown");
homepage.verifyLoggedInUserNameText();
logger.createNode("verified that logged in text");
homepage.clickOnLogoutLink();
logger.createNode("Clicked on logout link");
}
}
Step 4: Creating testng.xml file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Everjobs Suite">
<test name="Page Object Model Project">
<classes>
<class name="tests.TestBase" />
<class name="tests.FbLoginTest" />
</classes>
</test>
</suite> <!-- Suite -->
Please check the pom.xml that i have used.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>PageObjectModel</groupId>
<artifactId>pomtest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.6.0</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.aventstack</groupId>
<artifactId>extentreports</artifactId>
<version>5.0.9</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
</project>
For extent report add the following dependency in your pom.xml:
<dependency>
<groupId>com.aventstack</groupId>
<artifactId>extentreports</artifactId>
<version>5.0.9</version>
</dependency>
Please check the Extent report generated after refreshing the project, you will see "RKExtentReport.html" under test-output folder. This is 100% working code and if you find any difficulty then you can post your queries.


RK