In diesem Tutorial lernen wir das Seitenobjektmodell kennen und entwerfen und entwickeln das Seitenobjektmodell-Framework von Grund auf neu.
Wir hatten alle besprochen Arten von Frameworks in Selen, einschließlich Seitenobjektmodell Hier würden wir eingehend durchgehen.
Wir werden die folgenden Funktionen entwerfen und entwickeln.
Was ist das Design des Page Object Model Framework in Selen?
Seitenobjektmodell ist ein Entwurfsmodell zum Erstellen von Selenium-Testautomatisierung, bei dem wir unsere gesamte zu testende Anwendung auf kleine Seiten verteilen (manchmal wird eine Webseite als Seite betrachtet, und manchmal wird ein Teil einer Webseite auch als Seite betrachtet). Jede dieser Seiten wird als Java-Klasse dargestellt, und die Funktionalitäten der Seiten werden als unterschiedliche Methoden in der Java-Klasse der jeweiligen Seite geschrieben.
Angenommen, Sie haben eine Google Mail-Anwendung, die Sie automatisieren. Daher gibt es auf der Google Mail-Anmeldeseite nur wenige wichtige Funktionen wie Anmelden, Erstellen eines Kontos usw.
Hier erstellen wir eine Java-Klasse als GmailLoginPage und schreiben Methoden mit den Namen performLogin (), createUserAccount usw.
Angenommen, Sie sind in Ihrem Google Mail-Konto angemeldet und verfügen über zahlreiche Funktionen wie Posteingang, gesendete Elemente, Papierkorb usw. Hier erstellen Sie für jedes Modul eine Java-Klasse und behalten deren Funktionen als Java-Methoden in den jeweiligen Java-Klassen bei.
Warum Seitenobjektmodell?
Das Seitenobjektmodell ist ein sehr robustes und fortschrittliches Framework-Entwurfsmodell, in dem Sie sich um die folgenden Bereiche kümmern können:
Struktur des Hybrid-Seitenobjektmodell-Frameworks
In den Im vorherigen Tutorial haben wir das hybride Seitenobjektmodell verstanden. und jetzt werden wir ein Framework entwerfen und entwickeln.
Die Architektur des Page Object Model-Frameworks
Wir können einfach ein Maven-Projekt erstellen und die Abhängigkeiten in die POM.xml-Datei integrieren, die anfangs für das Framework erforderlich ist, das wie folgt aussieht:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>demo</groupId>
<artifactId>DemoAutomation</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>DemoAutomation</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>7</source>
<target>7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.4.2</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>testNg.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.reportyng</groupId>
<artifactId>reporty-ng</artifactId>
<version>1.2</version>
<configuration>
<outputdir>/target/testng-xslt-report</outputdir>
<sorttestcaselinks>true</sorttestcaselinks>
<testdetailsfilter>FAIL,SKIP,PASS,CONF,BY_CLASS</testdetailsfilter>
<showruntimetotals>true</showruntimetotals>
</configuration>
</plugin>
</plugins>
</reporting>
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-server</artifactId>
<version>2.53.0</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.8.1</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.8</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.8</version>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>net.sourceforge.jexcelapi</groupId>
<artifactId>jxl</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
</project>
Danach werden wir kleine Module und Dienstprogramme erstellen, in denen wir diesen Schnappschuss unten angehängt haben, um allgemeine Einblicke / Ansichten zu bieten. Wir werden nacheinander Dienstprogramme bauen.

