Πλήρες πλαίσιο αντικειμένου σελίδας -2021

Σε αυτό το σεμινάριο, θα μάθουμε για το μοντέλο αντικειμένου σελίδας και επίσης θα σχεδιάσουμε και θα αναπτύξουμε το πλαίσιο του μοντέλου αντικειμένου σελίδας από την αρχή. 

Είχαμε συζητήσει όλα τα τύποι πλαισίων στο Σελήνιο, συμπεριλαμβανομένου του μοντέλου αντικειμένου σελίδας , εδώ θα περάσαμε σε βάθος.

Θα σχεδιάσουμε και θα αναπτύξουμε τις παρακάτω δυνατότητες.

Τι είναι το σχέδιο πλαισίου αντικειμένου σελίδας στο Σελήνιο  

Μοντέλο αντικειμένου σελίδας είναι ένα μοντέλο σχεδίασης για τη δημιουργία Αυτοματισμού δοκιμής Selenium, όπου διανέμουμε ολόκληρη την υπό δοκιμή Εφαρμογή μας σε μικρές σελίδες (μερικές φορές μια ιστοσελίδα θεωρείται ως σελίδα και μερικές φορές ένα υποτμήμα μιας Ιστοσελίδας θεωρείται επίσης ως Σελίδα ). Κάθε μία από αυτές τις σελίδες αναπαρίσταται ως κλάση Java και οι λειτουργίες των σελίδων γράφονται ως διαφορετικές μέθοδοι στην κλάση Java της αντίστοιχης σελίδας.

Ας υποθέσουμε ότι έχετε μια εφαρμογή Gmail την οποία θα αυτοματοποιήσετε. Ως εκ τούτου, η σελίδα σύνδεσης του Gmail είναι εκεί όπου έχετε λίγες σημαντικές λειτουργίες όπως σύνδεση, δημιουργία λογαριασμού κ.λπ.

Εδώ θα δημιουργήσουμε μια τάξη java ως GmailLoginPage και θα γράψουμε μεθόδους που ονομάζονται performLogin (), createUserAccount κ.λπ. 

Ας υποθέσουμε ότι μόλις συνδεθείτε στο λογαριασμό σας στο Gmail, έχετε πολλές δυνατότητες όπως εισερχόμενα, αντικείμενα αποστολής, κάδο απορριμμάτων κ.λπ. Τώρα εδώ, για κάθε ενότητα, δημιουργείτε μια τάξη Java και διατηρείτε τις λειτουργίες τους ως μεθόδους Java εντός των αντίστοιχων κλάσεων java. 

Γιατί μοντέλο αντικειμένου σελίδας

Το Page Object Model είναι ένα πολύ στιβαρό και προηγμένο μοντέλο σχεδιασμού πλαισίου όπου μπορείτε να φροντίσετε τις παρακάτω περιοχές: 

Δομή πλαισίου υβριδικού αντικειμένου σελίδας

Στο προηγούμενο σεμινάριο, καταλάβαμε το υβριδικό μοντέλο αντικειμένου σελίδας, και τώρα θα σχεδιάσουμε και θα αναπτύξουμε ένα πλαίσιο.

Η αρχιτεκτονική του πλαισίου μοντέλου αντικειμένου σελίδας

Μπορούμε απλά να δημιουργήσουμε ένα έργο maven και να ενσωματώσουμε τις εξαρτήσεις στο αρχείο POM.xml που απαιτείται για το πλαίσιο αρχικά που μοιάζει με αυτό: 

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

Μετά από αυτό, θα δημιουργήσουμε μικρές ενότητες και βοηθητικά προγράμματα, όπου έχουμε επισυνάψει αυτό το στιγμιότυπο παρακάτω για να παρέχουμε υψηλού επιπέδου πληροφορίες / προβολή. Θα φτιάξουμε βοηθητικά προγράμματα ένα προς ένα. 

Πλαίσιο μοντέλου αντικειμένου σελίδας σεληνίου Structure

Ακολουθούν οι παρακάτω ενότητες που θα αναπτύξουμε. παρέχουμε το απόσπασμα κώδικα για το ίδιο: 

