Kumpletong Framework ng Model ng Bagay ng Pahina -2021

Sa tutorial na ito, malalaman natin ang tungkol sa Modelong Bagay ng Pahina, at dinidisenyo at bubuo din namin ang balangkas ng Modelong Bagay ng Pahina mula sa simula. 

Tinalakay namin ang lahat ng mga uri ng balangkas sa Selenium, kabilang ang Model ng Bagay ng Pahina , dito tayo dadaan sa kalaliman.

Framework ng Modelong Bagay ng Pahina
Pag-unlad ng Balangkas ng Modelong Bagay ng Pahina

Magdidisenyo at bubuo kami ng mga tampok sa ibaba.

Ano ang disenyo ng Framework Model ng Bagay ng Pahina sa Selenium  

Ang Model ng Bagay ng Pahina ay isang Modelong Disenyo para sa pagbuo ng Selenium test Automation, kung saan ipinamamahagi namin ang aming buong Application sa ilalim ng pagsubok sa mga maliliit na pahina (kung minsan ang isang webpage ay isinasaalang-alang bilang isang pahina, at kung minsan ang isang subpart ng isang Webpage ay isinasaalang-alang din bilang isang Pahina). Ang bawat isa sa mga pahinang ito ay kinakatawan bilang isang klase sa Java, at ang mga pag-andar ng mga pahina ay nakasulat bilang iba't ibang mga pamamaraan sa magkakaugnay na pahina ng Java na klase.

Sabihin nating mayroon kang isang application ng Gmail na awtomatiko mo; samakatuwid ang pahina ng pag-login sa Gmail ay naroroon kung saan mayroon kang ilang mga pangunahing pag-andar tulad ng pag-login, lumikha ng isang account, atbp.

Dito lilikha kami ng isang java class bilang GmailLoginPage, at magsusulat kami ng mga pamamaraan na pinangalanan bilang performLogin (), createUserAccount, atbp. 

Sabihin nating sa sandaling naka-log in ka sa iyong Gmail account, mayroon kang maraming mga tampok tulad ng inbox, nagpadala ng mga item, basurahan, atbp. Ngayon, para sa bawat module, lumikha ka ng isang klase sa Java at panatilihin ang kanilang mga pagpapaandar bilang mga pamamaraan ng Java sa loob ng kani-kanilang mga klase sa java. 

Bakit Modelo ng Bagay ng Pahina

Ang Model ng Bagay ng Pahina ay isang napaka-matatag at advanced na modelo ng disenyo ng balangkas kung saan maaari mong alagaan ang mga nasa ibaba na lugar: 

  • Security ng codebase ng automation ng mga web page (ang bawat pag-andar at code ng webpage ay hindi nakalantad sa ibang webpage o java class)
  • Muling magagamit, ibig sabihin, maaari kang tumawag sa kani-kanilang pamamaraan ng pahina nang hindi ito isinusulat "N" na bilang ng mga lugar sa iyong balangkas.
  • Ang Tagahanap ng bawat isa sa pahina ay naninirahan sa iba't ibang mga lokasyon (mga interface ng antas ng pahina o sa pamamagitan ng paggamit ng pagefactory, kaya't sa kaso ng anumang mga bagong tagahanap para sa pahinang iyon o pagbabago sa tagahanap ay maaari kang pumunta sa kani-kanilang lugar na mga tagahanap ng pahina at baguhin ito, at ito ay makikita sa mga pamamaraan ng pagtawag kung saan tinawag ang mga tagahanap)
  • Madaling pag-debug dahil sa mga tampok sa itaas
  • Madaling mapanatili.
  • Nasusukat: Maaari mong isama ang isang malawak na hanay ng mga tool / kliyente kasama ang iyong balangkas na modelo ng Bagay ng Pahina at pagbutihin at sukatin ang iyong balangkas ng modelo ng object ng object upang i-automate din ang mga kaso ng sobrang paggamit. 

Istraktura ng Balangkas ng Modelong Bagay ng Pahina ng Hybrid na Pahina

Sa nakaraang tutorial, naintindihan namin ang hybrid na Model ng Bagay ng Pahina, at ngayon ay magdidisenyo at bubuo kami ng isang balangkas.

Ang arkitektura ng balangkas ng Modelong Pahina ng Bagay

Maaari lamang kaming lumikha ng isang proyekto ng maven at isama ang mga dependency sa file na POM.xml na kinakailangan para sa balangkas sa una na ganito ang hitsura: 

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

Pagkatapos nito, magtatayo kami ng maliliit na mga module at kagamitan, kung saan namin ikinabit ang snapshot na ito sa ibaba upang makapagbigay lamang ng mga pananaw / pagtingin sa mataas na antas. Tatayo kami ng mga kagamitan nang paisa-isa. 

Kumpletong Framework ng Model ng Bagay ng Pahina -2021
Istraktura ng Balangkas ng Modelong Bagay ng Pahina ng Selenium

Narito ang mga modyul sa ibaba na bubuo namin; naibigay namin ang snippet ng code para sa pareho: 

