Cadre complet de modèle d'objet de page -2021

Dans ce didacticiel, nous en apprendrons davantage sur le modèle d'objet de page, et nous allons également concevoir et développer le cadre de modèle d'objet de page à partir de zéro. 

Nous avions discuté de tous les types de framework dans Selenium, y compris le modèle d'objet de page , ici nous passerions en revue en profondeur.

Framework de modèle d'objet de page
Développement d'un cadre de modèle d'objet de page

Nous concevrons et développerons les fonctionnalités ci-dessous.

Qu'est-ce que la conception du cadre de modèle d'objet de page dans Selenium  

Le modèle d'objet de page est un modèle de conception pour la construction de l'automatisation des tests Selenium, où nous distribuons l'ensemble de notre application testée en petites pages (parfois une page Web est considérée comme une page, et parfois une sous-partie d'une page Web est également considérée comme une page). Chacune de ces pages est représentée comme une classe Java, et les fonctionnalités des pages sont écrites comme différentes méthodes dans la classe Java de la page respective.

Disons que vous avez une application Gmail que vous automatiserez; par conséquent, la page de connexion Gmail est là où vous avez quelques fonctionnalités majeures telles que la connexion, la création d'un compte, etc.

Ici, nous allons créer une classe java en tant que GmailLoginPage, et nous écrirons des méthodes nommées performLogin (), createUserAccount, etc. 

Disons qu'une fois que vous êtes connecté à votre compte Gmail, vous disposez de nombreuses fonctionnalités comme la boîte de réception, les éléments envoyés, la corbeille, etc. Maintenant, ici, pour chaque module, vous créez une classe Java et conservez leurs fonctionnalités en tant que méthodes Java dans les classes Java respectives. 

Pourquoi le modèle d'objet de page

Page Object Model est un modèle de conception de framework très robuste et avancé dans lequel vous pouvez vous occuper des domaines ci-dessous: 

  • Sécurité de la base de code d'automatisation des pages Web (les fonctionnalités et le code de chaque page Web ne sont pas exposés à une autre page Web ou classe Java)
  • Réutilisable, c'est-à-dire que vous pouvez appeler la méthode de page respective sans l'écrire dans "N" nombre de places dans votre cadre.
  • Le localisateur de chacune des pages réside dans des emplacements différents (interfaces au niveau de la page ou en utilisant pagefactory, donc en cas de nouveaux localisateurs pour cette page ou de changement de localisateur, vous pouvez simplement aller dans la zone de localisateurs de page respective et le modifier, et il sera reflété dans les méthodes d'appel partout où les localisateurs sont appelés)
  • Débogage facile grâce aux fonctionnalités ci-dessus
  • Facilement maintenable.
  • Évolutif: vous pouvez intégrer un large éventail d'outils / clients avec votre cadre de modèle d'objet de page et améliorer et mettre à l'échelle votre cadre de modèle d'objet de page pour automatiser également les cas d'utilisation supercritiques. 

Structure du cadre du modèle d'objet de page hybride

Dans le tutoriel précédent, nous avons compris le modèle d'objet de page hybride, et maintenant nous allons concevoir et développer un cadre.

L'architecture du framework de modèle d'objet de page

Nous pouvons simplement créer un projet maven et incorporer les dépendances dans le fichier POM.xml requis pour le framework initialement qui ressemble à celui-ci: 

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

Après cela, nous créerons de petits modules et utilitaires, auxquels nous avons joint cet instantané ci-dessous juste pour fournir des informations / vues de haut niveau. Nous allons créer des utilitaires un par un. 

Structure du cadre du modèle d'objet de page Selenium

Voici les modules ci-dessous que nous développerons; nous avons fourni l'extrait de code pour le même: 

DriverUtils - Cadre de modèle d'objet de page

Ce module fournit tous les utilitaires et le support pour travailler avec les différents navigateurs (Chrome, Firefox, etc.). Cet utilitaire est basé sur le modèle de conception Factory, comme nous l'avons vu dans le tutoriel précédent ici.

package com.base.driverUtils;

import org.openqa.selenium.WebDriver;

public interface IDriver {

  public WebDriver init(String browserName);
}

Implémentation de Localdriver, qui s'exécutera localement avec Selenium Webdriver:

package 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 implements 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();
     default:
        return new FirefoxDriver();
     }
  }

}

Remote Webdriver: pour travailler avec un webdriver distant (tel que Selenium Grid), vous avez besoin d'une référence distante du pilote de navigateur, qui va comme: 

