Page Object Model | Feature Framework

In last tutorial we have seen how to create basic POM framework, but in organization level framework should serve all the needs.

In this tutorial we are going to learn how to implement page Object Model with full features using selenium webdriver

A good Framework should support :

1. Reusable methods
2. Logging
3. Low maintanance
4. Reporting
5. Test case mapping with manual test cases
6. Data Changes without compiling
7. Handling non Supported application
We will learn how to implement all thse featues in page object model

Page Object Model Folder Structure

folder-structure-pom-selenium-webdriver

Page object model contains several packages, let's learn about each package and its purpose in the framework.

base : base package will conatins all the initialization files like opening browser, initializing logging

constants : conatsnts package will have all the constant file like Css properties, Attribute properties.

data : data package will have all the data handling java files like handling excel, handling properties java files..

files : files folder will have all the file s used in our framework which includes input and output files like excel sheets, properties fils

jars : jars folder will contain all the jar files related with our framework

lib : lib package will have all the re-usable libraries

po : po package will have all the page object java classes

test : test package will have all the testcases in framework.

Logging

Logging is very important for framework, without logs user may not be able to find the execution point.

We will be using log4j for logging purpose, you can find the complete tutorial about logging on Log4j with Selenium Webdriver




Steps for Logging :
1. Create InitializeLogging class under base package, All remaining classes are going to extend this class

2. Create a static block, as we are not going to change anything in the log4j properties during run time, we can hard code the values.

    Static Block : static block will be executed once the class is loadded to stack, static block executes even before main method.

3. Create variable called log for logging the all the logs from the framework, which shloud be static and public, so that we can access across testcases.

4. Configure the properties file using configure method from the PropertyConfigurator class

log4j properties file


										# Root logger denotes where to write and priority level to write
										log4j.rootLogger=INFO, file
										 
										# Direct log messages to a log file
										log4j.appender.file=org.apache.log4j.RollingFileAppender
										log4j.appender.file.File=C:\\Users\\user\\Pictures\\firstLogOutput.log
										log4j.appender.file.MaxFileSize=10MB
										log4j.appender.file.MaxBackupIndex=10

										# layout of the log output pattern
										log4j.appender.file.layout=org.apache.log4j.PatternLayout
										log4j.appender.file.layout.ConversionPattern=[%t] %-5p %c %x - %m%n
										

Complete program for logging with log4j:

										package base;
										
										import org.apache.log4j.Logger;
										import org.apache.log4j.PropertyConfigurator;
										
										public class InitializeLogging {
											public static Logger log = Logger.getLogger("Regression");
											// static block
											static{
												//PropertiesConfigurator is used to configure logger from properties file
												PropertyConfigurator.configure("C:\\Users\\user\\Pictures\\log4j.properties");
										 
												//log the message to file
												log.trace("Logging Initialized");
											}
										}
										
										

Handle Excel data

It is important for any framework to work with data changes without re-compilation, Apache POI helps us to read data from the excel sheet in selenium webdriver.


Below are the steps to read Excel:

1. Create java class ExcelData under data package, ExcelData should extend InitializeLogging class

2. To support multi-threading we have to write all the method as non-static methods.

3. Let's write method called readExcel which accepts the Excel file name, Excel Sheet name, row number, column number.

4. Read the data by creating object to Workbook class, call getStingCellvalue() method to get the value of the cell

5. We can log the data that we retrieved from the excel.

6. Return the cell value

Steps to write Excel in data :
1. In ExcelData class write one more non-static method called writeExcel , writeExcel method should accept Excel file name, Excel Sheet name, row number, column number, and data to write

2. We can set the cell value using setCellValue() method present in Apache POI
3. Log the data that we about to write to the excel.


