Marco completo del modelo de objetos de página -2021

En este tutorial, aprenderemos sobre el modelo de objetos de página y también diseñaremos y desarrollaremos el marco del modelo de objetos de página desde cero. 

Habíamos discutido todos los tipos de marco en Selenium, incluido el modelo de objetos de página , aquí lo analizaríamos en profundidad.

Diseñaremos y desarrollaremos las siguientes características.

¿Qué es el diseño de Page Object Model Framework en Selenium?  

Modelo de objeto de página es un modelo de diseño para construir la automatización de pruebas de Selenium, donde distribuimos toda nuestra aplicación bajo prueba en páginas pequeñas (a veces, una página web se considera como una página y, a veces, una subparte de una página web también se considera como una página). Cada una de estas páginas se representa como una clase de Java, y las funcionalidades de las páginas se escriben como diferentes métodos en la clase de Java de la página respectiva.

Digamos que tiene una aplicación de Gmail que va a automatizar; por lo tanto, la página de inicio de sesión de Gmail es donde tiene algunas funcionalidades importantes, como iniciar sesión, crear una cuenta, etc.

Aquí crearemos una clase java como GmailLoginPage, y escribiremos métodos denominados performLogin (), createUserAccount, etc. 

Digamos que una vez que ha iniciado sesión en su cuenta de Gmail, tiene muchas características como bandeja de entrada, elementos enviados, papelera, etc. Ahora aquí, para cada módulo, crea una clase Java y mantiene sus funcionalidades como métodos Java dentro de las respectivas clases Java. 

Por qué el modelo de objetos de página

Page Object Model es un modelo de diseño de marco muy sólido y avanzado en el que puede encargarse de las siguientes áreas: 

Estructura del marco del modelo de objetos de página híbrida

En tutorial anterior, entendimos el modelo de objeto de página híbrido, y ahora diseñaremos y desarrollaremos un marco.

La arquitectura del marco del modelo de objetos de página

Simplemente podemos crear un proyecto maven e incorporar las dependencias en el archivo POM.xml que se requiere para el marco inicialmente que se ve así: 

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

Después de eso, crearemos pequeños módulos y utilidades, donde adjuntamos esta instantánea a continuación solo para proporcionar información / vista de alto nivel. Construiremos los servicios públicos uno por uno. 

Aquí están los siguientes módulos que desarrollaremos; hemos proporcionado el fragmento de código para el mismo: 

DriverUtils - Marco del modelo de objetos de página

Este módulo proporciona todas las utilidades y soporte para trabajar con los distintos navegadores (Chrome, Firefox, etc.). Esta utilidad se basa en Factory patrón de diseño, como discutimos en el tutorial anterior aquí.

paquete com.base.driverUtils; importar org.openqa.selenium.WebDriver; interfaz pública IDriver { public WebDriver init(String browserName); }

Implementación de Localdriver, que se ejecutará localmente con Selenium Webdriver :

paquete com.base.driverUtils;
importar org.openqa.selenium.WebDriver;
importar org.openqa.selenium.chrome.ChromeDriver;
importar org.openqa.selenium.firefox.FirefoxDriver;
importar org.openqa.selenium.ie.InternetExplorerDriver;
clase pública LocalDriver implementa IDriver {
  init público WebDriver (cadena nombre del navegador) {
     cambiar (nombre del navegador) {
     caso "firefox":
        devolver nuevo FirefoxDriver();
     caso "cromo":
        System.setProperty("webdriver.chrome.driver",
              "..\\\\DummyAutomation\\\\DriverExe\\\\chromedriver.exe");
        devolver nuevo ChromeDriver();
     caso "es decir":
        System.setProperty("webdriver.es.driver",
              "..\\\\DummyAutomation\\\\DriverExe\\\\IEDriverServer.exe");
        devolver nuevo InternetExplorerDriver();
     por defecto:
        devolver nuevo FirefoxDriver();
     }
  }
}

