I hope that you have enjoyed the journey of “Step by step tutorial of setting up Keyword Driven Framework with Selenium WebDriver” so far and you have understood all the topics well. Let’s revise what we have covered and do a Practice Exercise on it.
What we have covered in the previous chapters:
- Automate an End 2 End flow
- Identify & Implement Action Keywords
- Set Up Data Engine – Excel Sheet
- Implement Java Reflection class to create Action Keywords run time
- Set Up Java Constant Variables for fixed data
- Set Up Object Repository properties file
- Set Up Test Suite Execution Engine
- Set Up Log4j Logging in Framework
- Set Up Exception Handling in Framework
- Set Up Test Result Reporting
- Set Up Data Driven Technique in Framework
- Set Up Framework for Manual Testers
It is almost the end of setting up the framework. We have already covered everything and what is remaining is expanding the test to cover End to End scenarios. Still, there can be many enhancement pending on this framework such as screenshots, html reporting, emailing status or many more.
Practice Exercise
Before jumping to the next level I would like to do an exercise on what we have learned so far on the Demo Application. What we have covered so far is the Login functionality only. I would like you to automate an end to end flow covering below steps:
- Login to the demo application Online Store
- Selecting a product category from Top Menu
- Selecting a product and adding it to the cart
- Go to payment details page and complete the order
- Verify details from final Confirmation page
Once you are done with the above exercise, please send me your code so that I can share it with wider audience with your name.
Project Download
Please download the code from here Selenium Automation - Keyword Driven Framework
Or please read the code below.
Package: executionEngine
Class: DriverScript
package executionEngine;
import java.io.FileInputStream;
import java.lang.reflect.Method;
import java.util.Properties;
import org.apache.log4j.xml.DOMConfigurator;
import config.ActionKeywords;
import config.Constants;
import utility.ExcelUtils;
import utility.Log;
public class DriverScript {
public static Properties OR;
public static ActionKeywords actionKeywords;
public static String sActionKeyword;
public static String sPageObject;
public static Method method[];
public static int iTestStep;
public static int iTestLastStep;
public static String sTestCaseID;
public static String sRunMode;
public static String sData;
public static boolean bResult;
public DriverScript() throws NoSuchMethodException, SecurityException{
actionKeywords = new ActionKeywords();
method = actionKeywords.getClass().getMethods();
}
public static void main(String[] args) throws Exception {
ExcelUtils.setExcelFile(Constants.Path_TestData);
DOMConfigurator.configure("log4j.xml");
String Path_OR = Constants.Path_OR;
FileInputStream fs = new FileInputStream(Path_OR);
OR= new Properties(System.getProperties());
OR.load(fs);
DriverScript startEngine = new DriverScript();
startEngine.execute_TestCase();
}
private void execute_TestCase() throws Exception {
int iTotalTestCases = ExcelUtils.getRowCount(Constants.Sheet_TestCases);
for(int iTestcase=1;iTestcase<iTotalTestCases;iTestcase++){
bResult = true;
sTestCaseID = ExcelUtils.getCellData(iTestcase, Constants.Col_TestCaseID, Constants.Sheet_TestCases);
sRunMode = ExcelUtils.getCellData(iTestcase, Constants.Col_RunMode,Constants.Sheet_TestCases);
if (sRunMode.equals("Yes")){
Log.startTestCase(sTestCaseID);
iTestStep = ExcelUtils.getRowContains(sTestCaseID, Constants.Col_TestCaseID, Constants.Sheet_TestSteps);
iTestLastStep = ExcelUtils.getTestStepsCount(Constants.Sheet_TestSteps, sTestCaseID, iTestStep);
bResult=true;
for (;iTestStep<iTestLastStep;iTestStep++){
sActionKeyword = ExcelUtils.getCellData(iTestStep, Constants.Col_ActionKeyword,Constants.Sheet_TestSteps);
sPageObject = ExcelUtils.getCellData(iTestStep, Constants.Col_PageObject, Constants.Sheet_TestSteps);
sData = ExcelUtils.getCellData(iTestStep, Constants.Col_DataSet, Constants.Sheet_TestSteps);
execute_Actions();
if(bResult==false){
ExcelUtils.setCellData(Constants.KEYWORD_FAIL,iTestcase,Constants.Col_Result,Constants.Sheet_TestCases);
Log.endTestCase(sTestCaseID);
break;
}
}
if(bResult==true){
ExcelUtils.setCellData(Constants.KEYWORD_PASS,iTestcase,Constants.Col_Result,Constants.Sheet_TestCases);
Log.endTestCase(sTestCaseID);
}
}
}
}
private static void execute_Actions() throws Exception {
for(int i=0;i<method.length;i++){
if(method[i].getName().equals(sActionKeyword)){
method[i].invoke(actionKeywords,sPageObject, sData);
if(bResult==true){
ExcelUtils.setCellData(Constants.KEYWORD_PASS, iTestStep, Constants.Col_TestStepResult, Constants.Sheet_TestSteps);
break;
}else{
ExcelUtils.setCellData(Constants.KEYWORD_FAIL, iTestStep, Constants.Col_TestStepResult, Constants.Sheet_TestSteps);
ActionKeywords.closeBrowser("","");
break;
}
}
}
}
}
Package: config
Class: Action Keywords
package config;
import java.util.concurrent.TimeUnit;
import static executionEngine.DriverScript.OR;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import executionEngine.DriverScript;
import utility.Log;
public class ActionKeywords {
public static WebDriver driver;
public static void openBrowser(String object,String data){
Log.info("Opening Browser");
try{
if(data.equals("Mozilla")){
driver=new FirefoxDriver();
Log.info("Mozilla browser started");
}
else if(data.equals("IE")){
//Dummy Code, Implement you own code
driver=new InternetExplorerDriver();
Log.info("IE browser started");
}
else if(data.equals("Chrome")){
//Dummy Code, Implement you own code
driver=new ChromeDriver();
Log.info("Chrome browser started");
}
int implicitWaitTime=(10);
driver.manage().timeouts().implicitlyWait(implicitWaitTime, TimeUnit.SECONDS);
}catch (Exception e){
Log.info("Not able to open the Browser --- " + e.getMessage());
DriverScript.bResult = false;
}
}
public static void navigate(String object, String data){
try{
Log.info("Navigating to URL");
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get(Constants.URL);
}catch(Exception e){
Log.info("Not able to navigate --- " + e.getMessage());
DriverScript.bResult = false;
}
}
public static void click(String object, String data){
try{
Log.info("Clicking on Webelement "+ object);
driver.findElement(By.xpath(OR.getProperty(object))).click();
}catch(Exception e){
Log.error("Not able to click --- " + e.getMessage());
DriverScript.bResult = false;
}
}
public static void input(String object, String data){
try{
Log.info("Entering the text in " + object);
driver.findElement(By.xpath(OR.getProperty(object))).sendKeys(data);
}catch(Exception e){
Log.error("Not able to Enter UserName --- " + e.getMessage());
DriverScript.bResult = false;
}
}
public static void waitFor(String object, String data) throws Exception{
try{
Log.info("Wait for 5 seconds");
Thread.sleep(5000);
}catch(Exception e){
Log.error("Not able to Wait --- " + e.getMessage());
DriverScript.bResult = false;
}
}
public static void closeBrowser(String object, String data){
try{
Log.info("Closing the browser");
driver.quit();
}catch(Exception e){
Log.error("Not able to Close the Browser --- " + e.getMessage());
DriverScript.bResult = false;
}
}
}
Class: Constants
package config;
public class Constants {
//System Variables
public static final String URL = "https://www.store.demoqa.com";
public static final String Path_TestData = "D://Tools QA Projects//trunk//Hybrid KeyWord Driven//src//dataEngine//DataEngine.xlsx";
public static final String Path_OR = "D://Tools QA Projects//trunk//Hybrid KeyWord Driven//src//config//OR.txt";
public static final String File_TestData = "DataEngine.xlsx";
public static final String KEYWORD_FAIL = "FAIL";
public static final String KEYWORD_PASS = "PASS";
//Data Sheet Column Numbers
public static final int Col_TestCaseID = 0;
public static final int Col_TestScenarioID =1 ;
public static final int Col_PageObject =4 ;
public static final int Col_ActionKeyword =5 ;
public static final int Col_RunMode =2 ;
public static final int Col_Result =3 ;
public static final int Col_DataSet =6 ;
public static final int Col_TestStepResult =7 ;
// Data Engine Excel sheets
public static final String Sheet_TestSteps = "Test Steps";
public static final String Sheet_TestCases = "Test Cases";
}
Properties: Object Repository
# Home Page Objects
btn_MyAccount=.//*[@id='account']/a
btn_LogOut=.//*[@id='account_logout']/a
# Login Page Object
txtbx_UserName=.//*[@id='log']
txtbx_Password=.//*[@id='pwd']
btn_LogIn=.//*[@id='login']
Package: dataEngine
Sheet: Test Case
Sheet: Test Steps
Sheet: Test Data
Sheet: Settings
Package: Utility
Class: ExcelUtils
package utility;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFRow;
import config.Constants;
import executionEngine.DriverScript;
public class ExcelUtils {
private static XSSFSheet ExcelWSheet;
private static XSSFWorkbook ExcelWBook;
private static org.apache.poi.ss.usermodel.Cell Cell;
private static XSSFRow Row;
//private static XSSFRow Row;
public static void setExcelFile(String Path) throws Exception {
try {
FileInputStream ExcelFile = new FileInputStream(Path);
ExcelWBook = new XSSFWorkbook(ExcelFile);
} catch (Exception e){
Log.error("Class Utils | Method setExcelFile | Exception desc : "+e.getMessage());
DriverScript.bResult = false;
}
}
public static String getCellData(int RowNum, int ColNum, String SheetName ) throws Exception{
try{
ExcelWSheet = ExcelWBook.getSheet(SheetName);
Cell = ExcelWSheet.getRow(RowNum).getCell(ColNum);
String CellData = Cell.getStringCellValue();
return CellData;
}catch (Exception e){
Log.error("Class Utils | Method getCellData | Exception desc : "+e.getMessage());
DriverScript.bResult = false;
return"";
}
}
public static int getRowCount(String SheetName){
int iNumber=0;
try {
ExcelWSheet = ExcelWBook.getSheet(SheetName);
iNumber=ExcelWSheet.getLastRowNum()+1;
} catch (Exception e){
Log.error("Class Utils | Method getRowCount | Exception desc : "+e.getMessage());
DriverScript.bResult = false;
}
return iNumber;
}
public static int getRowContains(String sTestCaseName, int colNum,String SheetName) throws Exception{
int iRowNum=0;
try {
//ExcelWSheet = ExcelWBook.getSheet(SheetName);
int rowCount = ExcelUtils.getRowCount(SheetName);
for (; iRowNum<rowCount; iRowNum++){
if (ExcelUtils.getCellData(iRowNum,colNum,SheetName).equalsIgnoreCase(sTestCaseName)){
break;
}
}
} catch (Exception e){
Log.error("Class Utils | Method getRowContains | Exception desc : "+e.getMessage());
DriverScript.bResult = false;
}
return iRowNum;
}
public static int getTestStepsCount(String SheetName, String sTestCaseID, int iTestCaseStart) throws Exception{
try {
for(int i=iTestCaseStart;i<=ExcelUtils.getRowCount(SheetName);i++){
if(!sTestCaseID.equals(ExcelUtils.getCellData(i, Constants.Col_TestCaseID, SheetName))){
int number = i;
return number;
}
}
ExcelWSheet = ExcelWBook.getSheet(SheetName);
int number=ExcelWSheet.getLastRowNum()+1;
return number;
} catch (Exception e){
Log.error("Class Utils | Method getRowContains | Exception desc : "+e.getMessage());
DriverScript.bResult = false;
return 0;
}
}
@SuppressWarnings("static-access")
public static void setCellData(String Result, int RowNum, int ColNum, String SheetName) throws Exception {
try{
ExcelWSheet = ExcelWBook.getSheet(SheetName);
Row = ExcelWSheet.getRow(RowNum);
Cell = Row.getCell(ColNum, Row.RETURN_BLANK_AS_NULL);
if (Cell == null) {
Cell = Row.createCell(ColNum);
Cell.setCellValue(Result);
} else {
Cell.setCellValue(Result);
}
FileOutputStream fileOut = new FileOutputStream(Constants.Path_TestData);
ExcelWBook.write(fileOut);
//fileOut.flush();
fileOut.close();
ExcelWBook = new XSSFWorkbook(new FileInputStream(Constants.Path_TestData));
}catch(Exception e){
DriverScript.bResult = false;
}
}
}
Class: Log
package utility;
import org.apache.log4j.Logger;
public class Log {
//Initialize Log4j logs
private static Logger Log = Logger.getLogger(Log.class.getName());//
// This is to print log for the beginning of the test case, as we usually run so many test cases as a test suite
public static void startTestCase(String sTestCaseName){
Log.info("****************************************************************************************");
Log.info("****************************************************************************************");
Log.info("$$$$$$$$$$$$$$$$$$$$$ "+sTestCaseName+ " $$$$$$$$$$$$$$$$$$$$$$$$$");
Log.info("****************************************************************************************");
Log.info("****************************************************************************************");
}
//This is to print log for the ending of the test case
public static void endTestCase(String sTestCaseName){
Log.info("XXXXXXXXXXXXXXXXXXXXXXX "+"-E---N---D-"+" XXXXXXXXXXXXXXXXXXXXXX");
Log.info("X");
Log.info("X");
Log.info("X");
Log.info("X");
}
// Need to create these methods, so that they can be called
public static void info(String message) {
Log.info(message);
}
public static void warn(String message) {
Log.warn(message);
}
public static void error(String message) {
Log.error(message);
}
public static void fatal(String message) {
Log.fatal(message);
}
public static void debug(String message) {
Log.debug(message);
}
}