DriverUtils - Framework ng Model ng Bagay ng Pahina

Nagbibigay ang modyul na ito ng lahat ng mga kagamitan at suporta upang gumana sa iba't ibang mga browser (Chrome, Firefox, atbp.). Ang utility na ito ay batay sa pattern ng disenyo ng Pabrika, tulad ng tinalakay natin sa nakaraang tutorial dito.

package com.base.driverUtils;

import org.openqa.selenium.WebDriver;

public interface IDriver {

  public WebDriver init(String browserName);
}

Pagpapatupad ng Localdriver, na lokal na isasagawa sa 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: Upang gumana sa isang remote webdriver (tulad ng Selenium Grid), kailangan mo ng isang remote na sanggunian ng driver ng browser, na kagaya ng: 

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

}

Klase ng Factory Driver: Nagbibigay ito sa amin ng object ng klase ng driver (remote / local) upang simulan ang mga browser na iyong pinili. Dadalhin namin ang uri ng driver (lokal o remote) at browser (chrome o firefox atbp.) Sa pamamagitan ng file ng pagsasaayos (gumamit kami ng isang file ng mga katangian upang mapanatili ang mga pagsasaayos, na ibabahagi namin sa ilang sandali)

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

Ngayon kahit saan mo mangangailangan ang sanggunian ng driver, maaari mo lamang likhain ang object ng object ng klase ng pabrika (DriverProvider sa kasong ito) at maaaring simulan ang halimbawa ng driver browser.

Narito ang napaka pangunahing config file; maaari kang lumikha ng isang file ng mga katangian at maiimbak ang mga halagang tulad nito: 

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

Framework ng Modelo ng Bagay na DataUtils-Page: 

Dinisenyo namin ang mga kagamitan sa data dito bilang parehong pattern ng disenyo ng Pabrika tulad ng ginawa namin mula sa pagpapatupad ng mga module ng driver browser.

Narito ang snippet ng code sa ibaba para sa pareho; sa balangkas, ipinakita namin ang mga util ng Excel at kagamitan ng pag-aari, maaari mong mapahusay ang higit pa upang suportahan ang iba pang mga kagamitan sa data tulad ng YAML, PDF, atbp. 

Ang interface ganito ang ganito: 

package com.base.dataUtils;

public interface IDataProvider {

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

Narito ang pagpapatupad para sa Provider ng Data ng 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;
  }

}

Tagapagbigay ng Data ng Mga Katangian: 

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

}

Ang klase ng pabrika para sa data na Mga Utilities na ito

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;

  }
}

Mga utility sa WebAction -Prangka ng Modelong Bagay ng Bagay

Sa mga kagamitan, isinusulat namin ang lahat ng mga kagamitan na nauugnay sa iyong mga pagkilos sa Web tulad ng (pag-click, mga sendkey, screenshot, atbp.), At magagamit namin ito sa Mga Pamamaraan ng Pahina upang maisagawa ang mga pagkilos sa web upang makamit ang mga pag-andar ng pahina tulad ng tinalakay nang mas maaga sa tutorial na ito. 

Narito ang snippet ng code para sa WebAction Utilities: 

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

  }
}

Mga Utility ng Pahina ng Module ng Pahina-Framework ng Model ng Bagay ng Pahina

Tulad ng alam natin, kailangan nating likhain ang klase ng Pahina at panatilihin ang mga pag-andar ng pahina sa mga pamamaraan ng pahina, kaya't lumikha tayo ngayon ng Module ng Pahina para sa balangkas ng Modelong Bagay ng Pahina: 

Tuwing Class Class muli nagpapalawak ng WebAction Utils na binuo natin ngayon lang at nagpapatupad ng mga interface ng Pahina, kung saan ang mga interface ng pahina ay walang anuman kundi ang mga interface upang mapanatili ang mga Web Elemento / locator ng bawat pahina.

Ngayon Bakit Kailangan namin ng mga interface upang maiimbak ang mga locator: 

  • Maaari kaming gumamit ng anumang mga katangian / excel file upang panatilihin ang mga locator doon, ngunit sa pamamaraang ito, kailangan naming kunin ang mga tagahanap tuwing nilalayon naming gamitin ito sa mga pamamaraan ng pahina kung saan tataas ang pagiging kumplikado ng oras, kaya hindi namin naimbak ang mga tagahanap sa mga file. 
  • Maaari naming magamit ang parehong klase (pageclass na may pagpapatupad ng pabrika ng pahina na may @findBy anotation), ngunit hindi namin ginamit ang klasikong Model na object ng Pahina dahil sa pag-iimbak ng kani-kanilang mga tagahanap sa kani-kanilang mga klase sa pahina, ang code ay hindi nababasa at malamya, nais naming paghiwalayin ang mga tagahanap mula sa code upang mapanatili ang malinis na codebase at mapanatili at ma-debug at muling magagamit din ay tataas sa pamamaraang ito.
  • Maaari naming iimbak ang mga tagahanap sa magkakahiwalay na klase, ngunit hindi namin ito ginawa dahil tumawag Ang mga klase ng tagahanap ng "N" na pahina, kinailangan naming lumikha ng "n" na bilang ng mga bagay na pinag-uuri ng mga tagahanap; samakatuwid ang pagiging kumplikado ng espasyo ay maaapektuhan.