Controlador web remoto: para trabajar con un controlador web remoto (como Selenium Grid), necesita una referencia remota del controlador del navegador, que dice lo siguiente: 

paquete com.base.driverUtils; importar java.net.MalformedURLException; importar java.net.URL; importar org.openqa.selenium.WebDriver; importar org.openqa.selenium.remote.DesiredCapabilities; importar org.openqa.selenium.remote.RemoteWebDriver; clase pública RemoteDriver implementa IDriver { DesiredCapabilities caps; Cadena remoteHuburl; @Override public WebDriver init(String browserName) { switch (browserName) { case "firefox": try { return new RemoteWebDriver(nueva URL(remoteHuburl), caps.firefox()); } catch (MalformedURLException e2) { // TODO Bloque catch generado automáticamente e2.printStackTrace(); } case "chrome": pruebe { return new RemoteWebDriver(nueva URL(remoteHuburl), caps.chrome()); } catch (MalformedURLException e1) { // TODO Bloque catch generado automáticamente e1.printStackTrace(); } caso "es decir": intente { devuelva nuevo RemoteWebDriver (nueva URL (remoteHuburl), caps.internetExplorer ()); } catch (MalformedURLException e) { // TODO Bloque catch generado automáticamente e.printStackTrace(); } predeterminado: pruebe { devuelva el nuevo RemoteWebDriver(nueva URL(remoteHuburl), caps.firefox()); } catch (MalformedURLException e) { // TODO Bloque catch generado automáticamente e.printStackTrace(); } } devuelve nulo; } }

Clase de controlador de fábrica: Esto nos proporciona el objeto de clase de controlador (remoto / local) para iniciar los navegadores de su elección. Tomaremos el tipo de controlador (local o remoto) y navegador (chrome o firefox etc.) a través del archivo de configuración (hemos usado un archivo de propiedades para mantener las configuraciones, que compartiremos en breve)

paquete com.base.driverUtils; Clase pública DriverProvider { public IDriver getDriver(String typeOfDriverExecution){ switch(typeOfDriverExecution){ case "local": return new LocalDriver(); case "remoto": devuelve nuevo RemoteDriver(); predeterminado: devuelve nuevo LocalDriver(); } } }

Ahora, siempre que necesite la referencia del controlador, simplemente puede crear el objeto del objeto de clase de fábrica (DriverProvider en este caso) y puede iniciar la instancia del navegador del controlador.

Aquí está el archivo de configuración muy básico; puede crear un archivo de propiedades y almacenar los valores como este: 

modeOfExecution=navegador local=chrome url=http://www.applicationUrl.com/

Marco del modelo de objetos de DataUtils-Page: 

Hemos diseñado las utilidades de datos aquí con el mismo patrón de diseño de fábrica que hicimos al implementar los módulos del navegador del controlador.

Aquí está el siguiente fragmento de código para el mismo; en el marco, hemos mostrado utilidades de Excel y utilidades de propiedades, puede mejorar más para admitir otras utilidades de datos como YAML, PDF, etc .: 

La interfaz. aquí va así: 

paquete com.base.dataUtils; interfaz pública IDataProvider { Public Object[][] fetchDataSet(String... dataFileInfo); public String fetchData(String... dataFileInfo); }

Aquí está la implementación para Proveedor de datos de Excel

paquete com.base.dataUtils; importar java.io.Archivo; importar java.io.FileInputStream; importar java.io.FileNotFoundException; importar java.io.IOException; importar org.apache.poi.xssf.usermodel.XSSFCell; importar org.apache.poi.xssf.usermodel.XSSFSheet; importar org.apache.poi.xssf.usermodel.XSSFWorkbook; clase pública ExcelDataProvider implementa IDataProvider { FileInputStream fis = null; libro de trabajo XSSFWorkbook estático privado = nulo; Celda XSSFCell estática privada; hoja XSSFSheet estática privada; public static String[][] excelDataSet = null; @Override public Object[][] fetchDataSet(String... dataFileInfo) { String excelFilePath = dataFileInfo[0]; String excelSheetName = dataFileInfo[1]; Archivo archivo = nuevo archivo (excelFilePath); prueba { fis = new FileInputStream(archivo); } catch (FileNotFoundException e) { // TODO Bloque catch generado automáticamente e.printStackTrace(); } intente { libro de trabajo = new XSSFWorkbook (fis); } catch (IOException e) { // TODO Bloque catch generado automáticamente e.printStackTrace(); } hoja = workBook.getSheet(excelSheetName); intci, cj; int filaCuenta = hoja.getLastRowNum(); int totalCols = hoja.getRow(0).getPhysicalNumberOfCells(); excelDataSet = new String[rowCount][totalCols - 1]; ci = 0; for (int i = 1; i <= número de filas; i++, ci++) { cj = 0; for (int j = 1; j <= totalCols - 1; j++, cj++) { try { excelDataSet[ci][cj] = getCellData(i, j); } catch (Exception e) { // TODO Bloque catch generado automáticamente e.printStackTrace(); } } } devuelve excelDataSet; } public static String getCellData(int RowNum, int ColNum) throws Exception { try { Cell = sheet.getRow(RowNum).getCell(ColNum); int dataType = Cell.getCellType(); si (tipo de datos == 3) { retorno ""; } else if (tipo de datos == XSSFCell.CELL_TYPE_NUMERIC) { int i = (int) Cell.getNumericCellValue(); devuelve Integer.toString(i); } más { String CellData = Cell.getStringCellValue(); devolver datos de celda; } } atrapar (Excepción e) { lanzar (e); } } @Override public String fetchData(String... dataFileInfo) { // TODO Método generado automáticamente stub return null; } }

Proveedor de datos de propiedades: 

paquete com.base.dataUtils; importar java.io.FileInputStream; importar java.io.IOException; importar java.util.Properties; la clase pública PropertiesDataProvider implementa IDataProvider { FileInputStream fis=null; @Override public Object[][] fetchDataSet(String... dataFileInfo) { // TODO Método generado automáticamente stub return null; } @Override public String fetchData(String... dataFileInfo) { String dataValue; String pathToFile = dataFileInfo[0]; Clave de cadena = información del archivo de datos [1]; Propiedades propiedades = nuevas propiedades (); intente { fis = new FileInputStream (pathToFile); propiedades.load(fis); } catch (IOException e) { // TODO Bloque catch generado automáticamente e.printStackTrace(); } dataValue = propiedades.getProperty(clave); devolver valor de datos; } }

La clase de fábrica para estos datos Utilidades

paquete com.base.dataUtils; clase pública DataHelperProvider { public IDataProvider getDataHelperProvider(String typeOfDataHandler) { switch (typeOfDataHandler) { case "excel": return new ExcelDataProvider(); case "propiedades": devuelve nuevo PropertiesDataProvider(); } devuelve nulo; } }

Utilidades de WebAction -Marco del modelo de objetos de página

En las utilidades, escribimos todas las utilidades relacionadas con sus acciones web como (hacer clic, enviar claves, capturas de pantalla, etc.), y podemos utilizarlas en Métodos de página para realizar acciones web para lograr las funcionalidades de la página como se discutió anteriormente en este tutorial. 

Aquí está el fragmento de código para WebAction Utilities: 

paquete com.base.webActionHelperUtils; importar java.util.ArrayList; importar java.util.List; importar java.util.concurrent.TimeUnit; importar org.openqa.selenium.By; importar org.openqa.selenium.WebDriver; importar org.openqa.selenium.WebElement; importar org.openqa.selenium.support.ui.ExpectedConditions; importar org.openqa.selenium.support.ui.WebDriverWait; clase pública WebActionsHelperUtils { controlador WebDriver protegido; public WebActionsHelperUtils (controlador WebDriver) { this.driver = controlador; } public void safeClick(Por elemento) { waitForElementToBeClickAble(elemento, 30); conductor.findElement(elemento).click(); } Lista pública getElements(Por elementos) { return driver.findElements(elementos); } public void waitForWebElementsToBeDisplayed(Por elementos, int timeOuts) { WebDriverWait wait = new WebDriverWait(driver, timeOuts); wait.until(ExpectedConditions.visibilityOfAllElements(getElements(elements))); } public void waitForElementToBeClickAble(Por elemento, int timeOutSeconds) { WebDriverWait waitForElement = new WebDriverWait(driver, timeOutSeconds); waitForElement.until(ExpectedConditions.elementToBeClickable(element)); } public void waitForElementToBeDisplayed(Por elemento, int timeOuts) { WebDriverWait wait = new WebDriverWait(driver, timeOuts); wait.until(ExpectedConditions.visibilityOfElementLocated(elemento)); } public void enterTextIntoElement(Por elemento, String textToBeIntered) { driver.findElement(elemento).sendKeys(textToBeIntered); } public String getText(Por elemento) { return driver.findElement(elemento).getText(); } public String getAttribute(Por elemento, String atributo) { return driver.findElement(elemento).getAttribute(atributo); } public boolean isSelected(Por elemento) { boolean isElementSelected = false; if (controlador.findElement(elemento).isSelected() == true) { isElementSelected = true; } return isElementSelected; } public void clearField(Por elemento) { driver.findElement(elemento).clear(); } public void implícitalyWait(int timeOuts) { driver.manage().timeouts().implicitlyWait(timeOuts, TimeUnit.SECONDS); } public boolean isElementPresent(Por elemento) { try { driver.findElement(elemento); devolver verdadero; } catch (Excepción e) { return false; } } public void switchToTab(int indexOfTab) { ArrayList pestañas = nueva ArrayList (controlador.getWindowHandles()); driver.switchTo().window(tabs.get(indexOfTab)); } }

Page Module utilidades-Page Object Model Framework

Como sabemos, tenemos que crear la clase Page y mantener las funcionalidades de la página en los métodos de la página, así que ahora creemos el Módulo de página para el marco del Modelo de objetos de página: 

Cada clase de página de nuevo extiende las utilidades de WebAction que desarrollamos hace un momento y implementa las interfaces de la página, donde las interfaces de la página no son más que las interfaces para mantener los elementos web / localizadores de la página respectiva.

Ahora, ¿por qué necesitamos interfaces para almacenar los localizadores? 

Por lo tanto, usamos interfaces separadas para los localizadores de páginas separados para almacenar según este enfoque; resolvemos todas las declaraciones de problemas anteriores, que son la complejidad del tiempo, la complejidad del espacio y la base de código limpia y mantenible como en las interfaces, no tenemos que crear objetos para acceder a los localizadores.

paquete com.base.pageModules; importar java.util.List; importar org.openqa.selenium.By; importar org.openqa.selenium.WebDriver; importar org.openqa.selenium.WebElement; importar com.base.commonUtils.JSonHandler; importar com.base.webActionHelperUtils.WebActionsHelperUtils; importar com.page.locatorModules.HomePageLocators; HomePage de clase pública extiende WebActionsHelperUtils implementa HomePageLocators { JSonHandler jsonHandler = new JSonHandler(); página de inicio pública (controlador WebDriver) { super (controlador); este.controlador = controlador; } 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) { Lista elementos = getElements(SUGGESTION_BOX); jsonHandler.captureAndWriteJsonData(elements, pathToJsonDataStore, searchData); } public void genericWait(int timeOuts) { implícitalyWait(timeOuts); } public void clikcOnSelectedElement(String option) { int optionSelection = Integer.parseInt(option); safeClick(By.xpath("//div[@id='s-separator']/siguiente-hermano::div[" + optionSelection + "]")); } }

Asimismo, puede seguir incluyendo las características de la página en los diferentes métodos de página de la página dentro de las respectivas clases de página. 

Así es como el Interfaces de localizadores de página parece : 

paquete com.page.locatorModules; importar org.openqa.selenium.By; interfaz pública HomePageLocators { By SEARCH_BOX=By.id("twotabsearchtextbox"); Por SUGGESTION_BOX=By.xpath("//div[@id='suggestions']/div"); }

Ahora, el siguiente segmento, puede crear un baseSetUp o Basetest donde desea realizar las partes de inicialización / carga de datos. Además, podrías usar @antes de la prueba, @ antes de la clase métodos en esta clase y utilícelos en sus clases de prueba.

Configuración básica La clase se ve así: 

paquete com.demo.testS;
importar org.openqa.selenium.WebDriver;
importar org.testng.annotations.DataProvider;
importar com.base.dataUtils.DataHelperProvider;
importar com.base.dataUtils.IDataProvider;
importar com.base.driverUtils.DriverProvider;
clase pública BaseSetUp {
\tcontrolador WebDriver público;
\tDriverProvider browserProvider = nuevo DriverProvider();
\tDataHelperProvider datahelperProvider = nuevo DataHelperProvider();
\tIDataProvider dataProvider = datahelperProvider.getDataHelperProvider("propiedades");
\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, "navegador");
\tString pathToJasonDataStore = "..\\\\DummyAutomation\\\\ProductJsonData\\\\";
\tString pathToExcelData = "..\\\\DummyAutomation\\\\TestConfigsData\\\\TestData.xlsx";
\tpublic WebDriver getDriver() {
\t\regresar conductor;
\t}
\tprotected void setDriver() {
\t\tdriver = browserProvider.getDriver(modeOfExecution).init(browserName);
\t}
\t@DataProvider(nombre = "Funcionalidad de búsqueda")
\tobjeto público[][] getCityDetails() {
\t\tObject[][] arrayObject = dataProviderExcel.fetchDataSet(pathToExcelData, "DataFeed");
\t\treturn arrayObject;
\t}
}

Clases de prueba: Como estaríamos usando TestNG aquí, debe escribir el método @test para que se desarrolle el script de prueba, como: 

Aquí está el fragmento de código para las clases de prueba  

paquete com.demo.testS; importar org.testng.anotaciones.AfterMethod; importar org.testng.annotations.BeforeMethod; importar org.testng.annotations.Test; importar com.base.pageModules.HomePage; importar com.base.pageModules.SearchPage; clase pública DemoTest extiende BaseSetUp { HomePage homePage; Página de búsqueda página de búsqueda; @BeforeMethod public void setUpTest() { setDriver(); página de inicio = nueva página de inicio (controlador); página de búsqueda = nueva página de búsqueda (controlador); página de inicio.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(); } } }

Archivo TestNgXML -Marco del modelo de objetos de página

Necesitaría definir una clase XML para testng.xml, que básicamente es un marco de prueba unitario y controla el flujo de su automatización; puedes mencionar las clases de prueba allí mismas.







Entonces, con estas actividades, su Modelo de objeto de página marco debería estar listo ahora. Si desea lograr la versión avanzada de su marco, puede incorporar estas áreas a continuación: 

Marco del modelo de objetos de la página de funciones de informes

Puede utilizar cualquier función de informes disponible como atractivo, informe de extensión, informe de TestNG o informe avanzado mediante el uso Pila ELK, etc. 

Solo para mantener la simplicidad, mostramos aquí la función de informes con el informe de extensión, que tiene muchas características y se puede considerar como un nivel intermedio de informes. 

Debe crear una clase para que las utilidades funcionen con el informe de extensión, y mientras lo hace, debe implementar el interfaz ITestlistener de TestNg; el siguiente código muestra cómo: 

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

conclusión: Con esto estamos concluyendo el desarrollo del marco del modelo de objeto de página de Selenium a través del cual puede comenzar a construir el marco del modelo de objeto de página y puede llevarlo al nivel avanzado, en la próxima serie del tutorial discutiremos más sobre las características avanzadas del marco de Selenium . Para pasar por la serie de Tutorial de selenio que puede seguir aquí.

Deja un comentario