Complete Excel reading and writing program :


										import java.io.FileInputStream;
										import java.io.FileOutputStream;
										import org.apache.poi.ss.usermodel.Cell;
										import org.apache.poi.ss.usermodel.Row;
										import org.apache.poi.ss.usermodel.Sheet;
										import org.apache.poi.ss.usermodel.Workbook;
										import org.apache.poi.ss.usermodel.WorkbookFactory;

										public class ExcelData {
											public String readData(String inputFile, String sheetname, int rowNumber, int columnNumber) throws Exception {
												// create file input stream object for the excel sheet
												FileInputStream fis = new FileInputStream(inputFile);
												// create object for work book
												Workbook wb = WorkbookFactory.create(fis);
												//create object for sheet present in excel using Workbook object 'wb'
												Sheet sheet = wb.getSheet(sheetname);
												//create object for row present in sheet using Sheet object 'sheet'
												Row row = sheet.getRow(rowNumber);
												//create object for cell present in row using Row object 'row'
												Cell cell = row.getCell(columnNumber);
												// return the value present in the excel sheet cell
												return cell.getStringCellValue();
											}
											
											public void writeData(String outputFile, String sheetName, int rowNumber, int columnNumber, String dataToWrite) throws Exception {
												// create file input stream object for the excel sheet
												FileInputStream fis = new FileInputStream(outputFile);
												// create object for work book
												Workbook wb = WorkbookFactory.create(fis);
												//create object for sheet present in excel using Workbook object 'wb'
												Sheet sheet = wb.getSheet(sheetName);
												//create object for row present in sheet using Sheet object 'sheet'
												Row row = sheet.getRow(rowNumber);
												//create object for cell present in row using Row object 'row'
												Cell cell = row.createCell(columnNumber);
												cell.setCellValue(dataToWrite);
												FileOutputStream fos = new FileOutputStream(outputFile);
												wb.write(fos);
											}
										}
										

Handle Properties file

When we donot have much data or when we have data which almost never going to change, we can use data in Properties file such kind of situations. Details like username, password, application url.

Steps to Read properties file :
1. Create a Java class called PropertiesData under data package

2. Create non-static metghod called readProperty, which should accept following parameters Properties file name, Property name. readProperty method should return a string value.

3. Create object for Properties class

4. Load FileInputStream object into properties file using load method present in Properties class object

5. Get the values using 'get("key")' method or getProperty("key") method by passing key as the patrameter

Steps to Write properties file :
1. Write non-static method called writeProperty, which should accept following paramaters Properties file name, Property name, property value.

2. Create Properties class object to access the property file.

3. Set the values using setProperty("key","Value") method by passing key and values as the patrameters

Complete Properties file reading and writing program :


										import java.io.FileInputStream;
										import java.io.FileOutputStream;
										import java.util.Properties;

										public class PropertiesData {
											public String readProperty(String fileName, String property) throws Exception {
												// create file input stream object for the properties file
												FileInputStream fis = new FileInputStream(fileName);
												// create Properties class object to access properties file
												Properties prop = new Properties();
												// load the properties file
												prop.load(fis);
												// return the property value
												return prop.getProperty(property);
											}
											
											public void writeProperty(String outputFile, String property, String propertyValue) throws Exception{
												// create file output stream object for the properties file
												FileOutputStream fis = new FileOutputStream(outputFile);
												// create Properties class object to access properties file
												Properties prop = new Properties();
												// load the properties file
												// set the properties
												prop.setProperty(property, propertyValue);
												// store the file into local system
												prop.store(fis, null);
											}
										}
										

Implementing Class Constructor locator in Selenium

Initialization of driver

We have to initialize our browser and we have to store it in driver variable. We should initialize the browser at top most class in page object model, so that we can use the driver across all other scripts. This class should not have any scripts.

We should also make the browser invocation on run time i.e we should choose our browser on run time by getting the data either from excel sheet or from Properties file


Steps to Initialize browser :
1. Create a class called IntializeBrowser which should extend InitializeLogging for logging purpose

2. Initialize 'browser' variable with object of the EventFiringWebDriver to listen to all the events occurring in framework. This browser only will be used across all the testcases for accessing all the elements from the webpage.

3. Read propertis file to know which browser to invoke