package com.base.driverUtils;

import java.net.MalformedURLException;
import java.net.URL;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;

public class RemoteDriver implements 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();
        }
     default:
        try {
           return new RemoteWebDriver(new URL(remoteHuburl), caps.firefox());
        } catch (MalformedURLException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
        }
     }
     return null;
  }
 

}

Classe de pilote d'usine: Cela nous fournit l'objet de classe de pilote (distant / local) pour lancer les navigateurs de votre choix. Nous prendrons le type de pilote (local ou distant) et de navigateur (chrome ou firefox etc.) via le fichier de configuration (nous avons utilisé un fichier de propriétés pour conserver les configurations, que nous partagerons prochainement)

package 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();
     }
  }
}

Désormais, partout où vous avez besoin de la référence du pilote, vous pouvez simplement créer l'objet de l'objet de classe d'usine (DriverProvider dans ce cas) et lancer l'instance de navigateur de pilote.

Voici le fichier de configuration très basique; vous pouvez créer un fichier de propriétés et stocker les valeurs comme ceci: 

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

Framework de modèle d'objet DataUtils-Page: 

Nous avons conçu les utilitaires de données ici comme le même modèle de conception d'usine que nous l'avons fait à partir de l'implémentation des modules de navigateur de pilotes.

Voici l'extrait de code ci-dessous pour le même; dans le cadre, nous avons montré des utilitaires Excel et des utilitaires de propriétés, vous pouvez améliorer davantage pour prendre en charge d'autres utilitaires de données tels que YAML, PDF, etc.: 

au jugement, interface voici comme ça: 

package com.base.dataUtils;

public interface IDataProvider {

  public Object[][] fetchDataSet(String... dataFileInfo);
  public String fetchData(String... dataFileInfo);
}

Voici la mise en œuvre pour Fournisseur de données Excel

package com.base.dataUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ExcelDataProvider implements IDataProvider {

  FileInputStream fis = null;
  private static XSSFWorkbook workBook = null;
  private static XSSFCell Cell;
  private static XSSFSheet sheet;

  public static String[][] excelDataSet = null;

  @Override
  public Object[][] fetchDataSet(String... dataFileInfo) {
     String excelFilePath = dataFileInfo[0];
     String excelSheetName = dataFileInfo[1];
     File file = new File(excelFilePath);

     try {
        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 = 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 Auto-generated catch block
              e.printStackTrace();
           }
        }
     }
     return excelDataSet;

  }

  public static String getCellData(int RowNum, int ColNum) throws Exception {

     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();
           return Integer.toString(i);
        }

        else {

           String CellData = Cell.getStringCellValue();

           return CellData;

        }
     } catch (Exception e) {

        throw (e);

     }

  }

  @Override
  public String fetchData(String... dataFileInfo) {
     // TODO Auto-generated method stub
     return null;
  }

}

Propriétés du fournisseur de données: 

package com.base.dataUtils;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

public class PropertiesDataProvider implements IDataProvider {

  FileInputStream fis=null;

  @Override
  public Object[][] fetchDataSet(String... dataFileInfo) {
     // TODO Auto-generated method stub
     return null;
  }

  @Override
  public String fetchData(String... dataFileInfo) {

     String dataValue;
     String pathToFile = dataFileInfo[0];
     String key = dataFileInfo[1];
     Properties properties = new Properties();
     try {
        fis=new FileInputStream(pathToFile);
        properties.load(fis);
     } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
     }
     dataValue = properties.getProperty(key);
     return dataValue;
  }

}

au jugement, classe d'usine pour ces utilitaires de données

package com.base.dataUtils;

public class DataHelperProvider {

  public IDataProvider getDataHelperProvider(String typeOfDataHandler) {
     switch (typeOfDataHandler) {
     case "excel":
        return new ExcelDataProvider();
     case "properties":
        return new PropertiesDataProvider();
     }
     return null;

  }
}

Utilitaires WebAction -Cadre de modèle d'objet de page

Dans les utilitaires, nous écrivons tous les utilitaires liés à vos actions Web comme (clic, touches d'envoi, captures d'écran, etc.), et nous pouvons les utiliser dans les méthodes de page pour effectuer des actions Web pour atteindre les fonctionnalités de la page comme indiqué précédemment dans ce tutoriel. 

Voici l'extrait de code des utilitaires WebAction: 

package com.base.webActionHelperUtils;

import java.util.ArrayList;
import java.util.List;
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;