DriverUtils - Πλαίσιο μοντέλου αντικειμένου σελίδας

Αυτή η ενότητα παρέχει όλα τα βοηθητικά προγράμματα και την υποστήριξη για εργασία με τα διάφορα προγράμματα περιήγησης (Chrome, Firefox, κ.λπ.). Αυτό το βοηθητικό πρόγραμμα βασίζεται στο Factory μοτίβο σχεδίασης, όπως συζητήσαμε στο προηγούμενο σεμινάριο εδώ.

πακέτο com.base.driverUtils; εισαγωγή org.openqa.selenium.WebDriver; δημόσια διεπαφή IDriver { public WebDriver init(String browserName); }

Υλοποίηση τοπικού προγράμματος οδήγησης, η οποία θα εκτελεστεί τοπικά με Σελήνιο Webdriver :

πακέτο com.base.driverUtils; εισαγωγή org.openqa.selenium.WebDriver; εισαγωγή org.openqa.selenium.chrome.ChromeDriver; εισαγωγή org.openqa.selenium.firefox.FirefoxDriver; εισαγωγή org.openqa.selenium.ie.InternetExplorerDriver; public class Το LocalDriver υλοποιεί IDriver { public WebDriver init(String browserName) { switch (browserName) { case "firefox": return new FirefoxDriver(); case "chrome": System.setProperty("webdriver.chrome.driver", "..\\DummyAutomation\\DriverExe\\chromedriver.exe"); επιστροφή νέου ChromeDriver(); case "ie": System.setProperty("webdriver.ie.driver", "..\\DummyAutomation\\DriverExe\\IEDriverServer.exe"); επιστροφή νέου InternetExplorerDriver(); προεπιλογή: επιστροφή νέου FirefoxDriver(); } }

Remote Webdriver: Για να εργαστείτε με ένα απομακρυσμένο πρόγραμμα οδήγησης ιστού (όπως το Selenium Grid), χρειάζεστε μια απομακρυσμένη αναφορά του προγράμματος οδήγησης προγράμματος περιήγησης, η οποία έχει ως εξής: 

πακέτο com.base.driverUtils; εισαγωγή java.net.MalformedURLException; εισαγωγή java.net.URL; εισαγωγή org.openqa.selenium.WebDriver; εισαγωγή org.openqa.selenium.remote.DesiredCapabilities; εισαγωγή org.openqa.selenium.remote.RemoteWebDriver; public class RemoteDriver υλοποιεί 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 Auto-generated catch block e2.printStackTrace(); } case "chrome": try { return new RemoteWebDriver(new URL(remoteHuburl), caps.chrome()); } catch (MalformedURLException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } case "ie": try { return new RemoteWebDriver(new URL(remoteHuburl), caps.internetExplorer()); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } προεπιλογή: δοκιμάστε { return new RemoteWebDriver(new URL(remoteHuburl), caps.firefox()); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return null; } }

Κατηγορία οδηγού εργοστασίου: Αυτό μας παρέχει αντικείμενο κλάσης προγράμματος οδήγησης (απομακρυσμένο / τοπικό) για να ξεκινήσουμε τα προγράμματα περιήγησης της επιλογής σας. Θα πάρουμε τον τύπο προγράμματος οδήγησης (τοπικό ή απομακρυσμένο) και το πρόγραμμα περιήγησης (chrome ή firefox κ.λπ.) μέσω του αρχείου διαμόρφωσης (έχουμε χρησιμοποιήσει ένα αρχείο ιδιοτήτων για να διατηρήσουμε τις διαμορφώσεις, τις οποίες θα κοινοποιήσουμε σύντομα)