Samakatuwid gumamit kami ng magkakahiwalay na mga interface para sa magkakahiwalay na mga tagahanap ng pahina upang maiimbak ayon sa pamamaraang ito; nilulutas namin ang lahat ng mga pahayag sa problema sa itaas, na kung saan ay kumplikado ng oras, pagiging kumplikado ng espasyo, at ang malinis at napapanatili na codebase tulad ng sa mga interface, hindi namin kailangang lumikha ng mga bagay upang ma-access ang mga locator.

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 + "]"));
  }

}

Gayundin, maaari mong panatilihing isama ang mga tampok sa pahina sa iba't ibang mga pamamaraan ng pahina sa loob ng kani-kanilang mga klase sa pahina. 

Narito kung paano ang Mga interface ng locator ng pahina kamukha : 

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");
 
}

Ngayon ang susunod na segment, maaari kang lumikha ng isang baseSetUp o Basetest kung saan mo nais gampanan ang mga bahagi ng pagsisimula / pag-load ng data. Gayundin, maaari mong gamitin @beforeTest, @beoforeClass mga pamamaraan sa mismong klase na ito at ginagamit ang mga ito sa iyong mga klase sa pagsubok.

BaseSetup Ang klase ay parang: 

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

Mga Klase sa Pagsubok: Tulad ng gagamitin namin sa TestNG dito, kaya kailangan mong magsulat ng @test na pamamaraan para maipabuo ang script ng pagsubok, tulad ng: 

Narito ang code snippet para sa Mga Klase sa Pagsubok  

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

}

File ng TestNgXML -Prangka ng Modelong Bagay ng Pahina

Kakailanganin mong tukuyin ang isang klase ng XML para sa testng.xml, na karaniwang isang framework ng pagsubok ng yunit at kinokontrol ang daloy ng iyong automation; maaari mong banggitin ang mga pagsubok na klase doon mismo.

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

Kaya sa mga aktibidad na ito, ang iyong pangunahing Modelong Bagay ng Pahina dapat handa na ngayon ang balangkas. Kung nais mong Makamit ang advanced na bersyon ng iyong balangkas, maaari mong isama ang mga sumusunod na lugar: 

Pag-uulat ng Framework ng Modelong Tampok na Pahina ng Tampok

Maaari mong gamitin ang anumang tampok sa pag-uulat na magagamit tulad ng pang-akit, lawak ng ulat, ulat ng TestNG, o paunang pag-uulat sa pamamagitan ng paggamit ELK stack, at iba pa 

Upang mapanatili lamang ang pagiging simple, ipinapakita namin dito ang tampok na pag-uulat na may Malawakang ulat, na kung saan ay nagkakaroon ng maraming mga tampok kasama nito at maaaring maituring bilang isang gitnang antas ng pag-uulat. 

Kailangan mong bumuo ng isang klase upang magkaroon ng mga kagamitan upang gumana sa Malawakang ulat, at habang ginagawa ito, kailangan mong ipatupad ang interface ng ITestlistener mula sa TestNg; ipinapakita ang code sa ibaba kung paano: 

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

  }
}

Konklusyon: Sa pamamagitan nito natatapos namin ang pagbuo ng balangkas ng Modelong Pahina ng Selenium na Pahina kung saan maaari mong simulang buuin ang balangkas ng modelo ng Bagay na Pahina at madadala ito sa advanced na antas, sa paparating na serye ng tutorial tatalakayin namin ang higit pa sa mga advanced na tampok ng Selenium framework . Upang dumaan sa serye ng Selenium tutorial maaari kang dumaan dito.

Tungkol kay Debarghya

Kumpletong Framework ng Model ng Bagay ng Pahina -2021Ang Sarili kong Debarghya Roy, ako ay isang Engineering ARCHITECT na nagtatrabaho kasama ang fortune 5 na kumpanya at isang open source na nag-aambag, pagkakaroon ng humigit-kumulang 12 taong karanasan / kadalubhasaan sa iba't ibang stack ng Teknolohiya.
Nagtrabaho ako sa iba't ibang mga teknolohiya tulad ng 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 atbp), RPA, Process Engineering Automation, Mainframe Automation, Back End Development na may SpringBoot, Kafka, Redis, RabitMQ, ELK stack, GrayLog, Jenkins at mayroon ding karanasan sa Cloud Technologies, DevOps atbp.
Nakatira ako sa Bangalore, India kasama ang aking asawa at may hilig sa Blogging, musika, pagtugtog ng gitara at ang aking Pilosopiya ng buhay ay Edukasyon para sa Lahat na nagbigay ng kapanganakan ng LambdaGeeks. Hinahayaan nating kumonekta sa loob ng naka-link - https://www.linkedin.com/in/debarghya-roy/

Mag-iwan ng komento

Ang iyong email address ay hindi ilalathala. Ang mga kailangang field ay may markang *

en English
X