public class WebActionsHelperUtils {

  protected WebDriver driver;

  public WebActionsHelperUtils(WebDriver driver) {

     this.driver = driver;
  }

  public void safeClick(By element) {

     waitForElementToBeClickAble(element, 30);
     driver.findElement(element).click();
  }

  public List<WebElement> 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;
     }
     return 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);
        return true;
     } catch (Exception e) {
        return false;
     }
  }

  public void switchToTab(int indexOfTab) {
     ArrayList<String> tabs = new ArrayList<String>(driver.getWindowHandles());
     driver.switchTo().window(tabs.get(indexOfTab));

  }
}

Module de page utilitaires - Framework de modèle d'objet de page

Comme nous le savons, nous devons créer la classe Page et conserver les fonctionnalités de page dans les méthodes de page, alors créons maintenant le module de page pour le cadre de modèle d'objet de page: 

Chaque classe de page à nouveau étend les utilitaires WebAction que nous avons développé tout à l'heure et implémente les interfaces de page, où les interfaces de page ne sont rien d'autre que les interfaces pour conserver les éléments Web / localisateurs de la page respective.

Maintenant, pourquoi nous avons besoin d'interfaces pour stocker les localisateurs: 

  • Nous pourrions utiliser n'importe quel fichier de propriétés / excel pour conserver les localisateurs à partir de là, mais dans cette approche, nous devons récupérer les localisateurs chaque fois que nous avons l'intention de les utiliser dans les méthodes de page où la complexité du temps augmentera, nous n'avons donc pas stocké le localisateurs dans les fichiers. 
  • Nous pourrions utiliser la même classe (pageclass avec l'implémentation de la fabrique de pages avec l'annotation @findBy), mais nous n'avons pas utilisé ce modèle d'objet de page classique car en stockant les localisateurs respectifs dans les classes de page respectives, le code sera illisible et maladroit, nous voulions séparer les localisateurs du code pour maintenir la base de code propre et la maintenabilité, le débogage et la réutilisabilité seront également augmentés dans cette approche.
  • Nous pourrions stocker les localisateurs dans des classes séparées, mais nous ne l'avons pas fait car appeler «N» classes de localisateurs de pages, nous avons dû créer le nombre «n» d'objets des localisateurs classés; par conséquent, la complexité de l'espace sera affectée.

Par conséquent, nous avons utilisé des interfaces séparées pour les localisateurs de pages séparés à stocker selon cette approche; nous résolvons toutes les déclarations de problème ci-dessus, qui sont la complexité du temps, la complexité de l'espace et la base de code propre et maintenable comme dans les interfaces, nous n'avons pas besoin de créer des objets pour accéder aux localisateurs.

package com.base.pageModules;

import java.util.List;

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;

public class HomePage extends WebActionsHelperUtils implements HomePageLocators {

  JSonHandler jsonHandler = new JSonHandler();

  public HomePage(WebDriver driver) {
     super(driver);
     this.driver = driver;
  }

  public void enterSearchdataToSearchField(String searchData) {

     waitForElementToBeClickAble(SEARCH_BOX, 10);
     enterTextIntoElement(SEARCH_BOX, searchData);

  }

  public void navigatToUrl() {
     driver.get(url);
  }

  public void captureSearchSuggestion(String pathToJsonDataStore, String searchData) {
     List<WebElement> elements = getElements(SUGGESTION_BOX);
     jsonHandler.captureAndWriteJsonData(elements, 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 + "]"));
  }

}

De même, vous pouvez continuer à inclure les fonctionnalités de page dans les différentes méthodes Page dans les classes de page respectives. 

Voici comment le Interfaces de localisateurs de pages ressembler : 

package com.page.locatorModules;

import org.openqa.selenium.By;

public interface HomePageLocators {

 
  By SEARCH_BOX=By.id("twotabsearchtextbox");
  By SUGGESTION_BOX=By.xpath("//div[@id='suggestions']/div");
 
}

Maintenant, le segment suivant, vous pouvez créer un baseSetUp ou Basetest où vous souhaitez effectuer les parties d'initialisation / chargement de données. Vous pouvez également utiliser @beforeTest, @beforeClass méthodes dans cette classe elle-même et utilisez-les dans vos classes de test.

Configuration de base La classe ressemble à: 

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

public class BaseSetUp {

