Quadro completo del modello a oggetti della pagina -2021

In questo tutorial impareremo a conoscere il Page Object Model e inoltre progetteremo e svilupperemo il framework Page Object Model da zero. 

Avevamo discusso di tutti i file tipi di framework in Selenium, incluso il Page Object Model , qui vorremmo approfondire.

Progetteremo e svilupperemo le seguenti funzionalità.

Che cos'è il design del framework del modello di oggetti di pagina in Selenium  

Modello a oggetti della pagina è un modello di progettazione per la creazione di Selenium test Automation, in cui distribuiamo l'intera applicazione sottoposta a test in piccole pagine (a volte una pagina Web è considerata come una pagina e talvolta anche una sottoparte di una pagina Web è considerata una Pagina). Ognuna di queste pagine è rappresentata come una classe Java e le funzionalità delle pagine sono scritte come metodi diversi nella rispettiva classe Java della pagina.

Supponiamo che tu abbia un'applicazione Gmail che automatizzerai; quindi la pagina di accesso di Gmail è lì dove hai poche funzionalità importanti come l'accesso, la creazione di un account, ecc.

Qui creeremo una classe java come GmailLoginPage e scriveremo metodi denominati performLogin (), createUserAccount, ecc. 

Diciamo che una volta effettuato l'accesso al tuo account Gmail, hai molte funzionalità come posta in arrivo, elementi inviati, cestino, ecc. Ora qui, per ogni modulo, crei una classe Java e mantieni le loro funzionalità come metodi Java all'interno delle rispettive classi java. 

Perché il modello a oggetti della pagina

Page Object Model è un modello di progettazione framework molto robusto e avanzato in cui puoi occuparti delle aree seguenti: 

Struttura del framework del modello a oggetti della pagina ibrida

Nel tutorial precedente, abbiamo compreso il modello ibrido a oggetti di pagina, e ora progetteremo e svilupperemo un framework.

L'architettura del framework Page Object Model

Possiamo semplicemente creare un progetto maven e incorporare le dipendenze nel file POM.xml richiesto inizialmente per il framework che assomiglia a questo: 

<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>

Successivamente, costruiremo piccoli moduli e utilità, a cui abbiamo allegato questa istantanea di seguito solo per fornire approfondimenti / viste di alto livello. Costruiremo le utilità una per una. 

Ecco i moduli seguenti che svilupperemo; abbiamo fornito lo snippet di codice per lo stesso: 

DriverUtils - Framework del modello di oggetti della pagina

Questo modulo fornisce tutte le utilità e il supporto per lavorare con i vari browser (Chrome, Firefox, ecc.). Questa utilità è basata su Factory modelli di progettazione, come abbiamo discusso nel tutorial precedente qui.

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

Implementazione di Localdriver, che verrà eseguita localmente con Selenio Webdriver :

pacchetto com.base.driverUtils;
importare org.openqa.selenium.WebDriver;
importa org.openqa.selenium.chrome.ChromeDriver;
importa org.openqa.selenium.firefox.FirefoxDriver;
importare org.openqa.selenium.ie.InternetExplorerDriver;
la classe pubblica LocalDriver implementa IDriver {
  public WebDriver init(String nomebrowser) {
     cambia (nomebrowser) {
     caso "firefox":
        restituisce il nuovo FirefoxDriver();
     custodia "cromata":
        System.setProperty("webdriver.chrome.driver",
              "..\\\\DummyAutomation\\\\DriverExe\\\\chromedriver.exe");
        restituisce il nuovo ChromeDriver();
     caso "cioè":
        System.setProperty("webdriver.ie.driver",
              "..\\\\DummyAutomation\\\\DriverExe\\\\IEDriverServer.exe");
        restituisce il nuovo InternetExplorerDriver();
     predefinito:
        restituisce il nuovo FirefoxDriver();
     }
  }
}