4. We have to write if else condition block to decide which browser to open based on the value retrieved from the properties file.

5. Log the browser name using log4j

6. We have modularize teh class for easy debugging purpose


Complete program for IntializeBrowser

										package base;
										
										import org.openqa.selenium.WebDriver;
										import org.openqa.selenium.chrome.ChromeDriver;
										import org.openqa.selenium.firefox.FirefoxDriver;
										import org.openqa.selenium.ie.InternetExplorerDriver;
										import org.openqa.selenium.support.events.EventFiringWebDriver;
										
										import data.PropertiesData;
										
										public class IntializeBrowser extends InitializeLogging {
											// this browser variable will be used through the framework
											public static EventFiringWebDriver browser;
											
											public static void main(String[] args) throws Exception {
												// initialize driver
												WebDriver driver = initializeDriver();
												// Create object for Listener implementation
												ListenerHelper listen = new ListenerHelper();
												// create object event listener object
												browser = new EventFiringWebDriver(driver);
												// register even listener object
												browser.register(listen);
												
											}
											
											private static WebDriver initializeDriver() throws Exception
											{
												WebDriver driver = null;
												PropertiesData pd = new PropertiesData();
												String propertiesFilePath = "C:\\Users\\user\\workspace1\\FeaturePOM\\src\\files\\input\\config.properties";
												String browserToChoose = pd.readProperty(propertiesFilePath, "browser");
												log.info("Trying to browser : "+browserToChoose);
												if(browserToChoose.equalsIgnoreCase("firefox") || browserToChoose.equalsIgnoreCase("ff")){
													System.setProperty("webdriver.gecko.driver", "C:/~/geckodriver.exe");
													driver = new FirefoxDriver();
													
												}else if(browserToChoose.equalsIgnoreCase("chrome") || browserToChoose.equalsIgnoreCase("gc")){
													System.setProperty("webdriver.chrome.driver", "C:/~/chromedriver.exe");
													driver = new ChromeDriver();
												}else if(browserToChoose.equalsIgnoreCase("internet explorer") || browserToChoose.equalsIgnoreCase("ie")){
													System.setProperty("webdriver.ie.driver", "C:/~/IEdriverserver.exe");
													driver = new InternetExplorerDriver();
												}
												log.info(browserToChoose+" browser opened successfully");
												return driver;
											}
										}
										

Constants in Page Object Model

We will be using some constants in our application framework, instead of writing those contants on test or lib files, we can write all of them under contants package.

For example : We may be using CSS properties like 'font, color, background-color, padding-top, margin-left, font-size..'

Steps to create constants :

1. Create a java Interface called ICssContants under constants package.

2. Write all the properties as public static String variable.

3. We are wring the string snot the css values

4. By this way we can avoid creation of string during run time, and also can avoid duplicate strings.

ICssConstants file:


										package constants;
										
										public interface ICssConstants {
											public static String FONT_SIZE = "font-size";
											public static String COLOR = "color";
											public static String FONT_WEIGHT = "font-weight";
											public static String PADDING_TOP = "padding-top";
										}
										
										

Page Objects

We are going to use google.com as project url, so we have to create PageObject Classes based on the
1. Google Home Page,
2. Google Search Result Page

We are gong to use non-static methods as page objects and which returns WebElement or WebElements

Steps to create PageObjects :

1. Create a class called HomePagePO which inherits IntializeBrowser, so that we can access browser variable directly

2. Create non-static methods which retun webelement or webelements
3. Create header fr teach method you create in the framework
4. write log statements based on our need

Complete HomePagePO file :


										import org.openqa.selenium.By;
										import org.openqa.selenium.WebElement;
										import base.IntializeBrowser;
										
										public class HomePagePO extends IntializeBrowser {
											/**
											 * @author user
											 * @return WebElement
											 */
											public static WebElement searchBar(){
												return browser.findElement(By.name("q"));
											}
											
											/**
											 * @author user
											 * @return WebElement
											 */
											public static WebElement searchButton(){
												return browser.findElement(By.xpath("//input[contains(@value, 'Search')]"));
											}
											/**
											 * @author user
											 * @return WebElement
											 */
											public static WebElement googleBanner(){
												return browser.findElement(By.id("hplogo"));
											}
										}
										

