Compleet Page Object Model Framework -2021

In deze tutorial zullen we leren over het Page Object Model, en ook zullen we het Page Object Model framework helemaal opnieuw ontwerpen en ontwikkelen. 

We hadden alle besproken soorten raamwerk in Selenium, inclusief Page Object Model , hier zouden we dieper ingaan.

We zullen de onderstaande functies ontwerpen en ontwikkelen.

Wat is Page Object Model Framework-ontwerp in Selenium  

Pagina-objectmodel is een ontwerpmodel voor het bouwen van Selenium-testautomatisering, waarbij we onze hele te testen applicatie in kleine pagina's distribueren (soms wordt een webpagina als een pagina beschouwd en soms wordt een subgedeelte van een webpagina ook als een pagina beschouwd). Elk van deze pagina's wordt weergegeven als een Java-klasse en de functionaliteiten van de pagina's zijn geschreven als verschillende methoden in de Java-klasse van de betreffende pagina.

Stel dat u een Gmail-applicatie heeft die u gaat automatiseren; vandaar dat de inlogpagina van Gmail daar is waar je enkele belangrijke functionaliteiten hebt, zoals inloggen, een account aanmaken, etc.

Hier zullen we een Java-klasse maken als GmailLoginPage, en we zullen methoden schrijven met de naam performLogin (), createUserAccount, enz. 

Laten we zeggen dat als je eenmaal bent ingelogd op je Gmail-account, je veel functies hebt zoals inbox, verzonden items, prullenbak, enz. Nu hier, voor elke module, maak je een Java-klasse en bewaar je hun functionaliteiten als Java-methoden binnen de respectievelijke java-klassen. 

Waarom Page Object Model

Page Object Model is een zeer robuust en geavanceerd framework-ontwerpmodel waarin u voor de onderstaande gebieden kunt zorgen: 

Hybride pagina-objectmodel Framework-structuur

In het vorige tutorial, we begrepen het hybride Page Object Model, en nu gaan we een raamwerk ontwerpen en ontwikkelen.

De architectuur van het Page Object Model Framework

We kunnen eenvoudig een maven-project maken en de afhankelijkheden opnemen in het POM.xml-bestand dat nodig is voor het framework dat er aanvankelijk als volgt uitziet: 

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
\txsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
\t<modelVersion>4.0.0</modelVersion>

\t<groupId>demo</groupId>
\t<artifactId>DemoAutomation</artifactId>
\t<version>0.0.1-SNAPSHOT</version>
\t<packaging>jar</packaging>

\t<name>DemoAutomation</name>
\t<url>http://maven.apache.org</url>
\t<properties>
\t\t<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
\t</properties>
\t<build>
\t\t<plugins>
\t\t\t<plugin>
\t\t\t\t<groupId>org.apache.maven.plugins</groupId>
\t\t\t\t<artifactId>maven-compiler-plugin</artifactId>
\t\t\t\t<version>3.0</version>
\t\t\t\t<configuration>
\t\t\t\t\t<source>7</source>
\t\t\t\t\t<target>7</target>
\t\t\t\t</configuration>
\t\t\t</plugin>
\t\t\t<plugin>
\t\t\t\t<groupId>org.apache.maven.plugins</groupId>
\t\t\t\t<artifactId>maven-surefire-plugin</artifactId>
\t\t\t\t<version>2.4.2</version>
\t\t\t\t<configuration>
\t\t\t\t\t<suiteXmlFiles>
\t\t\t\t\t\t<suiteXmlFile>testNg.xml</suiteXmlFile>
\t\t\t\t\t</suiteXmlFiles>
\t\t\t\t</configuration>
\t\t\t</plugin>
\t\t</plugins>
\t</build>
\t<reporting>
\t\t<plugins>
\t\t\t<plugin>
\t\t\t\t<groupId>org.reportyng</groupId>
\t\t\t\t<artifactId>reporty-ng</artifactId>
\t\t\t\t<version>1.2</version>
\t\t\t\t<configuration>
\t\t\t\t    <outputdir>/target/testng-xslt-report</outputdir>
\t\t\t\t    <sorttestcaselinks>true</sorttestcaselinks>
\t\t\t            <testdetailsfilter>FAIL,SKIP,PASS,CONF,BY_CLASS</testdetailsfilter>
\t\t\t\t    <showruntimetotals>true</showruntimetotals>
\t\t\t\t</configuration>
\t\t\t</plugin>
\t\t</plugins>
\t</reporting>
\t<dependencies>
\t\t<dependency>
\t\t\t<groupId>org.seleniumhq.selenium</groupId>
\t\t\t<artifactId>selenium-server</artifactId>
\t\t\t<version>2.53.0</version>
\t\t</dependency>
\t\t<dependency>
\t\t\t<groupId>org.testng</groupId>
\t\t\t<artifactId>testng</artifactId>
\t\t\t<version>6.8.1</version>
\t\t</dependency>
\t\t<dependency>
\t\t\t<groupId>org.apache.poi</groupId>
\t\t\t<artifactId>poi</artifactId>
\t\t\t<version>3.8</version>
\t\t</dependency>
\t\t<dependency>
\t\t\t<groupId>org.apache.poi</groupId>
\t\t\t<artifactId>poi-ooxml</artifactId>
\t\t\t<version>3.8</version>
\t\t</dependency>