πακέτο com.base.driverUtils; public class DriverProvider { public IDriver getDriver(String typeOfDriverExecution){ switch(typeOfDriverExecution){ case "local": return new LocalDriver(); περίπτωση "Remote": επιστροφή νέου RemoteDriver(); προεπιλογή: επιστροφή νέου LocalDriver(); } }

Τώρα όπου θέλετε την αναφορά προγράμματος οδήγησης, μπορείτε απλώς να δημιουργήσετε το αντικείμενο του αντικειμένου της εργοστασιακής κατηγορίας (DriverProvider σε αυτήν την περίπτωση) και να ξεκινήσετε την παρουσία προγράμματος περιήγησης προγράμματος οδήγησης.

Εδώ είναι το πολύ βασικό αρχείο ρυθμίσεων. μπορείτε να δημιουργήσετε ένα αρχείο ιδιοτήτων και να αποθηκεύσετε τις τιμές ως εξής: 

modeOfExecution=τοπικό πρόγραμμα περιήγησης=chrome url=http://www.applicationUrl.com/

DataUtils-Page Object Model Model Framework: 

Έχουμε σχεδιάσει τα βοηθητικά προγράμματα δεδομένων εδώ με το ίδιο πρότυπο εργοστασιακής σχεδίασης που κάναμε από την εφαρμογή των λειτουργικών μονάδων προγράμματος περιήγησης προγράμματος οδήγησης.

Ακολουθεί το παρακάτω απόσπασμα κώδικα για το ίδιο. στο πλαίσιο, δείξαμε εργαλεία Excel και εργαλεία ιδιοτήτων, μπορείτε να βελτιώσετε περισσότερο για να υποστηρίξετε άλλα βοηθητικά προγράμματα δεδομένων, όπως YAML, PDF κ.λπ. 

Η καλύτερη διεπαφή εδώ πηγαίνει έτσι: 

πακέτο com.base.dataUtils; δημόσια διεπαφή IDataProvider { public Object[][] fetchDataSet(String... dataFileInfo); public String fetchData(String... dataFileInfo); }

Εδώ είναι η εφαρμογή για Πάροχος δεδομένων Excel

πακέτο com.base.dataUtils; εισαγωγή java.io.File; εισαγωγή java.io.FileInputStream; εισαγωγή java.io.FileNotFoundException; εισαγωγή java.io.IOException; εισαγωγή org.apache.poi.xssf.usermodel.XSSFCell; εισαγωγή org.apache.poi.xssf.usermodel.XSSFSheet; εισαγωγή org.apache.poi.xssf.usermodel.XSSFWorkbook; δημόσια κλάση ExcelDataProvider υλοποιεί IDataProvider { FileInputStream fis = null; private static XSSFWorkbook WorkBook = null; ιδιωτικό στατικό κελί XSSFCell. ιδιωτικό στατικό φύλλο XSSFSheet. δημόσια στατική συμβολοσειρά[][] excelDataSet = null; @Override public Object[][] fetchDataSet(String... dataFileInfo) { String excelFilePath = dataFileInfo[0]; Συμβολοσειρά excelSheetName = dataFileInfo[1]; Αρχείο = νέο αρχείο (excelFilePath); δοκιμάστε { fis = new FileInputStream(file); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { workBook = new XSSFWorkbook(fis); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } sheet = workBook.getSheet(excelSheetName); int ci, cj; int rowCount = sheet.getLastRowNum(); int totalCols = sheet.getRow(0).getPhysicalNumberOfCells(); excelDataSet = νέα συμβολοσειρά[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 (Εξαίρεση e) { // TODO Αυτόματη δημιουργία μπλοκ catch e.printStackTrace(); } } } επιστροφή excelDataSet; } δημόσια στατική συμβολοσειρά getCellData(int RowNum, int ColNum) ρίχνει Εξαίρεση { 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(); επιστροφή Integer.toString(i); } else { String CellData = Cell.getStringCellValue(); επιστροφή CellData; } } catch (Exception e) { throw (e); } } @Override public String fetchData(String... dataFileInfo) { // TODO Αυτόματη δημιουργία στέλεχος μεθόδου επιστροφή null; } }

Πάροχος δεδομένων ιδιοτήτων: 

πακέτο com.base.dataUtils; εισαγωγή java.io.FileInputStream; εισαγωγή java.io.IOException; εισαγωγή java.util.Properties; δημόσια κλάση PropertiesDataProvider υλοποιεί IDataProvider { FileInputStream fis=null; @Override public Object[][] fetchDataSet(String... dataFileInfo) { // TODO Το στέλεχος μεθόδου που δημιουργήθηκε αυτόματα επιστρέφει null; } @Override public String fetchData(String... dataFileInfo) { String dataValue; String pathToFile = dataFileInfo[0]; Κλειδί συμβολοσειράς = dataFileInfo[1]; Ιδιότητες ιδιότητες = new Properties(); δοκιμάστε { fis=new FileInputStream(pathToFile); ιδιότητες.load(fis); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } dataValue = properties.getProperty(key); επιστροφή δεδομένωνΤιμής; } }

Η καλύτερη εργοστασιακή κλάση για αυτό το βοηθητικό πρόγραμμα δεδομένων

πακέτο com.base.dataUtils; public class DataHelperProvider { public IDataProvider getDataHelperProvider(String typeOfDataHandler) { switch (typeOfDataHandler) { case "excel": return new ExcelDataProvider(); περίπτωση "ιδιότητες": επιστροφή νέου PropertiesDataProvider(); } return null; } }

Βοηθητικά προγράμματα WebAction -Πλαίσιο μοντέλου αντικειμένου σελίδας

Στα βοηθητικά προγράμματα, γράφουμε όλα τα βοηθητικά προγράμματα που σχετίζονται με τις ενέργειές σας στο Web, όπως (κλικ, πλήκτρα αποστολής, στιγμιότυπα οθόνης κ.λπ.) και μπορούμε να το χρησιμοποιήσουμε στις Μέθοδοι σελίδας για την εκτέλεση ενεργειών ιστού για την επίτευξη των λειτουργιών της σελίδας, όπως συζητήθηκε νωρίτερα σε αυτό το σεμινάριο. 

Ακολουθεί το απόσπασμα κώδικα για τα WebAction Utilities: 

πακέτο com.base.webActionHelperUtils; εισαγωγή java.util.ArrayList; εισαγωγή java.util.List; εισαγωγή java.util.concurrent.TimeUnit; εισαγωγή org.openqa.selenium.By; εισαγωγή org.openqa.selenium.WebDriver; εισαγωγή org.openqa.selenium.WebElement; εισαγωγή org.openqa.selenium.support.ui.ExpectedConditions; εισαγωγή org.openqa.selenium.support.ui.WebDriverWait; δημόσια κλάση WebActionsHelperUtils { προστατευμένο πρόγραμμα οδήγησης WebDriver; public WebActionsHelperUtils(WebDriver driver) { this.driver = driver; } public void safeClick(By element) { waitForElementToBeClickAble(στοιχείο, 30); driver.findElement(element).click(); } δημόσια λίστα 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(στοιχείο)); } public void waitForElementToBeDisplayed(By element, int timeOuts) { WebDriverWait wait = new WebDriverWait(driver, timeOuts); wait.until(ExpectedConditions.visibilityOfElementLocated(στοιχείο)); } 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 χαρακτηριστικό) { return driver.findElement(element).getAttribute(attribute); } public boolean isSelected(By element) { boolean isElementSelected = false; if (driver.findElement(element).isSelected() == true) { isElementSelected = true; } επιστροφή 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); επιστροφή αληθινή? } catch (Exception e) { return false; } } public void switchToTab(int indexOfTab) { ArrayList καρτέλες = νέα ArrayList (driver.getWindowHandles()); driver.switchTo().window(tabs.get(indexOfTab)); } }

Utility Page Module-Page Object Model Framework

Όπως γνωρίζουμε, πρέπει να δημιουργήσουμε την κλάση σελίδας και να διατηρήσουμε τις λειτουργίες της σελίδας στις μεθόδους σελίδας, οπότε τώρα ας δημιουργήσουμε τη λειτουργική σελίδα σελίδας για το πλαίσιο σελίδας αντικειμένου σελίδας: 

Κάθε τάξη σελίδων ξανά επεκτείνει τα WebAction Utils που αναπτύξαμε μόλις τώρα και εφαρμόζει τις διεπαφές σελίδας, όπου οι διεπαφές σελίδας δεν είναι τίποτα άλλο από τις διεπαφές για τη διατήρηση των Στοιχείων / εντοπιστών Ιστού της αντίστοιχης σελίδας.

Τώρα γιατί χρειαζόμαστε διασυνδέσεις για την αποθήκευση των εντοπιστών: 

Ως εκ τούτου, χρησιμοποιήσαμε ξεχωριστές διεπαφές για ξεχωριστές εντοπιστές σελίδων για αποθήκευση όπως αυτή η προσέγγιση επιλύουμε όλες τις παραπάνω δηλώσεις προβλημάτων, που είναι η πολυπλοκότητα του χρόνου, η πολυπλοκότητα του χώρου και η καθαρή και διατηρήσιμη βάση κώδικα όπως στις διεπαφές, δεν χρειάζεται να δημιουργήσουμε αντικείμενα για πρόσβαση στους εντοπιστές.

πακέτο com.base.pageModules; εισαγωγή java.util.List; εισαγωγή org.openqa.selenium.By; εισαγωγή org.openqa.selenium.WebDriver; εισαγωγή org.openqa.selenium.WebElement; εισαγωγή com.base.commonUtils.JSonHandler; εισαγωγή com.base.webActionHelperUtils.WebActionsHelperUtils; εισαγωγή com.page.locatorModules.HomePageLocators; δημόσια τάξη Η αρχική σελίδα επεκτείνει το WebActionsHelperUtils υλοποιεί το HomePageLocators { JSonHandler jsonHandler = new JSonHandler(); public HomePage(WebDriver driver) { super(driver); this.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 στοιχεία = getElements(SUGGESTION_BOX); jsonHandler.captureAndWriteJsonData(στοιχεία, pathToJsonDataStore, searchData); } public void genericWait(int timeOuts) { implicitlyWait(timeOuts); } public void clikcOnSelectedElement(επιλογή συμβολοσειράς) { int optionSelection = Integer.parseInt(option); safeClick(By.xpath("//div[@id='s-separator']/following-sibling::div[" + optionSelection + "]")); } }

Ομοίως, μπορείτε να συνεχίσετε να συμπεριλαμβάνετε τις δυνατότητες σελίδας στη σελίδα διαφορετικές μεθόδους σελίδας εντός των αντίστοιχων κατηγοριών σελίδων. 

Εδώ είναι πώς το Διεπαφές εντοπιστών σελίδων μοιάζει : 

πακέτο com.page.locatorModules; εισαγωγή org.openqa.selenium.By; δημόσια διεπαφή HomePageLocators { By SEARCH_BOX=By.id("twotabsearchtextbox"); Από SUGGESTION_BOX=By.xpath("//div[@id='suggestions']/div"); }

Τώρα το επόμενο τμήμα, μπορείτε να δημιουργήσετε ένα baseSetUp ή Basetest όπου θέλετε να εκτελέσετε τα μέρη προετοιμασίας / φόρτωσης δεδομένων. Επίσης, θα μπορούσατε να χρησιμοποιήσετε @beforeTest, @beoforeClass μεθόδους σε αυτήν την τάξη και χρησιμοποιήστε τις στις δοκιμαστικές σας τάξεις.

Βασική ρύθμιση Η τάξη μοιάζει με: 

πακέτο com.demo.testS; εισαγωγή org.openqa.selenium.WebDriver; εισαγωγή org.testng.annotations.DataProvider; εισαγωγή com.base.dataUtils.DataHelperProvider; εισαγωγή com.base.dataUtils.IDataProvider; εισαγωγή com.base.driverUtils.DriverProvider; public class BaseSetUp { public WebDriver driver; DriverProvider browserProvider = new DriverProvider(); DataHelperProvider datahelperProvider = new DataHelperProvider(); IDataProvider dataProvider = datahelperProvider.getDataHelperProvider("ιδιότητες"); IDataProvider dataProviderExcel = datahelperProvider.getDataHelperProvider("excel"); δημόσια τελική συμβολοσειρά configProperties = "..\\DummyAutomation\\TestConfigsData\\config.properties"; public String 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() { return driver; } προστατευμένο void setDriver() { driver = browserProvider.getDriver(modeOfExecution).init(browserName); } @DataProvider(name = "SearchFunctionality") public Object[][] getCityDetails() { Object[][] arrayObject = dataProviderExcel.fetchDataSet(pathToExcelData, "DataFeed"); επιστροφή arrayObject; } }

Μαθήματα δοκιμής: Όπως θα χρησιμοποιούσαμε το TestNG εδώ, οπότε πρέπει να γράψετε τη μέθοδο @test για την ανάπτυξη του δοκιμαστικού σεναρίου, όπως: 

Ακολουθεί το απόσπασμα κώδικα για τις δοκιμαστικές τάξεις  

πακέτο com.demo.testS; εισαγωγή org.testng.annotations.AfterMethod; εισαγωγή org.testng.annotations.BeforeMethod; εισαγωγή org.testng.annotations.Test; εισαγωγή com.base.pageModules.HomePage; εισαγωγή com.base.pageModules.SearchPage; δημόσια τάξη DemoTest επεκτείνει BaseSetUp { Αρχική Σελίδα Αρχική Σελίδα; Αναζήτηση Σελίδας Αναζήτηση Σελίδα; @BeforeMethod public void setUpTest() { setDriver(); αρχική σελίδα = νέα αρχική σελίδα(πρόγραμμα οδήγησης); SearchPage = νέα SearchPage(πρόγραμμα οδήγησης); homePage.navigatToUrl(); } @Test(dataProvider = "SearchFunctionality") δημόσια κενή αναζήτηση (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 - Πλαίσιο μοντέλου αντικειμένου σελίδας

Θα χρειαστεί να ορίσετε μια κλάση XML για το testng.xml, το οποίο βασικά είναι ένα πλαίσιο δοκιμής μονάδας και ελέγχει τη ροή του αυτοματισμού σας. μπορείτε να αναφέρετε τα μαθήματα δοκιμών εκεί.







Έτσι, με αυτές τις δραστηριότητες, το βασικό σας Μοντέλο αντικειμένου σελίδας πλαίσιο πρέπει να είναι έτοιμο τώρα. Εάν θέλετε να επιτύχετε την προηγμένη έκδοση του πλαισίου σας, τότε θα μπορούσατε να ενσωματώσετε τις παρακάτω περιοχές: 

Πλαίσιο μοντέλου αντικειμένου αναφοράς σελίδας αναφοράς

Μπορείτε να χρησιμοποιήσετε οποιαδήποτε διαθέσιμη δυνατότητα αναφοράς, όπως γοητεία, έκταση έκθεσης, έκθεση TestNG ή εκθέσεις εκ των προτέρων χρησιμοποιώντας ELK στοίβα, και ούτω καθεξής 

Για να διατηρήσουμε την απλότητα, παρουσιάζουμε εδώ τη δυνατότητα αναφοράς με την αναφορά Extent, η οποία διαθέτει πολλές δυνατότητες μαζί της και μπορεί να θεωρηθεί ως ενδιάμεσο επίπεδο αναφοράς. 

Πρέπει να δημιουργήσετε μια τάξη για να έχετε τα βοηθητικά προγράμματα για να εργαστείτε με την έκθεση Extent και, ενώ το κάνετε αυτό, πρέπει να εφαρμόσετε το διεπαφή ITestlistener από TestNg; Ο παρακάτω κώδικας δείχνει πώς: 

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

Συμπέρασμα: Με αυτό ολοκληρώνουμε την ανάπτυξη πλαισίου μοντέλου Σελίδας αντικειμένου Σελενίου μέσω της οποίας μπορείτε να ξεκινήσετε τη δημιουργία του πλαισίου μοντέλου Σελίδας Αντικειμένου και να το φτάσετε στο προχωρημένο επίπεδο, στην επερχόμενη σειρά του σεμιναρίου θα συζητήσουμε περισσότερα σχετικά με τα προηγμένα χαρακτηριστικά του πλαισίου Σελήνιο . Για να περάσετε από τη σειρά του Σεμινάριο σεμινάριο μπορείτε να διαβάσετε εδώ.

Αφήστε ένα σχόλιο

Η διεύθυνση email σας δεν θα δημοσιευθεί. Τα υποχρεωτικά πεδία σημειώνονται *

Μεταβείτε στην κορυφή