Library Files

Sometimes we may have a repeating test steps across script, in such cases we have to create those steps as re-usable methods. Re-usable methods can be used across multiple scripts in framework

Steps to create Library :
1. Library Name should be Same as PageObject Class name except the PO at the end, library file names will have Lib in end like HomePageLib, SearchResultPageLib...

2. Create a class called HomePageLib under lib package,

3. Import the static member of InitializeLogging class

4. We have to create create object for the PO class that we are going use in this Lib file. Eg:HomePagePO hp = new HomePagePO();

5. Write all the methods as non-static methods, and return the values if required.

6. We can add log statement based on our need

Complete HomePageLib


										import static base.InitializeLogging.*;
										import po.HomePagePO;

										public class HomePageLib {
											HomePagePO hp = new HomePagePO();
											
											public void searchGoogle(String searchTerm){
												hp.searchBar().sendKeys(searchTerm);
												log.info("Searching google for the term : "+searchTerm);
												hp.searchButton().click();
												log.info("Google search button clicked");
											}
										}

										
Note: For example purpose I have created only one method

Unit Testing Framework | TestNG

When we want to create testcases we should have unit testing framework integrated with our application. With selenium java we can use either TestNG or JUnit. For this framework we will be using TestNG unit testing framework

Steps to integrate TestNG :

1. Right click on the project and click Properties Option
2. Click On the Add Library
3. Choose TestNG from available libraries
4. Click Next and Finish


Note: Please visit for TestNG with Selenium Webdriver tutorials section for more Details

Test Cases With TestNG in Selenium Webdriver

We have create testcase class to create test scripts, which are nothing but automation scripts for ourmanual testcases. We are using TestNG tool for mapping manual and automation testcases. Every @Test denotes that it s a testcase, and result will be generated based on this test.

Steps to create test case Class :

1. Create a class called HomePageTest, name of the class should be accordance with PO and Lib classes

2. Import the static member of the InitializeBrowser class so that we can acces browser variable.

3. Create a non-static method to write the test steps and annote the method with @Test annotation

4. based on our need we can write @Before and @After annotations

5. Log details if required, details like what test case, test case name, test case number, what step is running

Complete file of HomePageTest


										import org.testng.annotations.AfterClass;
										import org.testng.annotations.BeforeClass;
										import org.testng.annotations.Test;
										import static base.IntializeBrowser.*;

										import lib.HomePageLib;

										public class HomePageTest {

											HomePageLib hpLib = new HomePageLib();
											@BeforeClass
											public void setUp(){
												browser.get("https://google.com");
											}
											@Test
											public void searchGoogleTest(){
												hpLib.searchGoogle("first test with POM");
											}
											@AfterClass
											public void tearDown(){
												browser.quit();
											}
										}

										

Result and Logging

Result :
1. On the eclipse console we can check the result under TestNG section. testng-tab-output-pom-selenium-webdriver testng-tab-output-pom-selenium-webdriver

2. We can also Check the HTML report from the TestNG by navigatiing to test-output folder under project and open index.html

test-output folder test-output-pom-selenium-webdriver


Index.html html-testng-pom-selenium-webdriver

Logging : log-pom-selenium-webdriver

Learn OOPS in Java with selenium

About Author

Myself KarthiQ, I am the author of this blog, I know ways to write a good article but some how I donot have the skills to make it to reach people, would you like help me to reach more people By sharing this Article in the social media.

Share this Article Facebook
Comment / Suggestion Section
Point our Mistakes and Post Your Suggestions

Recent Addition

new tutorial Registrations for Selenium Online Training is Over.

Below are the training details:
Meeting link : https://zoom.us/j/737840591
Starting Time : 9:00PM 18th DEC 2018
 
Join My Facebook Group
Join Group