Webdriver remoto: per lavorare con un webdriver remoto (come Selenium Grid), è necessario un riferimento remoto del driver del browser, che è simile a: 

pacchetto com.base.driverUtils; import java.net.MalformedURLException; importare java.net.URL; import org.openqa.selenium.WebDriver; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.remote.RemoteWebDriver; la classe pubblica RemoteDriver implementa IDriver { DesiredCapabilities caps; Stringa remotaHuburl; @Override public WebDriver init(String browserName) { switch (browserName) { case "firefox": try { return new RemoteWebDriver(new URL(remoteHuburl), caps.firefox()); } catch (MalformedURLException e2) { // TODO Blocco catch generato automaticamente e2.printStackTrace(); } case "chrome": try { return new RemoteWebDriver(new URL(remoteHuburl), caps.chrome()); } catch (MalformedURLException e1) { // TODO Blocco catch generato automaticamente e1.printStackTrace(); } case "ie": try { return new RemoteWebDriver(new URL(remoteHuburl), caps.internetExplorer()); } catch (MalformedURLException e) { // TODO Blocco catch generato automaticamente e.printStackTrace(); } predefinito: try { return new RemoteWebDriver(new URL(remoteHuburl), caps.firefox()); } catch (MalformedURLException e) { // TODO Blocco catch generato automaticamente e.printStackTrace(); } } restituisce null; } }

Classe Factory Driver: Questo ci fornisce l'oggetto della classe driver (remoto / locale) per avviare i browser di tua scelta. Prenderemo il tipo di driver (locale o remoto) e browser (chrome o firefox ecc.) Attraverso il file di configurazione (abbiamo utilizzato un file delle proprietà per mantenere le configurazioni, che condivideremo a breve)

pacchetto com.base.driverUtils; public class DriverProvider { public IDriver getDriver(String typeOfDriverExecution){ switch(typeOfDriverExecution){ case "local": return new LocalDriver(); case "remote": restituisce new RemoteDriver(); default : restituisce new LocalDriver(); } } }

Ora, ovunque sia necessario il riferimento al driver, è possibile creare semplicemente l'oggetto dell'oggetto della classe factory (DriverProvider in questo caso) e avviare l'istanza del browser del driver.

Ecco il file di configurazione di base; puoi creare un file delle proprietà e memorizzare i valori in questo modo: 

modeOfExecution=browser locale=URL di Chrome=http://www.applicationUrl.com/

Struttura del modello a oggetti DataUtils-Page: 

Abbiamo progettato le utilità di dati qui come lo stesso modello di progettazione Factory che abbiamo fatto dall'implementazione dei moduli del browser del driver.

Ecco lo snippet di codice seguente per lo stesso; nel framework, abbiamo mostrato le utilità di Excel e le utilità delle proprietà, puoi migliorare di più per supportare altre utilità di dati come YAML, PDF, ecc .: 

I interfaccia qui va così: 

pacchetto com.base.dataUtils; interfaccia pubblica IDataProvider { public Object[][] fetchDataSet(String... dataFileInfo); public String fetchData(String... dataFileInfo); }

Ecco l'implementazione per Fornitore di dati Excel

pacchetto com.base.dataUtils; importare java.io.File; importa java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import org.apache.poi.xssf.usermodel.XSSFCell; importare org.apache.poi.xssf.usermodel.XSFSSheet; importare org.apache.poi.xssf.usermodel.XSSFWorkbook; la classe pubblica ExcelDataProvider implementa IDataProvider { FileInputStream fis = null; cartella di lavoro XSSFWorkbook statica privata = null; cella XSSFCell statica privata; foglio XSSFSheet statico privato; public statico String[][] excelDataSet = null; @Override public Object[][] fetchDataSet(String... dataFileInfo) { String excelFilePath = dataFileInfo[0]; Stringa excelSheetName = dataFileInfo[1]; File file = nuovo File(excelFilePath); try {fis = new FileInputStream(file); } catch (FileNotFoundException e) { // TODO Blocco catch generato automaticamente e.printStackTrace(); } prova {workBook = new XSSFWorkbook(fis); } catch (IOException e) { // TODO Blocco catch generato automaticamente e.printStackTrace(); } foglio = workBook.getSheet(excelSheetName); int ci, cj; int rowCount = foglio.getLastRowNum(); int totalCols = sheet.getRow(0).getPhysicalNumberOfCells(); excelDataSet = new 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++) { try { excelDataSet[ci][cj] = getCellData(i, j); } catch (Eccezione e) { // TODO Blocco catch generato automaticamente e.printStackTrace(); } } } restituisce excelDataSet; } public static String getCellData(int RowNum, int ColNum) genera un'eccezione { try { Cell = sheet.getRow(RowNum).getCell(ColNum); int dataType = Cell.getCellType(); if (dataType == 3) { return ""; } else if (dataType == XSSFCell.CELL_TYPE_NUMERIC) { int i = (int) Cell.getNumericCellValue(); restituisce Intero.toString(i); } else { String CellData = Cell.getStringCellValue(); restituire CellData; } } cattura (Eccezione e) { lancio (e); } } @Override public String fetchData(String... dataFileInfo) { // TODO stub del metodo generato automaticamente return null; } }

Proprietà fornitore di dati: 

pacchetto com.base.dataUtils; importa java.io.FileInputStream; import java.io.IOException; importare java.util.Proprietà; la classe pubblica PropertiesDataProvider implementa IDataProvider { FileInputStream fis=null; @Override public Object[][] fetchDataSet(String... dataFileInfo) { // TODO stub del metodo generato automaticamente return null; } @Override public String fetchData(String... dataFileInfo) { String dataValue; String pathToFile = dataFileInfo[0]; Chiave stringa = dataFileInfo[1]; Proprietà proprietà = new Proprietà(); prova {fis=nuovo FileInputStream(percorsoFile); properties.load(fis); } catch (IOException e) { // TODO Blocco catch generato automaticamente e.printStackTrace(); } valoredati = properties.getProperty(chiave); restituire il valore dei dati; } }

I classe factory per queste utilità di dati

pacchetto com.base.dataUtils; public class DataHelperProvider { public IDataProvider getDataHelperProvider(String typeOfDataHandler) { switch (typeOfDataHandler) { case "excel": return new ExcelDataProvider(); case "proprietà": restituisce new PropertiesDataProvider(); } restituisce null; } }

Utilità WebAction -Pagina Object Model Framework

Nelle utility, scriviamo tutte le utility relative alle tue azioni Web come (clic, sendkeys, screenshot, ecc.) E possiamo utilizzarle in Page Methods per eseguire azioni web per ottenere le funzionalità della pagina come discusso in precedenza in questo tutorial. 

Ecco lo snippet di codice per le utilità WebAction: 

pacchetto com.base.webActionHelperUtils; importare java.util.ArrayList; importare java.util.List; importare 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; public class WebActionsHelperUtils { driver WebDriver protetto; public WebActionsHelperUtils (driver WebDriver) { this.driver = driver; } public void safeClick(Per elemento) { waitForElementToBeClickAble(elemento, 30); driver.findElement(elemento).click(); } Elenco pubblico getElements(Per elementi) { return driver.findElements(elementi); } public void waitForWebElementsToBeDisplayed(Per elementi, int timeOuts) { WebDriverWait wait = new WebDriverWait(driver, timeOuts); wait.until(ExpectedConditions.visibilityOfAllElements(getElements(elements))); } public void waitForElementToBeClickAble(Per elemento, int timeOutSeconds) { WebDriverWait waitForElement = new WebDriverWait(driver, timeOutSeconds); waitForElement.until(ExpectedConditions.elementToBeClickable(elemento)); } public void waitForElementToBeDisplayed(Per elemento, int timeOuts) { WebDriverWait wait = new WebDriverWait(driver, timeOuts); wait.until(ExpectedConditions.visibilityOfElementLocated(elemento)); } public void enterTextIntoElement(Per elemento, String textToBeEntered) { driver.findElement(element).sendKeys(textToBeEntered); } public String getText(Per elemento) { return driver.findElement(elemento).getText(); } public String getAttribute(Per elemento, attributo String) { return driver.findElement(elemento).getAttribute(attributo); } public boolean isSelected(Per elemento) { boolean isElementSelected = false; if (driver.findElement(elemento).isSelected() == true) { isElementSelected = true; } restituisce èElementSelected; } public void clearField(Per elemento) { driver.findElement(elemento).clear(); } public void implicitlyWait(int timeOuts) { driver.manage().timeouts().implicitlyWait(timeOuts, TimeUnit.SECONDS); } public boolean isElementPresent(Per elemento) { try { driver.findElement(elemento); restituisce vero; } catch (Eccezione e) { return false; } } public void switchToTab(int indexOfTab) { ArrayList schede = nuovo ArrayList (driver.getWindowHandles()); driver.switchTo().window(tabs.get(indexOfTab)); } }

Utilità del modulo di pagina-Framework del modello di oggetti della pagina

Come sappiamo, dobbiamo creare la classe Page e mantenere le funzionalità della pagina nei metodi della pagina, quindi ora creiamo il modulo della pagina per il framework del modello a oggetti della pagina: 

Di nuovo ogni Page Class estende gli strumenti WebAction che abbiamo sviluppato proprio ora e implementa le interfacce Page, dove le interfacce della pagina non sono altro che le interfacce per mantenere i rispettivi elementi / localizzatori web della pagina.

Ora perché abbiamo bisogno di interfacce per memorizzare i localizzatori: 

Quindi abbiamo usato interfacce separate per localizzatori di pagine separati da memorizzare come con questo approccio; risolviamo tutte le dichiarazioni di problemi di cui sopra, che sono complessità temporale, complessità spaziale e la base di codice pulita e manutenibile come nelle interfacce, non dobbiamo creare oggetti per accedere ai localizzatori.

pacchetto com.base.pageModules; importare java.util.List; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; importare com.base.commonUtils.JSonHandler; import com.base.webActionHelperUtils.WebActionsHelperUtils; import com.page.locatorModules.HomePageLocators; la classe pubblica HomePage estende WebActionsHelperUtils implementa HomePageLocators { JSonHandler jsonHandler = new JSonHandler(); home page pubblica (driver WebDriver) { super (driver); this.driver = driver; } public void enterSearchdataToSearchField(String searchData) { waitForElementToBeClickAble(SEARCH_BOX, 10); enterTextIntoElement(SEARCH_BOX, searchData); } public void navigatToUrl() { driver.get(url); } public void captureSearchSuggestion(String pathToJsonDataStore, String searchData) { List elementi = getElements(SUGGESTION_BOX); jsonHandler.captureAndWriteJsonData(elementi, pathToJsonDataStore, searchData); } public void genericWait(int timeOuts) { implicitlyWait(timeOuts); } public void clikcOnSelectedElement (opzione String) { int optionSelection = Integer.parseInt (opzione); safeClick(By.xpath("//div[@id='s-separator']/following-sibling::div[" + optionSelection + "]")); } }

Allo stesso modo, puoi continuare a includere le caratteristiche della pagina nella pagina diversi metodi di pagina all'interno delle rispettive classi di pagina. 

Ecco come Interfacce dei localizzatori di pagine assomigliare : 

pacchetto com.page.locatorModules; import org.openqa.selenium.By; interfaccia pubblica HomePageLocators { Per SEARCH_BOX=By.id("twotabsearchtextbox"); Per SUGGESTION_BOX=By.xpath("//div[@id='suggerimenti']/div"); }

Ora il segmento successivo, è possibile creare un baseSetUp o Basetest in cui si desidera eseguire le parti di inizializzazione / caricamento dati. Inoltre, potresti usare @beforeTest, @beoforeClass metodi in questa classe stessa e utilizzarli nelle classi di test.

Configurazione base La classe ha questo aspetto: 

pacchetto com.demo.testS;
importare org.openqa.selenium.WebDriver;
importare org.testng.annotations.DataProvider;
importa com.base.dataUtils.DataHelperProvider;
import com.base.dataUtils.IDataProvider;
importa com.base.driverUtils.DriverProvider;
classe pubblica BaseSetUp {
\tdriver pubblico WebDriver;
\tDriverProvider browserProvider = nuovo DriverProvider();
\tDataHelperProvider datahelperProvider = nuovo DataHelperProvider();
\tIDataProvider dataProvider = datahelperProvider.getDataHelperProvider("properties");
\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\tautista di ritorno;
\T}
\tprotetto void setDriver() {
\t\tdriver = browserProvider.getDriver(modeOfExecution).init(browserName);
\T}
\t@DataProvider(nome = "SearchFunctionality")
\tOggetto pubblico[][] getCityDetails() {
\t\tObject[][] arrayObject = dataProviderExcel.fetchDataSet(pathToExcelData, "DataFeed");
\t\treturn arrayObject;
\T}
}

Classi di prova: Poiché qui utilizzeremmo TestNG, è necessario scrivere il metodo @test per lo sviluppo dello script di test, ad esempio: 

Ecco lo snippet di codice per le classi di test  

pacchetto com.demo.testS; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import com.base.pageModules.HomePage; import com.base.pageModules.SearchPage; la classe pubblica DemoTest estende BaseSetUp { HomePage homePage; Pagina di ricerca Pagina di ricerca; @BeforeMethod public void setUpTest() { setDriver(); homePage = nuova HomePage(driver); searchPage = nuova SearchPage(driver); homePage.navigatToUrl(); } @Test(dataProvider = "SearchFunctionality") public void search(String searchData, String selectOption) { homePage.enterSearchdataToSearchField(searchData); homePage.genericWait(5); homePage.captureSearchSuggestion(pathToJasonDataStore, searchData); homePage.clikcOnSelectedElement(selectOption); searchPage.clickOnFirstProduct(); searchPage.switchToProductSpecificPage(); searchPage.captureProductData(pathToJasonDataStore, searchData); } @AfterMethod public void tearDown() { if (driver != null) { driver.quit(); } } }

File TestNgXML -Page Framework modello a oggetti

Dovresti definire una classe XML per testng.xml, che fondamentalmente è un framework di unit test e controlla il flusso della tua automazione; puoi menzionare le lezioni di prova lì stesse.







Quindi con queste attività, le tue basi Modello a oggetti della pagina framework dovrebbe essere pronto ora. Se vuoi ottenere la versione avanzata del tuo framework, puoi incorporare le seguenti aree: 

Reporting Feature-Page Object Model Framework

Puoi utilizzare qualsiasi funzione di segnalazione disponibile come allure, extentreport, report TestNG o report anticipati utilizzando Pila ELK, ecc. 

Solo per mantenere la semplicità, stiamo mostrando qui la funzione di reporting con Extent report, che ha molte funzionalità insieme e può essere considerato come un livello intermedio di reporting. 

Devi costruire una classe per avere le utilità per lavorare con il rapporto Extent e, mentre lo fai, devi implementare il interfaccia ITestlistener da TestNg; il codice seguente mostra come: 

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
  }
}

Conclusione: Con questo stiamo concludendo lo sviluppo del framework Selenium Page Object Model attraverso il quale è possibile iniziare a costruire il framework del modello Page Object e portarlo al livello avanzato, nella prossima serie del tutorial discuteremo di più sulle funzionalità avanzate del framework Selenium . Per passare attraverso la serie di Tutorial sul selenio che puoi seguire qui.

Lascia un tuo commento