\t\t<dependency>
\t\t\t<groupId>com.googlecode.json-simple</groupId>
\t\t\t<artifactId>json-simple</artifactId>
\t\t\t<version>1.1</version>
\t\t</dependency>

\t\t<dependency>
\t\t\t<groupId>net.sourceforge.jexcelapi</groupId>
\t\t\t<artifactId>jxl</artifactId>
\t\t\t<version>2.6</version>
\t\t</dependency>
\t</dependencies>
</project>

Daarna zullen we kleine modules en hulpprogramma's bouwen, waar we deze momentopname hieronder hebben bijgevoegd om inzichten / weergave op hoog niveau te bieden. We bouwen hulpprogramma's een voor een. 

Hier zijn de onderstaande modules die we zullen ontwikkelen; we hebben het codefragment voor hetzelfde verstrekt: 

DriverUtils - Page Object Model Framework

Deze module biedt alle hulpprogramma's en ondersteuning om met de verschillende browsers (Chrome, Firefox, enz.) te werken. Dit hulpprogramma is gebaseerd op de Factory ontwerp patroon, zoals we in de vorige zelfstudie hier hebben besproken.

pakket com.base.driverUtils; import org.openqa.selenium.WebDriver; openbare interface IDriver { openbare WebDriver init (String browserName); }

Localdriver-implementatie, die lokaal wordt uitgevoerd met Selenium-webstuurprogramma :

pakket com.base.driverUtils;
importeer org.openqa.selenium.WebDriver;
importeer org.openqa.selenium.chrome.ChromeDriver;
importeer org.openqa.selenium.firefox.FirefoxDriver;
importeer org.openqa.selenium.ie.InternetExplorerDriver;
public class LocalDriver implementeert IDriver {
  public WebDriver init(String browsernaam) {
     schakelaar (browsernaam) {
     geval "firefox":
        retourneer nieuwe FirefoxDriver();
     geval "chroom":
        System.setProperty("webdriver.chrome.driver",
              "..\\\\DummyAutomation\\\\DriverExe\\\\chromedriver.exe");
        retourneer nieuwe ChromeDriver();
     geval "ie":
        System.setProperty("webdriver.ie.driver",
              "..\\\\DummyAutomation\\\\DriverExe\\\\IEDriverServer.exe");
        retourneer nieuwe InternetExplorerDriver();
     standaard:
        retourneer nieuwe FirefoxDriver();
     }
  }
}

Externe webdriver: om met een externe webdriver (zoals Selenium Grid) te werken, hebt u een externe referentie van de browser-driver nodig, die er als volgt uitziet: 