Hier sind die folgenden Module, die wir entwickeln werden; Wir haben das Code-Snippet für dasselbe bereitgestellt:
DriverUtils - Page Object Model Framework
Dieses Modul bietet alle Dienstprogramme und Unterstützung für die Arbeit mit den verschiedenen Browsern (Chrome, Firefox usw.). Dieses Dienstprogramm basiert auf Factory Entwurfsmuster, wie wir im vorherigen Tutorial hier besprochen haben.
Paket com.base.driverUtils; import org.openqa.selenium.WebDriver; öffentliche Schnittstelle IDriver { öffentlicher WebDriver init (String browserName); }
Localdriver-Implementierung, die lokal mit ausgeführt wird Selenium-Webtreiber :
Paket com.base.driverUtils; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.ie.InternetExplorerDriver; public class LocalDriver implementiert IDriver { public WebDriver init(String browserName) { switch (browserName) { case "firefox": return new FirefoxDriver(); case "chrome": System.setProperty("webdriver.chrome.driver", "..\\DummyAutomation\\DriverExe\\chromedriver.exe"); return new ChromeDriver(); case "ie": System.setProperty("webdriver.ie.driver", "..\\DummyAutomation\\DriverExe\\IEDriverServer.exe"); return new InternetExplorerDriver(); Standard: neuer FirefoxDriver(); zurückgeben; } } }
Remote-Webdriver: Um mit einem Remote-Webdriver (z. B. Selenium Grid) arbeiten zu können, benötigen Sie eine Remote-Referenz des Browsertreibers.
Paket com.base.driverUtils; java.net.MalformedURLException importieren; java.net.URL importieren; import org.openqa.selenium.WebDriver; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.remote.RemoteWebDriver; öffentliche Klasse RemoteDriver implementiert IDriver { DesiredCapabilities caps; String remoteHuburl; @Override public WebDriver init(String browserName) { switch (browserName) { case "firefox": try { return new RemoteWebDriver(new URL(remoteHuburl), caps.firefox()); } catch (MalformedURLException e2) { // TODO Automatisch generierter Catch-Block e2.printStackTrace(); } case "chrome": try {return new RemoteWebDriver(new URL(remoteHuburl), caps.chrome()); } catch (MalformedURLException e1) { // TODO Automatisch generierter Catch-Block e1.printStackTrace(); } case "ie": try {return new RemoteWebDriver(new URL(remoteHuburl), caps.internetExplorer()); } catch (MalformedURLException e) { // TODO Automatisch generierter Catch-Block e.printStackTrace(); } default: try {return new RemoteWebDriver(new URL(remoteHuburl), caps.firefox()); } catch (MalformedURLException e) { // TODO Automatisch generierter Catch-Block e.printStackTrace(); } } Null zurückgeben; } }
Werksfahrerklasse: Dadurch erhalten wir das Treiberklassenobjekt (remote / lokal), mit dem Sie die Browser Ihrer Wahl starten können. Wir werden den Typ des Treibers (lokal oder remote) und des Browsers (Chrome oder Firefox usw.) durch die Konfigurationsdatei führen (wir haben eine Eigenschaftendatei verwendet, um die Konfigurationen beizubehalten, die wir in Kürze freigeben werden).
Paket com.base.driverUtils; public class DriverProvider { public IDriver getDriver(String typeOfDriverExecution){ switch(typeOfDriverExecution){ case "local": return new LocalDriver(); case "remote": return new RemoteDriver(); default : return new LocalDriver(); } } }
Wo immer Sie die Treiberreferenz benötigen, können Sie jetzt einfach das Objekt des Factory-Klassenobjekts (in diesem Fall DriverProvider) erstellen und die Treiberbrowser-Instanz initiieren.
Hier ist die sehr grundlegende Konfigurationsdatei; Sie können eine Eigenschaftendatei erstellen und die folgenden Werte speichern:
modeOfExecution=lokaler Browser=chrome url=http://www.applicationUrl.com/
DataUtils-Page-Objektmodell-Framework:
Wir haben die Datendienstprogramme hier nach dem gleichen Factory-Entwurfsmuster entworfen wie bei der Implementierung der Treiberbrowser-Module.
Hier ist das folgende Code-Snippet für dasselbe; Im Framework haben wir Excel-Dienstprogramme und Eigenschaften-Dienstprogramme gezeigt. Sie können weitere Verbesserungen vornehmen, um andere Daten-Dienstprogramme wie YAML, PDF usw. zu unterstützen.
Die Schnittstelle hier geht es so:
Paket com.base.dataUtils; öffentliche Schnittstelle IDataProvider {öffentliches Objekt[][] fetchDataSet(String... dataFileInfo); public String fetchData(String... dataFileInfo); }
Hier ist die Implementierung für Excel-Datenanbieter :
Paket com.base.dataUtils; java.io.File importieren; java.io.FileInputStream importieren; java.io.FileNotFoundException importieren; java.io.IOException importieren; import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; öffentliche Klasse ExcelDataProvider implementiert IDataProvider { FileInputStream fis = null; privates statisches XSSFWorkbook workBook = null; private statische XSSFCell-Zelle; privates statisches XSSFSheet-Blatt; öffentlicher statischer String[][] excelDataSet = null; @Override public Object[][] fetchDataSet(String... dataFileInfo) { String excelFilePath = dataFileInfo[0]; String excelSheetName = dataFileInfo[1]; Datei file = new File(excelFilePath); try {fis = new FileInputStream(file); } catch (FileNotFoundException e) { // TODO Automatisch generierter Catch-Block e.printStackTrace(); } try {workBook = new XSSFWorkbook(fis); } catch (IOException e) { // TODO Automatisch generierter Catch-Block e.printStackTrace(); } Blatt = workBook.getSheet (excelSheetName); int ci, cj; int rowCount = sheet.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 (Exception e) { // TODO Automatisch generierter Catch-Block e.printStackTrace(); } } } excelDataSet zurückgeben; } öffentlicher statischer String getCellData(int RowNum, int ColNum) löst Ausnahme aus { 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(); Rückgabe Integer.toString(i); } Sonst {String CellData = Cell.getStringCellValue(); CellData zurückgeben; } } catch (Ausnahme e) { throw (e); } } @Override public String fetchData(String... dataFileInfo) { // TODO Automatisch generierter Methodenstub return null; } }
Eigenschaften Datenprovider:
Paket com.base.dataUtils; java.io.FileInputStream importieren; java.io.IOException importieren; java.util.Properties importieren; öffentliche Klasse PropertiesDataProvider implementiert IDataProvider { FileInputStream fis=null; @Override public Object[][] fetchDataSet(String... dataFileInfo) { // TODO Automatisch generierter Methodenstub return null; } @Override public String fetchData(String... dataFileInfo) { String dataValue; String pathToFile = dataFileInfo[0]; Zeichenfolgenschlüssel = dataFileInfo[1]; Eigenschaften Eigenschaften = neue Eigenschaften (); try {fis=new FileInputStream(pathToFile); properties.load(fis); } catch (IOException e) { // TODO Automatisch generierter Catch-Block e.printStackTrace(); } dataValue = properties.getProperty(key); Datenwert zurückgeben; } }
Die Factory-Klasse für diese Daten Dienstprogramme :
Paket com.base.dataUtils; public class DataHelperProvider { public IDataProvider getDataHelperProvider(String typeOfDataHandler) { switch (typeOfDataHandler) { case "excel": return new ExcelDataProvider(); Fall "Eigenschaften": Rückgabe neuer PropertiesDataProvider(); } Null zurückgeben; } }
WebAction-Dienstprogramme -Seitenobjektmodell-Framework
In den Dienstprogrammen schreiben wir alle Dienstprogramme, die sich auf Ihre Webaktionen beziehen, wie (Klicken, Senden, Schlüssel, Screenshots usw.), und wir können sie in Seitenmethoden verwenden, um Webaktionen auszuführen, um die Seitenfunktionen zu erreichen, wie weiter oben in diesem Lernprogramm erläutert.
Hier ist das Code-Snippet für die WebAction-Dienstprogramme:
Paket com.base.webActionHelperUtils; java.util.ArrayList importieren; java.util.List importieren; 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; öffentliche Klasse WebActionsHelperUtils { geschützter WebDriver-Treiber; öffentliche WebActionsHelperUtils (WebDriver-Treiber) { this.driver = Treiber; } public void safeClick (By element) { WaitForElementToBeClickAble (element, 30); driver.findElement(element).click(); } öffentliche Liste getElements (By elements) { return driver.findElements (elements); } public void waitForWebElementsToBeDisplayed (By elements, int timeOuts) { WebDriverWait wait = new WebDriverWait (driver, timeOuts); wait.until(ExpectedConditions.visibilityOfAllElements(getElements(elements))); } public void waitForElementToBeClickAble(By element, int timeOutSeconds) { WebDriverWait waitForElement = new WebDriverWait(driver, timeOutSeconds); waitForElement.until(ExpectedConditions.elementToBeClickable(element)); } public void waitForElementToBeDisplayed(By element, int timeOuts) { WebDriverWait wait = new WebDriverWait(driver, timeOuts); wait.until(ExpectedConditions.visibilityOfElementLocated(element)); } public void enterTextIntoElement (By element, String textToBeEntered) {driver.findElement(element).sendKeys(textToBeEntered); } public String getText(By element) { return driver.findElement(element).getText(); } public String getAttribute(By element, String attribute) { return driver.findElement(element).getAttribute(attribute); } public boolean isSelected(By element) {boolean isElementSelected = false; if (driver.findElement(element).isSelected() == true) { isElementSelected = true; } Rückgabe isElementSelected; } public void clearField(By element) {driver.findElement(element).clear(); } public void implicitlyWait(int timeOuts) {driver.manage().timeouts().implicitlyWait(timeOuts, TimeUnit.SECONDS); } public boolean isElementPresent(By element) { try { driver.findElement(element); gib true zurück; } catch (Ausnahme e) { return false; } } public void switchToTab(int indexOfTab) { ArrayList Registerkarten = neue ArrayList (driver.getWindowHandles()); driver.switchTo().window(tabs.get(indexOfTab)); } }
Seitenmodul-Dienstprogramme - Page Object Model Framework
Wie wir wissen, müssen wir die Page-Klasse erstellen und die Seitenfunktionen in den Seitenmethoden beibehalten. Erstellen wir nun das Seitenmodul für das Seitenobjektmodell-Framework:
Wieder jede Seitenklasse erweitert die WebAction Utils dass wir gerade entwickelt haben und implementiert die Seitenschnittstellen, wobei die Seitenschnittstellen nichts anderes als die Schnittstellen sind, um die Webelemente / Locators der jeweiligen Seite zu behalten.
Warum wir Schnittstellen zum Speichern der Locators benötigen:
Daher haben wir separate Schnittstellen für separate Seiten-Locators verwendet, um diese nach diesem Ansatz zu speichern. Wir lösen alle oben genannten Problemstellungen, nämlich Zeitkomplexität, Raumkomplexität und die saubere und wartbare Codebasis, da wir keine Objekte erstellen müssen, um auf Locators zuzugreifen.
.
Paket com.base.pageModules; java.util.List importieren; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import com.base.commonUtils.JSonHandler; import com.base.webActionHelperUtils.WebActionsHelperUtils; import com.page.locatorModules.HomePageLocators; öffentliche Klasse HomePage erweitert WebActionsHelperUtils implementiert HomePageLocators { JSonHandler jsonHandler = new JSonHandler(); öffentliche Homepage (WebDriver-Treiber) { super (Treiber); this.driver = Fahrer; } 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 Elemente = getElements (SUGGESTION_BOX); jsonHandler.captureAndWriteJsonData (Elemente, pathToJsonDataStore, searchData); } public void genericWait(int timeOuts) { implicitlyWait(timeOuts); } public void clikcOnSelectedElement (String-Option) { int optionSelection = Integer.parseInt (Option); safeClick(By.xpath("//div[@id='s-separator']/following-sibling::div[" + optionSelection + "]")); } }
Ebenso können Sie die Seitenfunktionen weiterhin in die Seite verschiedener Seitenmethoden innerhalb der jeweiligen Seitenklassen aufnehmen.
Hier ist wie die Seitenlokalisierungsschnittstellen aussehen :
Paket com.page.locatorModules; import org.openqa.selenium.By; öffentliche Schnittstelle HomePageLocators {By SEARCH_BOX=By.id("twotabsearchtextbox"); By SUGGESTION_BOX=By.xpath("//div[@id='suggestions']/div"); }
Im nächsten Segment können Sie nun ein baseSetUp oder einen Basetest erstellen, in dem Sie die Initialisierungs- / Datenladeteile ausführen möchten. Auch könnten Sie verwenden @beforeTest, @beforeClass Methoden in dieser Klasse selbst und verwenden Sie sie in Ihren Testklassen.
BasisSetup Klasse sieht aus wie:
Paket com.demo.testS; import org.openqa.selenium.WebDriver; import org.testng.annotations.DataProvider; import com.base.dataUtils.DataHelperProvider; import com.base.dataUtils.IDataProvider; import com.base.driverUtils.DriverProvider; öffentliche Klasse BaseSetUp { öffentlicher WebDriver-Treiber; DriverProvider browserProvider = new DriverProvider(); DataHelperProvider datahelperProvider = new DataHelperProvider(); IDataProvider dataProvider = datahelperProvider.getDataHelperProvider("properties"); IDataProvider dataProviderExcel = datahelperProvider.getDataHelperProvider("excel"); public final String configProperties = "..\\DummyAutomation\\TestConfigsData\\config.properties"; öffentliche Zeichenfolge url = dataProvider.fetchData (configProperties, "url"); String modeOfExecution = dataProvider.fetchData(configProperties, "modeOfExecution"); String browserName = dataProvider.fetchData(configProperties, "browser"); String pathToJasonDataStore = "..\\DummyAutomation\\ProductJsonData\\"; String pathToExcelData = "..\\DummyAutomation\\TestConfigsData\\TestData.xlsx"; public WebDriver getDriver() { Treiber zurückgeben; } protected void setDriver() { Treiber = browserProvider.getDriver(modeOfExecution).init(browserName); } @DataProvider(name = "SearchFunctionality") public Object[][] getCityDetails() { Object[][] arrayObject = dataProviderExcel.fetchDataSet(pathToExcelData, "DataFeed"); arrayObject zurückgeben; } }
Testklassen: Da wir hier TestNG verwenden würden, müssen Sie die @ test-Methode für das zu entwickelnde Testskript schreiben, z. B.:
Hier ist das Code-Snippet für die Testklassen
Paket 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; öffentliche Klasse DemoTest erweitert BaseSetUp { HomePage homePage; Suchseite suchseite; @BeforeMethod public void setUpTest() { setDriver(); Homepage = neue Homepage (Treiber); searchPage = new SearchPage (Treiber); 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(); } } }
TestNgXML-Datei -Seitenobjektmodell-Framework
Sie müssten eine XML-Klasse für die Datei testng.xml definieren, die im Grunde ein Unit-Test-Framework ist und den Ablauf Ihrer Automatisierung steuert. Sie können die Testklassen dort selbst erwähnen.
Also mit diesen Aktivitäten, Ihre grundlegende Seitenobjektmodell Framework sollte jetzt fertig sein. Wenn Sie die erweiterte Version Ihres Frameworks erreichen möchten, können Sie die folgenden Bereiche einbeziehen:
Reporting Feature-Page Objektmodell-Framework
Sie können jede verfügbare Berichtsfunktion wie verwenden Allure, Extentreport, TestNG-Bericht oder Vorabberichterstattung durch die Nutzung ELK Stapel, usw.
Der Einfachheit halber zeigen wir hier die Berichtsfunktion mit dem Extent-Bericht, der viele Funktionen enthält und als Zwischenstufe der Berichterstellung betrachtet werden kann.
Sie müssen eine Klasse erstellen, damit die Dienstprogramme mit dem Extent-Bericht arbeiten können, und dabei müssen Sie den implementieren Schnittstelle ITestlistener von TestNg; Der folgende Code zeigt, wie:
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 ="{\n" + " \"testCaseNumber\" : \""+testCaseNumber+"\",\n" + " \"status\" : \""+status+"\",\n" + " \"testDescription\" : \""+testDesc+"\",\n" + " \"exceptionType\" : \""+exceptionType+"\",\n" + " \"detailedError\":\""+detailedError+"\"\n" + " \n" + "}"; } @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 ="{\n" + " \"testCaseNumber\" : \""+testCaseNumber+"\",\n" + " \"status\" : \""+status+"\",\n" + " \"testDescription\" : \""+testDesc+"\",\n" + " \"exceptionType\" : \""+exceptionType+"\",\n" + " \"detailedError\":\""+detailedError+"\"\n" + " \n" + "}"; // 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 ="{\n" + " \"testCaseNumber\" : \""+testCaseNumber+"\",\n" + " \"status\" : \""+status+"\",\n" + " \"testDescription\" : \""+testDesc+"\",\n" + " \"exceptionType\" : \""+exceptionType+"\",\n" + " \"detailedError\":\""+detailedError+"\"\n" + " \n" + "}"; } @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 } }
Fazit: Damit schließen wir die Entwicklung des Selenium Page Object Model-Frameworks ab, mit der Sie mit dem Aufbau des Page Object Model-Frameworks beginnen und es auf die fortgeschrittene Ebene bringen können. In der kommenden Reihe des Tutorials werden wir mehr über die erweiterten Funktionen des Selenium Frameworks diskutieren . Um die Reihe von durchzugehen Das Selenium-Tutorial können Sie hier durchgehen.