	public WebDriver driver;
	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";
	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;
	}

	protected void setDriver() {
		driver = browserProvider.getDriver(modeOfExecution).init(browserName);
	}

	@DataProvider(name = "SearchFunctionality")
	public Object[][] getCityDetails() {
		Object[][] arrayObject = dataProviderExcel.fetchDataSet(pathToExcelData, "DataFeed");
		return arrayObject;
	}
}

Classes de test: Comme nous utiliserions TestNG ici, vous devez donc écrire la méthode @test pour le script de test à développer, telle que: 

Voici l'extrait de code pour les classes de test  

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

public class DemoTest extends BaseSetUp {

  HomePage homePage;
  SearchPage searchPage;

  @BeforeMethod
  public void setUpTest() {
     setDriver();
     homePage = new HomePage(driver);
     searchPage = new SearchPage(driver);
     homePage.navigatToUrl();
  }

  @Test(dataProvider = "SearchFunctionality")
  public void search(String searchData, String selectOption) {
     homePage.enterSearchdataToSearchField(searchData);
     homePage.genericWait(5);
     homePage.captureSearchSuggestion(pathToJasonDataStore, searchData);
     homePage.clikcOnSelectedElement(selectOption);
     searchPage.clickOnFirstProduct();
     searchPage.switchToProductSpecificPage();
     searchPage.captureProductData(pathToJasonDataStore, searchData);

  }

  @AfterMethod
  public void tearDown() {
     if (driver != null) {
        driver.quit();
     }
  }

}

Fichier TestNgXML -Page Object Model Framework

Vous auriez besoin de définir une classe XML pour le testng.xml, qui est essentiellement un cadre de test unitaire et contrôle le flux de votre automatisation; vous pouvez y mentionner les classes de test elles-mêmes.

<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" >
<suite name="test-parameter" parallel="tests" thread-count="3">

<test name="DemoAutomation_TarGet">
<classes>
<class name="com.demo.testS.DemoTest"></class>

</classes>
</test>
</suite>

Donc, avec ces activités, votre base Modèle d'objet de page le cadre devrait être prêt maintenant. Si vous souhaitez atteindre la version avancée de votre framework, vous pouvez intégrer ces domaines ci-dessous: 

Structure de modèle d'objet de page d'entités de création de rapports

Vous pouvez utiliser n'importe quelle fonctionnalité de rapport disponible comme allure, extentreport, rapport TestNG ou rapport préalable en utilisant Pile ELK, et ainsi de suite 

Juste pour garder la simplicité, nous montrons ici la fonctionnalité de reporting avec le rapport d'étendue, qui possède de nombreuses fonctionnalités et peut être considéré comme un niveau intermédiaire de reporting. 

Vous devez créer une classe pour avoir les utilitaires pour travailler avec le rapport d'étendue, et ce faisant, vous devez implémenter le interface ITestlistener de TestNg; le code ci-dessous montre comment: 

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

  }
}

Conclusion: Avec cela, nous concluons le développement du cadre du modèle d'objet de page Selenium à travers lequel vous pouvez commencer à créer le cadre du modèle d'objet de page et l'amener au niveau avancé.Dans la prochaine série du didacticiel, nous discuterons plus en détail des fonctionnalités avancées du cadre Selenium . Pour parcourir la série de Tutoriel Selenium que vous pouvez parcourir ici.

À propos de Debarghya

Moi-même Debarghya Roy, je suis un ARCHITECTE en ingénierie travaillant avec la société fortune 5 et un contributeur open source, ayant environ 12 ans d'expérience / expertise dans diverses piles technologiques.
J'ai travaillé avec diverses technologies telles que Java, C#, Python, Groovy, UI Automation (Selenium), Mobile Automation (Appium), API/Backend Automation, Performance Engineering (JMeter, Locust), Security Automation (MobSF, OwAsp, Kali Linux , Astra, ZAP, etc.), RPA, automatisation de l'ingénierie des processus, automatisation mainframe, développement back-end avec SpringBoot, Kafka, Redis, RabitMQ, pile ELK, GrayLog, Jenkins et ayant également une expérience dans les technologies cloud, DevOps, etc.
Je vis à Bangalore, en Inde avec ma femme et j'ai une passion pour les blogs, la musique, jouer de la guitare et ma philosophie de vie est l'éducation pour tous qui a donné naissance à LambdaGeeks. Permet de se connecter via linked-in - https://www.linkedin.com/in/debarghya-roy/

Laisser un commentaire

Votre adresse email n'apparaîtra pas. Les champs obligatoires sont marqués *

Geeks Lambda