pakket com.base.driverUtils; import java.net.MalformedURLE Exception; java.net.URL importeren; import org.openqa.selenium.WebDriver; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.remote.RemoteWebDriver; openbare klasse RemoteDriver implementeert IDriver {DesiredCapabilities caps; String op afstandHuburl; @Override public WebDriver init(String browserName) { switch (browserName) { case "firefox": try { return new RemoteWebDriver(new URL(remoteHuburl), caps.firefox()); } catch (MalformedURLException e2) {// TODO Automatisch gegenereerd catch-blok e2.printStackTrace(); } case "chrome": probeer { return new RemoteWebDriver(nieuwe URL(remoteHuburl), caps.chrome()); } catch (MalformedURLException e1) { // TODO Automatisch gegenereerd catch-blok e1.printStackTrace(); } case "ie": probeer { return new RemoteWebDriver(nieuwe URL(remoteHuburl), caps.internetExplorer()); } catch (MalformedURLException e) { // TODO Automatisch gegenereerd catch-blok e.printStackTrace(); } standaard: probeer { retourneer nieuwe RemoteWebDriver (nieuwe URL (remoteHuburl), caps.firefox()); } catch (MalformedURLException e) { // TODO Automatisch gegenereerd catch-blok e.printStackTrace(); } } retourneert null; } }

Factory Driver-klasse: Dit geeft ons het driver class-object (extern / lokaal) om de browsers van uw keuze te starten. We zullen het type stuurprogramma (lokaal of op afstand) en browser (chrome of firefox enz.) Door het configuratiebestand leiden (we hebben een eigenschappenbestand gebruikt om de configuraties te behouden, die we binnenkort zullen delen)

pakket com.base.driverUtils; public class DriverProvider {public IDriver getDriver(String typeOfDriverExecution){ switch(typeOfDriverExecution){ case "local": retourneer nieuwe LocalDriver(); case "remote": retourneer nieuwe RemoteDriver(); standaard: retourneer nieuwe LocalDriver(); } } }

Waar u nu de driverreferentie nodig heeft, u kunt eenvoudig het object van het fabrieksklasse-object maken (in dit geval DriverProvider) en de driver-browserinstantie starten.

Hier is het zeer eenvoudige configuratiebestand; u kunt een eigenschappenbestand maken en de waarden als volgt opslaan: 

modeOfExecution=lokale browser=chrome url=http://www.applicationUrl.com/

DataUtils-Page-objectmodelframework: 

We hebben de gegevenshulpprogramma's hier ontworpen volgens hetzelfde fabrieksontwerppatroon als bij het implementeren van de driver-browsermodules.

Hier is het onderstaande codefragment voor hetzelfde; in het raamwerk hebben we Excel-utils en property-utils getoond, u kunt meer verbeteren om andere gegevenshulpprogramma's zoals YAML, PDF, enz. te ondersteunen: 

De interface hier gaat het als volgt: 

pakket com.base.dataUtils; openbare interface IDataProvider { openbaar object [][] fetchDataSet (String... dataFileInfo); public String fetchData (String... dataFileInfo); }

Hier is de implementatie voor Excel-gegevensprovider

pakket com.base.dataUtils; java.io.Bestand importeren; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; importeer org.apache.poi.xssf.usermodel.XSSFCell; importeer org.apache.poi.xssf.usermodel.XSSFSheet; importeer org.apache.poi.xssf.usermodel.XSSFWorkbook; openbare klasse ExcelDataProvider implementeert IDataProvider { FileInputStream fis = null; privé statisch XSSFWorkbook workBook = null; particuliere statische XSSFCell-cel; privé statisch XSSFSheet-blad; openbare statische String [][] excelDataSet = null; @Override public Object[][] fetchDataSet(String... dataFileInfo) { String excelFilePath = dataFileInfo[0]; String excelSheetName = dataFileInfo [1]; Bestandsbestand = nieuw bestand (excelFilePath); probeer { fis = nieuwe FileInputStream (bestand); } catch (FileNotFoundException e) { // TODO Automatisch gegenereerd catch-blok e.printStackTrace (); } probeer { workBook = nieuwe XSSFWorkbook(fis); } catch (IOException e) { // TODO Automatisch gegenereerd catch-blok e.printStackTrace (); } sheet = workBook.getSheet(excelSheetName); int ci, cj; int rowCount = blad.getLastRowNum(); int totalCols = blad.getRow(0).getPhysicalNumberOfCells(); excelDataSet = nieuwe String [rowCount][totalCols - 1]; ci = 0; for (int i = 1; i <= rowCount; i++, ci++) { cj = 0; for (int j = 1; j <= totalCols - 1; j++, cj++) {probeer {excelDataSet[ci][cj] = getCellData(i, j); } catch (uitzondering e) { // TODO Automatisch gegenereerd catch-blok e.printStackTrace(); } } } retourneer excelDataSet; } openbare statische String getCellData (int RowNum, int ColNum) gooit Exception {try { Cell = sheet.getRow (RowNum).getCell (ColNum); int dataType = Cell.getCellType(); if (dataType == 3) { retourneer ""; } else if (dataType == XSSFCell.CELL_TYPE_NUMERIC) { int i = (int) Cell.getNumericCellValue(); retourneer Integer.toString(i); } else { String CellData = Cell.getStringCellValue(); retourneer CellData; } } vangen (Uitzondering e) { worp (e); } } @Override public String fetchData(String... dataFileInfo) { // TODO Automatisch gegenereerde methode stub return null; } }

Eigenschappen Gegevensprovider: 

pakket com.base.dataUtils; import java.io.FileInputStream; import java.io.IOException; import java.util.Eigenschappen; openbare klasse PropertiesDataProvider implementeert IDataProvider { FileInputStream fis = null; @Override public Object[][] fetchDataSet(String... dataFileInfo) { // TODO Automatisch gegenereerde methode stub return null; } @Override public String fetchData(String... dataFileInfo) { String dataValue; Tekenreeks pathToFile = dataFileInfo[0]; Tekenreekssleutel = dataFileInfo[1]; Eigenschappen eigenschappen = nieuwe eigenschappen(); probeer {fis=nieuwe FileInputStream(pathToFile); eigenschappen.load(fis); } catch (IOException e) { // TODO Automatisch gegenereerd catch-blok e.printStackTrace (); } dataValue = eigenschappen.getProperty(sleutel); retourneer gegevensWaarde; } }

De factory class voor deze data Utilities

pakket com.base.dataUtils; public class DataHelperProvider {public IDataProvider getDataHelperProvider(String typeOfDataHandler) {switch (typeOfDataHandler) {case "excel": retourneer nieuwe ExcelDataProvider(); case "properties": retourneer nieuwe PropertiesDataProvider(); } retourneert null; } }

WebAction-hulpprogramma's -Pagina Object Model Kader

In de hulpprogramma's schrijven we alle hulpprogramma's die verband houden met uw webacties, zoals (klikken, verstuurtoetsen, schermafbeeldingen, enz.), En we kunnen het gebruiken in Paginamethoden om webacties uit te voeren om de paginafuncties te bereiken zoals eerder in deze tutorial besproken. 

Hier is het codefragment voor de WebAction-hulpprogramma's: 

pakket com.base.webActionHelperUtils; java.util.ArrayList importeren; import java.util.Lijst; import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; openbare klasse WebActionsHelperUtils {beveiligde WebDriver-stuurprogramma; openbare WebActionsHelperUtils (WebDriver-stuurprogramma) { dit.stuurprogramma = stuurprogramma; } public void safeClick (per element) { waitForElementToBeClickAble (element, 30); driver.findElement(element).klik(); } openbare lijst getElements (Per elementen) { return driver.findElements (elementen); } public void waitForWebElementsToBeDisplayed (door elementen, int timeOuts) { WebDriverWait wait = nieuwe WebDriverWait (stuurprogramma, timeOuts); wait.until(ExpectedConditions.visibilityOfAllElements(getElements(elementen))); } public void waitForElementToBeClickAble (per element, int timeOutSeconds) { WebDriverWait waitForElement = nieuwe WebDriverWait (stuurprogramma, timeOutSeconds); waitForElement.until(ExpectedConditions.elementToBeClickable(element)); } public void waitForElementToBeDisplayed (per element, int timeOuts) { WebDriverWait wait = nieuwe WebDriverWait (stuurprogramma, timeOuts); wait.until(ExpectedConditions.visibilityOfElementLocated(element)); } public void enterTextIntoElement (Per element, String textToBeEntered) { driver.findElement (element).sendKeys (textToBeEntered); } public String getText(Per element) { return driver.findElement(element).getText(); } public String getAttribute (Per element, String attribuut) { return driver.findElement (element).getAttribute (attribuut); } public boolean isSelected(By element) {boolean isElementSelected = false; if (driver.findElement(element).isSelected() == true) { isElementSelected = true; } retour isElementSelected; } public void clearField(Per element) { driver.findElement(element).clear(); } public void implicitlyWait(int timeOuts) { driver.manage().timeouts().implicitlyWait(timeOuts, TimeUnit.SECONDS); } public boolean isElementPresent (per element) { probeer { driver.findElement (element); retourneer waar; } catch (Uitzondering e) { return false; } } public void switchToTab(int indexOfTab) {ArrayList tabs = nieuwe ArrayList (stuurprogramma.getWindowHandles()); driver.switchTo().window(tabs.get(indexOfTab)); } }

Page Module hulpprogramma's-Page Object Model Framework

Zoals we weten, moeten we de klasse Page maken en de paginafuncties in de paginamethoden behouden, dus laten we nu de paginamodule voor het Page Object Model-framework maken: 

Elke paginaklasse opnieuw breidt de WebAction Utils uit die we zojuist hebben ontwikkeld implementeert de pagina-interfaces, waar de pagina-interfaces niets anders zijn dan de interfaces om de respectieve webelementen / locators van de pagina te behouden.

Waarom hebben we interfaces nodig om de locators op te slaan: 

Daarom hebben we afzonderlijke interfaces gebruikt om afzonderlijke pagina-locators op te slaan zoals bij deze benadering; we lossen alle bovenstaande probleemstellingen op, die tijdcomplexiteit, ruimtecomplexiteit en de schone en onderhoudbare codebase zijn, zoals in interfaces, we hoeven geen objecten te maken om toegang te krijgen tot locators.

pakket com.base.pageModules; import java.util.Lijst; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; importeer com.base.commonUtils.JSonHandler; import com.base.webActionHelperUtils.WebActionsHelperUtils; importeer com.page.locatorModules.HomePageLocators; public class HomePage breidt WebActionsHelperUtils uit implementeert HomePageLocators { JSonHandler jsonHandler = new JSonHandler(); openbare HomePage (WebDriver-stuurprogramma) { super (stuurprogramma); dit.stuurprogramma = stuurprogramma; } public void enterSearchdataToSearchField (String searchData) { waitForElementToBeClickAble (SEARCH_BOX, 10); enterTextIntoElement (SEARCH_BOX, zoekgegevens); } public void navigatToUrl() { driver.get(url); } public void captureSearchSuggestion (String pathToJsonDataStore, String searchData) { Lijst elementen = getElements(SUGGESTION_BOX); jsonHandler.captureAndWriteJsonData(elementen, pathToJsonDataStore, searchData); } public void genericWait(int timeOuts) {implicitlyWait(timeOuts); } public void clikcOnSelectedElement (String-optie) { int optionSelection = Integer.parseInt (optie); safeClick(By.xpath("//div[@id='s-separator']/following-sibling::div[" + optionSelection + "]")); } }

Op dezelfde manier kunt u de paginafuncties op de pagina blijven opnemen met verschillende paginamethoden binnen de respectieve paginaklassen. 

Hier is hoe de Interfaces voor paginazoekers ziet eruit als : 

pakket com.page.locatorModules; import org.openqa.selenium.By; openbare interface HomePageLocators { Door SEARCH_BOX=By.id("twoabsearchtextbox"); Door SUGGESTION_BOX=By.xpath("//div[@id='suggesties']/div"); }

Nu het volgende segment, kunt u een baseSetUp of Basetest maken waar u de initialisatie / gegevenslaadparts wilt uitvoeren. Je zou ook kunnen gebruiken @beforeTest, @beofeClass methoden in deze klasse zelf en gebruik ze in uw testlessen.

Basisinstellingen Klasse ziet eruit als: 

pakket com.demo.testS;
importeer org.openqa.selenium.WebDriver;
importeer org.testng.annotations.DataProvider;
importeer com.base.dataUtils.DataHelperProvider;
importeer com.base.dataUtils.IDataProvider;
importeer com.base.driverUtils.DriverProvider;
openbare klasse BaseSetUp {
\tpublic WebDriver-stuurprogramma;
\tDriverProvider browserProvider = nieuwe DriverProvider();
\tDataHelperProvider datahelperProvider = nieuwe DataHelperProvider();
\tIDataProvider dataProvider = datahelperProvider.getDataHelperProvider("eigenschappen");
\tIDataProvider dataProviderExcel = datahelperProvider.getDataHelperProvider("excel");
\tpublic final String configProperties = "..\\\\DummyAutomation\\\\TestConfigsData\\\\config.properties";
\tpublic String url = dataProvider.fetchData(configProperties, "url");
\tString modeOfExecution = dataProvider.fetchData(configProperties, "modeOfExecution");
\tString browserName = dataProvider.fetchData(configProperties, "browser");
\tString pathToJasonDataStore = "..\\\\DummyAutomation\\\\ProductJsonData\\\\";
\tString pathToExcelData = "..\\\\DummyAutomation\\\\TestConfigsData\\\\TestData.xlsx";
\tpublic WebDriver getDriver() {
\t\treturn-stuurprogramma;
\T}
\tprotected void setDriver() {
\t\tdriver = browserProvider.getDriver(modeOfExecution).init(browsernaam);
\T}
\t@DataProvider(naam = "Zoekfunctionaliteit")
\tpublic object[][] getCityDetails() {
\t\tObject[][] arrayObject = dataProviderExcel.fetchDataSet(padNaarExcelData, "DataFeed");
\t\treturn arrayObject;
\T}
}

Testlessen: Omdat we hier TestNG zouden gebruiken, moet u de @test-methode schrijven om het testscript te ontwikkelen, zoals: 

Hier is het codefragment voor de testklassen  

pakket com.demo.testS; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; importeer com.base.pageModules.HomePage; import com.base.pageModules.SearchPage; openbare klasse DemoTest breidt BaseSetUp uit { HomePage homePage; Zoekpagina zoekpagina; @BeforeMethod public void setUpTest() { setDriver(); homePage = nieuwe HomePage (stuurprogramma); searchPage = nieuwe SearchPage (stuurprogramma); homePage.navigatToUrl(); } @Test(dataProvider = "SearchFunctionality") public void search (String searchData, String selectOption) { homePage.enterSearchdataToSearchField(searchData); homePage.genericWait(5); homePage.captureSearchSuggestion(pathToJasonDataStore, searchData); homePage.clickcOnSelectedElement(selectOption); searchPage.clickOnFirstProduct(); searchPage.switchToProductSpecificPage(); searchPage.captureProductData(pathToJasonDataStore, searchData); } @AfterMethod public void tearDown() { if (driver != null) { driver.quit(); } } }

TestNgXML-bestand -Page Object Model Framework

U zou een XML-klasse moeten definiëren voor de testng.xml, die in feite een unit-testraamwerk is en de stroom van uw automatisering regelt; je kunt daar zelf de testklassen noemen.







Dus met deze activiteiten, uw basis Pagina-objectmodel framework zou nu klaar moeten zijn. Als u de geavanceerde versie van uw framework wilt bereiken, kunt u deze onderstaande gebieden opnemen: 

Rapportage Feature-Page Object Model Framework

U kunt elke beschikbare rapportagefunctie gebruiken, zoals allure, omvangrapport, TestNG-rapport of voorafgaande rapportage met ELK-stapel, enz. 

Om de eenvoud te behouden, laten we hier de rapportagefunctie zien met het Extent-rapport, dat vele functies heeft en kan worden beschouwd als een tussenliggend rapportageniveau. 

U moet een klasse bouwen om de hulpprogramma's te hebben om met het Extent-rapport te werken, en terwijl u dit doet, moet u de interface ITestlistener van TestNg; de onderstaande code laat zien hoe: 

package com.cyborg.core.generic.reportUtils;
import com.aventstack.extentreports.ExtentReports;
import com.aventstack.extentreports.ExtentTest;
import com.aventstack.extentreports.Status;
import com.aventstack.extentreports.reporter.ExtentHtmlReporter;
import com.cyborg.core.generic.dataUtils.PropertiesDataUtils;
import io.appium.java_client.android.AndroidDriver;
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.remote.Augmenter;
import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestResult;
import org.testng.Reporter;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
public class ExtentReportUtils implements ITestListener {
  String screenShotPath = "";
  static ExtentReports extentReports;
  ExtentHtmlReporter extentHtmlReporter;
  protected ExtentTest extentTest;
  static String pathOfFile = "./configurator.properties";
  PropertiesDataUtils propertiesDataUtils = PropertiesDataUtils.getInstance(pathOfFile);
   Boolean log_to_kibana=Boolean.parseBoolean(PropertiesDataUtils.configDataStore.get("log_to_kibana"));
 
   public void setup() {
     try {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
        Date now = new Date();
        String currentTime = simpleDateFormat.format(now);
        extentHtmlReporter = new ExtentHtmlReporter(
              new File(System.getProperty("user.dir") + "_Reports_" + currentTime + ".html"));
        extentHtmlReporter.loadXMLConfig(
              new File(System.getProperty("user.dir") + "/src/test/resources/config/extent-config.xml"));
        extentReports = new ExtentReports();
        extentReports.setSystemInfo("Environment", PropertiesDataUtils.configDataStore.get("Environment"));
        extentReports.setSystemInfo("AppName", PropertiesDataUtils.configDataStore.get("AppName"));
        extentReports.setSystemInfo("ModeOfExecution", PropertiesDataUtils.configDataStore.get("modeOfExecution"));
        extentReports.attachReporter(extentHtmlReporter);
        System.out.println("DONE SETUP FOR extent Report");
     } catch (Exception ex) {
        ex.printStackTrace();
     }
  }
  public void setup(String reportName) {
     extentReports = getExtent(reportName);
  }
  public ExtentReports getExtent(String reportName) {
     if (extentReports != null)
        return extentReports; // avoid creating new instance of html file
     extentReports = new ExtentReports();
     extentReports.attachReporter(getHtmlReporter(reportName));
     return extentReports;
  }
  private ExtentHtmlReporter getHtmlReporter(String reportName) {
     extentHtmlReporter = new ExtentHtmlReporter("./reports/" + reportName + ".html");
     extentHtmlReporter.loadXMLConfig("./src/test/resources/config/extent-config.xml");
     // make the charts visible on report open
     extentHtmlReporter.config().setChartVisibilityOnOpen(true);
     extentHtmlReporter.config().setDocumentTitle(PropertiesDataUtils.configDataStore.get("AppName"));
     extentHtmlReporter.config().setReportName("Regression Cycle");
     // Append the existing report
     extentHtmlReporter.setAppendExisting(false);
     Locale.setDefault(Locale.ENGLISH);
     return extentHtmlReporter;
  }
  public void registerTestMethod(Method method) {
     String testName = method.getName();
     extentTest = extentReports.createTest(testName);
  }
  public void sequenceScreenShot(AndroidDriver driver, String application, String step) {
     try {
        extentTest.addScreenCaptureFromPath(screenshotStepWise(driver, application, step));
     } catch (Exception e) {
        e.printStackTrace();
     }
  }
  public void screenshotAnyCase(ITestResult result, WebDriver driver, String application) {
     String testName = result.getName();
     File file = new File(".");
     String filename = testName + ".png";
     String filepath = null;
     try {
        filepath = file.getCanonicalPath() + "/ScreenShots/" + application + "/" + putLogDate() + filename;
     } catch (IOException e1) {
        e1.printStackTrace();
     }
     if (PropertiesDataUtils.configDataStore.get("run_on_jenkins").equalsIgnoreCase("true"))
        screenShotPath = "job/Cyborg2/" + PropertiesDataUtils.configDataStore.get("build_number")
              + "/artifact/ScreenShots/" + application + "/" + putLogDate() + filename;
     else
        screenShotPath = System.getProperty("user.dir") + "/ScreenShots/" + application + "/" + putLogDate()
              + filename;
     try {
        WebDriver augmentedDriver = new Augmenter().augment(driver);
        File screenshotFile = ((TakesScreenshot) augmentedDriver).getScreenshotAs(OutputType.FILE);
        FileUtils.copyFile(screenshotFile, new File(filepath));
        File reportFile = new File(filepath);
        reportLogScreenshot(reportFile, filename, application);
     } catch (Exception e) {
        Reporter.log("Unable to get the screenshot");
     }
  }
  public String screenshotStepWise(WebDriver driver, String application, String step) throws Exception {
     File file = new File(".");
     String filename = step + ".png";
     String filepath = null;
     try {
        filepath = file.getCanonicalPath() + "/ScreenShots/" + application + "/" + putLogDateWithoutmm() + filename;
     } catch (IOException e1) {
        e1.printStackTrace();
     }
     if (PropertiesDataUtils.configDataStore.get("run_on_jenkins").equalsIgnoreCase("true"))
        screenShotPath = "job/Cyborg2/" + PropertiesDataUtils.configDataStore.get("build_number")
              + "/artifact/ScreenShots/" + application + "/" + putLogDateWithoutmm() + filename;
     else
        screenShotPath = System.getProperty("user.dir") + "/ScreenShots/" + application + "/"
              + putLogDateWithoutmm() + filename;
     try {
        WebDriver augmentedDriver = new Augmenter().augment(driver);
        File screenshotFile = ((TakesScreenshot) augmentedDriver).getScreenshotAs(OutputType.FILE);
        FileUtils.copyFile(screenshotFile, new File(filepath));
     } catch (Exception e) {
        Reporter.log("Unable to get the screenshot");
     }
     return screenShotPath;
  }
  protected void reportLogScreenshot(File file, String fileName, String application) {
     System.setProperty("org.uncommons.reportng.escape-output", "false");
     String absolute = file.getAbsolutePath();
     if (PropertiesDataUtils.configDataStore.get("run_on_jenkins").equalsIgnoreCase("true"))
        absolute = " /job/Cyborg2/" + PropertiesDataUtils.configDataStore.get("build_number")
              + "/artifact/ScreenShots/" + application + "/" + putLogDate() + fileName;
     else
        absolute = System.getProperty("user.dir") + "/ScreenShots/" + application + "/" + putLogDate() + fileName;
     screenShotPath = absolute;
  }
  public void captureStatus(ITestResult result) {
     if (result.getStatus() == ITestResult.SUCCESS) {
        extentTest.log(Status.PASS, "The test method Named as :" + result.getName() + " is PASSED");
        try {
           extentTest.addScreenCaptureFromPath(screenShotPath);
        } catch (IOException e) {
           e.printStackTrace();
        }
     } else if (result.getStatus() == ITestResult.FAILURE) {
        extentTest.log(Status.FAIL, "The test method Named as :" + result.getName() + " is FAILED");
        extentTest.log(Status.FAIL, "The failure : " + result.getThrowable());
        extentTest.log(Status.FAIL, "StackTrace: " + result.getThrowable());
        try {
           extentTest.addScreenCaptureFromPath(screenShotPath);
        } catch (IOException e) {
           e.printStackTrace();
        }
     } else if (result.getStatus() == ITestResult.SKIP) {
        extentTest.log(Status.SKIP, "The test method Named as :" + result.getName() + " is SKIPPED");
     }
  }
  public String putLogDate() {
     Calendar c = new GregorianCalendar();
     c.add(Calendar.DATE, +0);
     Date s = c.getTime();
     String dateString = new SimpleDateFormat("_EEE_ddMMMyyyy_hhmm").format(s);
     return dateString;
  }
  public String putLogDateWithoutmm() {
     Calendar c = new GregorianCalendar();
     c.add(Calendar.DATE, +0);
     Date s = c.getTime();
     String dateString = new SimpleDateFormat("_EEE_ddMMMyyyy_hh").format(s);
     return dateString;
  }
  public void cleanup() {
     extentReports.flush();
  }
  public void onTestStart(ITestResult result) {
     /*
      * try { DateFormat dateFormat = new SimpleDateFormat("yy-MM-dd HH-mm-ss"); Date
      * date = new Date();
      */
     /*
      * record = new ATUTestRecorder(System.getProperty("user.dir")+"/videos",
      * dateFormat.format(date), false); record.start();
      *//*
         *
         * } catch (ATUTestRecorderException e) { e.printStackTrace(); }
         */
  }
  public void onTestSuccess(ITestResult result) {
     /*
      * try { record.stop(); } catch (Exception e) { e.printStackTrace(); }
      */
     String testDescription = result.getMethod().getDescription();
     String testCaseNumber = testDescription.split("_")[0];
     String testDesc = testDescription.split("_")[1];
     String status = "PASSED";
     String exceptionType = "NA";
     String detailedError = "NA";
    
     String data ="{\
" +
           "   \\"testCaseNumber\\" : \\""+testCaseNumber+"\\",\
" +
           "   \\"status\\" : \\""+status+"\\",\
" +
           "   \\"testDescription\\" : \\""+testDesc+"\\",\
" +
           "   \\"exceptionType\\" : \\""+exceptionType+"\\",\
" +
           "   \\"detailedError\\":\\""+detailedError+"\\"\
" +
           "   \
" +
           "}";
     
  }
  @Override
  public void onTestFailure(ITestResult result) {
    
     String testDescription = result.getMethod().getDescription();
     String testCaseNumber = testDescription.split("_")[0];
     String testDesc = testCaseNumber.split("_")[1];
     String status = "FAILED";
     String exceptionType = String.valueOf(result.getThrowable().getClass().getSimpleName());
     String detailedError = String.valueOf(result.getThrowable().getMessage());
    
     String data ="{\
" +
           "   \\"testCaseNumber\\" : \\""+testCaseNumber+"\\",\
" +
           "   \\"status\\" : \\""+status+"\\",\
" +
           "   \\"testDescription\\" : \\""+testDesc+"\\",\
" +
           "   \\"exceptionType\\" : \\""+exceptionType+"\\",\
" +
           "   \\"detailedError\\":\\""+detailedError+"\\"\
" +
           "   \
" +
           "}";
    
     // TODO Auto-generated method stub
  }
  @Override
  public void onTestSkipped(ITestResult result) {
     String testDescription = result.getMethod().getDescription();
     String testCaseNumber = testDescription.split("_")[0];
     String testDesc = testCaseNumber.split("_")[1];
     String status = "SKIPPED";
     String exceptionType = result.getThrowable().getClass().getSimpleName();
     String detailedError = result.getThrowable().getMessage();
    
     String data ="{\
" +
           "   \\"testCaseNumber\\" : \\""+testCaseNumber+"\\",\
" +
           "   \\"status\\" : \\""+status+"\\",\
" +
           "   \\"testDescription\\" : \\""+testDesc+"\\",\
" +
           "   \\"exceptionType\\" : \\""+exceptionType+"\\",\
" +
           "   \\"detailedError\\":\\""+detailedError+"\\"\
" +
           "   \
" +
           "}";
  }
  @Override
  public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
     // TODO Auto-generated method stub
  }
  @Override
  public void onStart(ITestContext context) {
     // TODO Auto-generated method stub
  }
  @Override
  public void onFinish(ITestContext context) {
     // TODO Auto-generated method stub
  }
}

Conclusie: Hiermee sluiten we de ontwikkeling van het Selenium Page Object Model-raamwerk af waarmee u kunt beginnen met het bouwen van het Page Object-modelraamwerk en het naar een geavanceerd niveau kunt brengen, in de komende serie van de tutorial zullen we meer bespreken over de geavanceerde functies van het Selenium-raamwerk . Om de reeks van Selenium-tutorial die je hier kunt doorlopen.

Laat een bericht achter