page object model with page factory selenium tutorial
Denne grundige veiledningen forklarer alt om sideobjektmodell (POM) med sidefaktor ved bruk av eksempler. Du kan også lære implementeringen av POM i selen:
I denne opplæringen vil vi forstå hvordan du lager en sideobjektmodell ved bruk av Page Factory-tilnærmingen. Vi vil fokusere på:
- Fabrikklasse
- Hvordan lage en grunnleggende POM ved hjelp av Page Factory Pattern
- Ulike merknader som brukes i sidefabrikkinngang
Før vi ser hva som er Pagefactory og hvordan det kan brukes sammen med Page-objektmodellen, la oss forstå hva som er Page Object Model som er kjent som POM.
=> Besøk her for å se Selenium Training Series for All.
Hva du vil lære:
- Hva er Page Object Model (POM)?
- Hva er Pagefactory?
- POM bruker Page Factory
- ofte stilte spørsmål
- Konklusjon
Hva er Page Object Model (POM)?
Teoretiske terminologier beskriver Sideobjektmodell som et designmønster som brukes til å bygge et objektlager for webelementene som er tilgjengelige i applikasjonen som testes. Få andre omtaler det som et rammeverk for Selen-automatisering for den gitte applikasjonen som testes.
Det jeg har forstått om begrepet Page Object Model er imidlertid:
#1) Det er et designmønster der du har en egen Java-klassefil som tilsvarer hver skjerm eller side i applikasjonen. Klassefilen kan inneholde objektdatabasen til UI-elementene så vel som metoder.
#to) Hvis det er enorme webelementer på en side, kan objektlagerklassen for en side skilles fra klassen som inneholder metoder for den tilsvarende siden.
Eksempel: Hvis Register Account-siden har mange inndatafelt, kan det være en klasse RegisterAccountObjects.java som danner objektlageret for UI-elementene på registerkontosiden.
Det kan opprettes en egen klassefil RegisterAccount.java som utvider eller arver RegisterAccountObjects som inkluderer alle metodene som utfører forskjellige handlinger på siden.
# 3) Dessuten kan det være en generisk pakke med en {roperties-fil, Excel-testdata og vanlige metoder under en pakke.
Eksempel: DriverFactory som kan brukes veldig enkelt på alle sidene i applikasjonen
Forstå POM med eksempel
Sjekk her for å lære mer om POM.
Nedenfor er et øyeblikksbilde av websiden:
Ved å klikke på hver av disse koblingene vil brukeren omdirigere til en ny side.
Her er øyeblikksbildet av hvordan prosjektstrukturen med Selen er bygget ved hjelp av Page-objektmodellen som tilsvarer hver side på nettstedet. Hver Java-klasse inkluderer objektlager og metoder for å utføre forskjellige handlinger på siden.
Dessuten vil det være en annen JUNIT eller TestNG eller en Java-klassefil som påkaller anrop til klassefiler på disse sidene.
Hvorfor bruker vi sideobjektmodellen?
Det er en surring rundt bruken av dette kraftige Selen-rammeverket kalt POM eller sideobjektmodell. Nå oppstår spørsmålet som 'Hvorfor bruke POM?'.
Det enkle svaret på dette er at POM er en kombinasjon av datadrevne, modulære og hybrid rammer. Det er en tilnærming til systematisk å organisere skriptene på en slik måte at det gjør det enkelt for QA å opprettholde koden uten problemer og hjelper også til å forhindre overflødig eller duplikatkode.
For eksempel, hvis det er en endring i lokaliseringsverdien på en bestemt side, er det veldig enkelt å identifisere og gjøre den raske endringen bare i skriptet til den respektive siden uten å påvirke koden andre steder.
Vi bruker Page Object Model-konseptet i Selenium Webdriver av følgende årsaker:
- Et objektlager opprettes i denne POM-modellen. Det er uavhengig av testsaker og kan gjenbrukes til et annet prosjekt.
- Navngivningskonvensjonen for metoder er veldig enkel, forståelig og mer realistisk.
- Under Side-objektmodellen lager vi sideklasser som kan brukes på nytt i et annet prosjekt.
- Page-objektmodellen er lett for det utviklede rammeverket på grunn av flere fordeler.
- I denne modellen opprettes separate klasser for forskjellige sider i en webapplikasjon som påloggingsside, hjemmesiden, medarbeidernes detaljside, endring av passordside osv
- Hvis det er noen endring i noe element på et nettsted, trenger vi bare å gjøre endringer i en klasse, og ikke i alle klasser.
- Skriptet som er designet er mer gjenbrukbart, lesbart og vedlikeholdbart i sidemodellmodellen.
- Prosjektstrukturen er ganske enkel og forståelig.
- Kan bruke PageFactory i sideobjektmodellen for å initialisere webelementet og lagre elementene i hurtigbufferen.
- TestNG kan også integreres i Page Object Model-tilnærmingen.
Implementering av enkel POM i selen
# 1) Scenario for å automatisere
Nå automatiserer vi det gitte scenariet ved hjelp av Page Object Model.
Scenariet er forklart nedenfor:
Trinn 1: Start nettstedet 'https: //demo.vtiger.com'.
Steg 2: Skriv inn gyldig legitimasjon.
Trinn 3: Logg inn på siden.
Trinn 4: Bekreft hjemmesiden.
Trinn 5: Logg av nettstedet.
Trinn 6: Lukk nettleseren.
# 2) Selen Scripts For The Over Scenario In POM
Nå lager vi POM-strukturen i formørkelse, som forklart nedenfor:
Trinn 1: Lag et prosjekt i formørkelse - POM-basert struktur:
a) Opprett prosjekt 'Sideobjektmodell'.
b) Lag 3-pakke under prosjektet.
- bibliotek
- sider
- test tilfeller
Bibliotek: Under dette legger vi de kodene som må kalles igjen og igjen i testtilfellene som nettleserstart, skjermbilder osv. Brukeren kan legge til flere klasser under det basert på prosjektbehovet.
Sider: Under dette opprettes klasser for hver side i webapplikasjonen og kan legge til flere sideklasser basert på antall sider i applikasjonen.
Test tilfeller: Under dette skriver vi påloggingsprøvesaken og kan legge til flere testsaker etter behov for å teste hele applikasjonen.
c) Klasser under pakkene er vist i bildet nedenfor.
Steg to: Lag følgende klasser under bibliotekspakken.
Nettleser.java: I denne klassen er 3 nettlesere (Firefox, Chrome og Internet Explorer) definert, og det kalles i påloggingsprøvesaken. Basert på kravet kan brukeren også teste applikasjonen i forskjellige nettlesere.
package library; 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 Browser { static WebDriver driver; public static WebDriver StartBrowser(String browsername , String url) { // If the browser is Firefox if (browsername.equalsIgnoreCase('Firefox')) { // Set the path for geckodriver.exe System.setProperty('webdriver.firefox.marionette',' E://Selenium//Selenium_Jars//geckodriver.exe '); driver = new FirefoxDriver(); } // If the browser is Chrome else if (browsername.equalsIgnoreCase('Chrome')) { // Set the path for chromedriver.exe System.setProperty('webdriver.chrome.driver','E://Selenium//Selenium_Jars//chromedriver.exe'); driver = new ChromeDriver(); } // If the browser is IE else if (browsername.equalsIgnoreCase('IE')) { // Set the path for IEdriver.exe System.setProperty('webdriver.ie.driver','E://Selenium//Selenium_Jars//IEDriverServer.exe'); driver = new InternetExplorerDriver(); } driver.manage().window().maximize(); driver.get(url); return driver; } }
ScreenShot.java: I denne klassen skrives et skjermbildeprogram, og det kalles det i testsaken når brukeren vil ta et skjermbilde av om testen mislykkes eller består.
package library; import java.io.File; import org.apache.commons.io.FileUtils; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; import org.openqa.selenium.WebDriver; public class ScreenShot { public static void captureScreenShot(WebDriver driver, String ScreenShotName) { try { File screenshot=((TakesScreenshot)driver).getScreenshotAs(OutputType. FILE ); FileUtils.copyFile(screenshot, new File('E://Selenium//'+ScreenShotName+'.jpg')); } catch (Exception e) { System. out .println(e.getMessage()); e.printStackTrace(); } } }
Trinn 3: Opprett sideklasser under Sidepakke.
Hjemmeside.java: Dette er hjemmesideklassen der alle elementene på hjemmesiden og metodene er definert.
package pages; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; public class HomePage { WebDriver driver; By logout = By.id('p_lt_ctl03_wSOB_btnSignOutLink'); By home = By.id('p_lt_ctl02_wCU2_lblLabel'); //Constructor to initialize object public HomePage(WebDriver dr) { this .driver=dr; } public String pageverify() { return driver.findElement(home).getText(); } public void logout() { driver.findElement(logout).click(); } }
LoginPage.java: Dette er påloggingssideklassen, der alle elementene på påloggingssiden og metodene er definert.
package pages; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; public class LoginPage { WebDriver driver; By UserID = By.xpath('//*(contains(@id,'Login1_UserName'))'); By password = By.xpath('//*(contains(@id,'Login1_Password'))'); By Submit = By.xpath('//*(contains(@id,'Login1_LoginButton'))'); //Constructor to initialize object public LoginPage(WebDriver driver) { this .driver = driver; } public void loginToSite(String Username, String Password) { this .enterUsername(Username); this .enterPasssword(Password); this .clickSubmit(); } public void enterUsername(String Username) { driver.findElement(UserID).sendKeys(Username); } public void enterPasssword(String Password) { driver.findElement(password).sendKeys(Password); } public void clickSubmit() { driver.findElement(Submit).click(); } }
Trinn 4: Opprett testtilfeller for påloggingsscenariet.
LoginTestCase.java: Dette er LoginTestCase-klassen, hvor testsaken utføres. Brukeren kan også opprette flere testsaker i henhold til prosjektets behov.
package testcases; import java.util.concurrent.TimeUnit; import library.Browser; import library.ScreenShot; import org.openqa.selenium.WebDriver; import org.testng.Assert; import org.testng.ITestResult; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; import pages.HomePage; import pages.LoginPage; public class LoginTestCase { WebDriver driver; LoginPage lp; HomePage hp; int i = 0; // Launch of the given browser. @BeforeTest public void browserlaunch() { driver = Browser.StartBrowser('Chrome', 'http://demostore.kenticolab.com/Special-Pages/Logon.aspx'); driver.manage().timeouts().implicitlyWait(30,TimeUnit. SECONDS ); lp = new LoginPage(driver); hp = new HomePage(driver); } // Login to the Site. @Test(priority = 1) public void Login() { lp.loginToSite('gaurav.3n@gmail.com','Test@123'); } // Verifing the Home Page. @Test(priority = 2) public void HomePageVerify() { String HomeText = hp.pageverify(); Assert.assertEquals(HomeText, 'Logged on as'); } // Logout the site. @Test(priority = 3) public void Logout() { hp.logout(); } // Taking Screen shot on test fail @AfterMethod public void screenshot(ITestResult result) { i = i+1; String name = 'ScreenShot'; String x = name+String.valueOf(i); if (ITestResult. FAILURE == result.getStatus()) { ScreenShot.captureScreenShot(driver, x); } } @AfterTest public void closeBrowser() { driver.close(); } }
Trinn 5: Utfør “LoginTestCase.java“.
Trinn 6: Resultat av sideobjektmodellen:
- Start Chrome-nettleseren.
- Demosiden åpnes i nettleseren.
- Logg inn på demosiden.
- Bekreft hjemmesiden.
- Logg av nettstedet.
- Lukk nettleseren.
La oss nå utforske hovedkonseptet i denne opplæringen som fanger oppmerksomheten, dvs. “Pagefactory”.
Hva er Pagefactory?
PageFactory er en måte å implementere “Page Object Model” på. Her følger vi prinsippet om separasjon av Page Object Repository og Test Methods. Det er et innebygd konsept av Page Object Model som er veldig optimalisert.
La oss nå få mer klarhet i begrepet Pagefactory.
#1) For det første gir konseptet Pagefactory en alternativ måte når det gjelder syntaks og semantikk for å lage et objektlager for webelementene på en side.
#to) For det andre bruker den en litt annen strategi for initialisering av webelementene.
# 3) Objektlageret for UI-webelementene kan bygges ved hjelp av:
- Vanlig ‘POM uten Pagefactory’ og,
- Alternativt kan du bruke ‘POM med Pagefactory’.
Nedenfor er en billedlig fremstilling av det samme:
Nå skal vi se på alle aspektene som skiller den vanlige POM fra POM med Pagefactory.
a) Forskjellen i syntaksen for å lokalisere et element ved bruk av vanlig POM vs POM med Pagefactory.
For eksempel , Klikk her for å finne søkefeltet som vises på siden.
POM uten sidefaktor:
# 1) Nedenfor ser du hvordan du finner søkefeltet ved hjelp av den vanlige POM:
WebElement searchNSETxt=driver.findElement(By.id(“searchBox”));
# 2) Trinnet nedenfor overfører verdien 'investering' til NSE-søkefeltet.
searchNSETxt.sendkeys(“investment”);
POM ved bruk av Pagefactory:
#1) Du kan finne søkefeltet ved hjelp av Pagefactory som vist nedenfor.
Kommentaren @FindBy brukes i Pagefactory for å identifisere et element mens POM uten Pagefactory bruker driver.findElement () metode for å finne et element.
Den andre uttalelsen for Pagefactory etter @FindBy tilordner en type WebElement klasse som fungerer nøyaktig likt tildelingen av et elementnavn av typen WebElement-klasse som en returtype av metoden driver.findElement () som brukes i vanlig POM (searchNSETxt i dette eksemplet).
Vi vil se på @FindBy merknader i detalj i den kommende delen av denne veiledningen.
@FindBy(id = 'searchBox') WebElement searchNSETxt;
#to) Trinnet nedenfor overfører verdien 'investering' til Search NSE-feltet, og syntaksen forblir den samme som den vanlige POM (POM uten Pagefactory).
searchNSETxt.sendkeys(“investment”);
b) Forskjellen i strategien for initialisering av webelementer ved bruk av vanlig POM vs POM med Pagefactory.
Bruke POM uten sidefaktor:
Nedenfor er en kodebit for å angi Chrome-driverbanen. Det opprettes en WebDriver-forekomst med navnedriveren, og ChromeDriver er tildelt 'driveren'. Det samme driverobjektet brukes deretter til å starte National Stock Exchange-nettstedet, finne søkeboksen og angi strengverdien i feltet.
Poenget som jeg vil fremheve her er at når det er POM uten sidefabrikk, blir driverinstansen opprettet i utgangspunktet, og hvert webelement initialiseres ny hver gang det blir ringt til det webelementet ved hjelp av driver.findElement () eller driver .findElements ().
Dette er grunnen til, med et nytt trinn av driver.findElement () for et element, blir DOM-strukturen igjen skannet gjennom og oppdatert identifikasjon av elementet gjøres på den siden.
System.setProperty('webdriver.chrome.driver', 'C:\eclipse-workspace\automationframework\src\test\java\Drivers\chromedriver.exe'); WebDriver driver = new ChromeDriver(); driver.get('http://www.nseindia.com/'); WebElement searchNSETxt=driver.findElement(By.id(“searchBox”)); searchNSETxt.sendkeys(“investment”);
Bruke POM med Pagefactory:
Foruten å bruke @FindBy-kommentar i stedet for driver.findElement () -metoden, brukes kodebiten nedenfor i tillegg til Pagefactory. Den statiske initElements () -metoden til PageFactory-klassen brukes til å initialisere alle brukergrensesnittelementene på siden så snart siden lastes inn.
public PagefactoryClass(WebDriver driver) { this.driver = driver; PageFactory.initElements(driver, this); }
Ovennevnte strategi gjør PageFactory-tilnærmingen litt annerledes enn den vanlige POM. I den vanlige POM-en må webelementet initialiseres eksplisitt mens i Pagefactory-tilnærmingen initialiseres alle elementene med initElements () uten å eksplisitt initialisere hvert webelement.
For eksempel: Hvis WebElement ble deklarert, men ikke initialisert i den vanlige POM-en, kastes feilen 'initialiser variabel' eller NullPointerException. Derfor, i vanlig POM, må hvert WebElement initialiseres eksplisitt. PageFactory kommer med en fordel i forhold til vanlig POM i dette tilfellet.
La oss ikke initialisere webelementet BDate (POM uten Pagefactory), kan du se at feilen 'Initialiser variabel' vises og ber brukeren om å initialisere den til null, og du kan derfor ikke anta at elementene blir initialisert implisitt når de lokaliseres.
Element BDate initialisert eksplisitt (POM uten Pagefactory):
La oss nå se på et par forekomster av et komplett program som bruker PageFactory for å utelukke enhver tvetydighet i forståelsen av implementeringsaspektet.
Eksempel 1:
- Gå til ‘http://www.nseindia.com/’
- Velg 'Valutaderivater' fra rullegardinmenyen ved siden av søkefeltet.
- Søk etter ‘USDINR’. Bekreft teksten ‘US Dollar-Indian Rupee - USDINR’ på den resulterende siden.
Programstruktur:
- PagefactoryClass.java som inkluderer et objektlager ved hjelp av siden fabrikkonsept for nseindia.com som er en konstruktør for å initialisere alle webelementer, opprettes, method selectCurrentDerivative () for å velge verdi fra søkefeltets rullegardinfelt, velg Symbol () for å velge et symbol på side som dukker opp neste og verifiserer tekst () for å verifisere om sideoverskriften er som forventet eller ikke.
- NSE_MainClass.java er hovedklassfilen som kaller alle ovennevnte metoder og utfører de respektive handlingene på NSE-siden.
PagefactoryClass.java
package com.pagefactory.knowledge; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.ui.Select; public class PagefactoryClass { WebDriver driver; @FindBy(id = 'QuoteSearch') WebElement Searchbox; @FindBy(id = 'cidkeyword') WebElement Symbol; @FindBy(id = 'companyName') WebElement pageText; public PagefactoryClass(WebDriver driver) { this.driver = driver; PageFactory.initElements(driver, this); } public void selectCurrentDerivative(String derivative) { Select select = new Select(Searchbox); select.selectByVisibleText(derivative); // 'Currency Derivatives' } public void selectSymbol(String symbol) { Symbol.sendKeys(symbol); } public void verifytext() { if (pageText.getText().equalsIgnoreCase('U S Dollar-Indian Rupee - USDINR')) { System.out.println('Page Header is as expected'); } else System.out.println('Page Header is NOT as expected'); } }
NSE_MainClass.java
package com.pagefactory.knowledge; import java.util.List; import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.StaleElementReferenceException; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; public class NSE_MainClass { static PagefactoryClass page; static WebDriver driver; public static void main(String() args) { System.setProperty('webdriver.chrome.driver', 'C:\Users\eclipse-workspace\automation-framework\src\test\java\Drivers\chromedriver.exe'); driver = new ChromeDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get('https://www.nseindia.com/'); driver.manage().window().maximize(); test_Home_Page_ofNSE(); } public static void test_Home_Page_ofNSE() throws StaleElementReferenceException { page = new PagefactoryClass(driver); page.selectCurrentDerivative('Currency Derivatives'); page.selectSymbol('USD'); List Options = driver.findElements(By.xpath('//span(contains(.,'USD'))')); int count = Options.size(); for (int i = 0; i Eksempel 2:
- Gå til ‘https://www.shoppersstop.com/brands’
- Naviger til Haute curry link.
- Kontroller om Haute Curry-siden inneholder teksten “Start New Something”.
Programstruktur
- shopperstopPagefactory.java som inkluderer et objektlager ved hjelp av sidefabrikkskonsept for shoppersstop.com som er en konstruktør for å initialisere alle webelementer, opprettes, metoder lukkerExtraPopup () for å håndtere en varsel-popup-rute som åpnes, klikk på OnHauteCurryLink () for å klikke på Haute Curry Koble til og verifisereStartNewSomething () for å bekrefte om Haute Curry-siden inneholder teksten “Start nytt noe”.
- Shopperstop_CallPagefactory.java er hovedklassfilen som kaller alle ovennevnte metoder og utfører de respektive handlingene på NSE-siden.
shopperstopPagefactory.java
package com.inportia.automation_framework; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; public class shopperstopPagefactory { WebDriver driver; @FindBy(id='firstVisit') WebElement extrapopup; @FindBy(xpath='//img(@src='https://sslimages.shoppersstop.com /sys-master/root/haf/h3a/9519787376670/brandMedia_HauteCurry_logo.png')') WebElement HCLink; @FindBy(xpath='/html/body/main/footer/div(1)/p') WebElement Startnew; public shopperstopPagefactory(WebDriver driver) { this.driver=driver; PageFactory.initElements(driver, this); } public void closeExtraPopup() { extrapopup.click(); } public void clickOnHauteCurryLink() { JavascriptExecutor js = (JavascriptExecutor) driver; js.executeScript('arguments(0).click();',HCLink); js.executeAsyncScript('window.setTimeout(arguments(arguments.length - 1), 10000);'); if(driver.getCurrentUrl().equals('https://www.shoppersstop.com/haute-curry')) { System.out.println('We are on the Haute Curry page'); } else { System.out.println('We are NOT on the Haute Curry page'); } } public void verifyStartNewSomething() { if (Startnew.getText().equalsIgnoreCase('Start Something New')) { System.out.println('Start new something text exists'); } else System.out.println('Start new something text DOESNOT exists'); } }
Shopperstop_CallPagefactory.java
package com.inportia.automation_framework; import java.util.concurrent.TimeUnit; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; public class Shopperstop_CallPagefactory extends shopperstopPagefactory { public Shopperstop_CallPagefactory(WebDriver driver) { super(driver); // TODO Auto-generated constructor stub } static WebDriver driver; public static void main(String() args) { System.setProperty('webdriver.chrome.driver', 'C:\eclipse-workspace\automation-framework\src\test\java\Drivers\chromedriver.exe'); driver = new ChromeDriver(); Shopperstop_CallPagefactory s1=new Shopperstop_CallPagefactory(driver); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get('https://www.shoppersstop.com/brands'); s1.clickOnHauteCurryLink(); s1.verifyStartNewSomething(); } }
POM bruker Page Factory
Videoopplæringsprogrammer - POM With Page Factory
Del I
Del II
En fabrikklasse brukes til å gjøre bruk av sideobjekter enklere og enklere.
- Først må vi finne webelementene ved å kommentere @FindBy i sideklasser .
- Initialiser deretter elementene ved hjelp av initElements () når du starter sideklassen.
#1) @FindBy:
@FindBy-merknad brukes i PageFactory for å lokalisere og deklarere webelementene ved hjelp av forskjellige lokalisatorer.Her overfører vi attributtet samt verdien som brukes til å finne webelementet til @FindBy-merknaden, og deretter blir WebElement erklært.
Merknaden kan brukes på to måter.
For eksempel:
@FindBy(how = How.ID, using='EmailAddress') WebElement Email; @FindBy(id='EmailAddress') WebElement Email;
Imidlertid er førstnevnte standard måte å erklære WebElements på.
'Hvordan' er en klasse og den har statiske variabler som ID, XPATH, CLASSNAME, LINKTEXT, etc.
'ved hjelp av' - Å tilordne en verdi til en statisk variabel.
I ovennevnte eksempel , har vi brukt attributtet 'id' for å finne webelementet 'E-post'. På samme måte kan vi bruke følgende lokatorer med @FindBy-merknadene:
- klassenavn
- css
- Navn
- xpath
- tagName
- linkText
- partialLinkText
# 2) initElements ():
InitiElements er en statisk metode i PageFactory-klassen som brukes til å initialisere alle webelementene som er lokalisert ved @FindBy-kommentar. Dermed kan du enkelt starte sideklassene.
initElements(WebDriver driver, java.lang.Class pageObjectClass)
Vi bør også forstå at POM følger OOPS-prinsipper.
- WebElements blir erklært som private medlemsvariabler (Data Hiding).
- Binding av WebElements med tilsvarende metoder (Encapsulation).
Fremgangsmåte for å opprette POM ved hjelp av Page Factory Pattern
#1) Opprett en egen Java-klassefil for hver webside.
#to) I hver klasse skal alle WebElements deklareres som variabler (ved hjelp av kommentar - @FindBy) og initialiseres ved hjelp av initElement () -metoden. WebElements erklært må initialiseres for å kunne brukes i handlingsmetodene.
# 3) Definer tilsvarende metoder som virker på disse variablene.
La oss ta et eksempel på et enkelt scenario:
- Åpne nettadressen til et program.
- Skriv inn e-postadresse og passorddata.
- Klikk på Logg inn-knappen.
- Bekreft vellykket påloggingsmelding på søkesiden.
Sidelag
Her har vi to sider,
- Hjemmeside - Siden som åpnes når URL-adressen skrives inn og hvor vi legger inn dataene for pålogging.
- Søkeside - En side som vises etter en vellykket pålogging.
I sidelag blir hver side i webapplikasjonen erklært som en egen Java-klasse, og dens lokatorer og handlinger er nevnt der.
Fremgangsmåte for å lage POM med sanntidseksempel
# 1) Opprett en Java-klasse for hver side:
I dette eksempel , får vi tilgang til 2 nettsider, 'Hjem' og 'Søk' -sider.
Derfor vil vi lage to Java-klasser i Page Layer (eller i en pakke si com.automation.pages).
Package Name :com.automation.pages HomePage.java SearchPage.java
# 2) Definer WebElements som variabler ved å bruke Annotation @FindBy:
Vi vil samhandle med:
- E-post, passord, påloggingsfelt på hjemmesiden.
- Vellykket melding på søkesiden.
Så vi vil definere WebElements ved hjelp av @FindBy
For eksempel: Hvis vi skal identifisere EmailAddress ved hjelp av attributt-ID, så er dens variable erklæring
//Locator for EmailId field @FindBy(how=How.ID,using='EmailId') private WebElementEmailIdAddress;
# 3) Lag metoder for handlinger utført på WebElements.
Handlingene nedenfor utføres på WebElements:
- Skriv inn handling i feltet E-postadresse.
- Skriv inn handling i Passord-feltet.
- Klikk på handlingen på påloggingsknappen.
For eksempel, Brukerdefinerte metoder opprettes for hver handling på WebElement som,
public void typeEmailId(String Id){ driver.findElement(EmailAddress).sendKeys(Id) }
Her blir ID gitt som en parameter i metoden, siden input vil bli sendt av brukeren fra hovedtestsaken.
Merk :Det må opprettes en konstruktør i hver klasse i sidelaget for å få driverinstansen fra hovedklassen i testlaget og også initialisere WebElements (sideobjekter) som er erklært i sideklassen ved hjelp av PageFactory.InitElement () .
Vi starter ikke driveren her, snarere blir forekomsten mottatt fra hovedklassen når objektet til sidelagsklassen blir opprettet.
InitElement () - brukes til å initialisere WebElements deklarert, ved hjelp av driverinstans fra hovedklassen. Med andre ord, WebElements opprettes ved hjelp av driverinstansen. Først etter at WebElements er initialisert, kan de brukes i metodene for å utføre handlinger.
To Java-klasser opprettes for hver side som vist nedenfor:
Hjemmeside.java
//package com.automation.pages; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; public class HomePage { WebDriver driver; // Locator for Email Address @FindBy(how=How.ID,using='EmailId') private WebElement EmailIdAddress; // Locator for Password field @FindBy(how=How.ID,using='Password ') private WebElement Password; // Locator for SignIn Button @FindBy(how=How.ID,using='SignInButton') private WebElement SignInButton; // Method to type EmailId public void typeEmailId(String Id){ driver.findElement(EmailAddress).sendKeys(Id) } // Method to type Password public void typePassword(String PasswordValue){ driver.findElement(Password).sendKeys(PasswordValue) } // Method to click SignIn Button public void clickSignIn(){ driver.findElement(SignInButton).click() } // Constructor // Gets called when object of this page is created in MainClass.java public HomePage(WebDriver driver) { // 'this' keyword is used here to distinguish global and local variable 'driver' //gets driver as parameter from MainClass.java and assigns to the driver instance in this class this.driver=driver; PageFactory.initElements(driver,this); // Initialises WebElements declared in this class using driver instance. } }
SearchPage.Java
//package com.automation.pages; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; public class SearchPage{ WebDriver driver; // Locator for Success Message @FindBy(how=How.ID,using='Message') private WebElement SuccessMessage; // Method that return True or False depending on whether the message is displayed public Boolean MessageDisplayed(){ Boolean status = driver.findElement(SuccessMessage).isDisplayed(); return status; } // Constructor // This constructor is invoked when object of this page is created in MainClass.java public SearchPage(WebDriver driver) { // 'this' keyword is used here to distinguish global and local variable 'driver' //gets driver as parameter from MainClass.java and assigns to the driver instance in this class this.driver=driver; PageFactory.initElements(driver,this); // Initialises WebElements declared in this class using driver instance. } }
Test lag
Test tilfeller er implementert i denne klassen. Vi lager en egen pakke si, com.automation.test og oppretter deretter en Java-klasse her (MainClass.java)
Fremgangsmåte for å lage testsaker:
- Initialiser driveren og åpne applikasjonen.
- Opprett et objekt fra PageLayer-klassen (for hver webside) og send driverinstansen som en parameter.
- Bruk objektet som er opprettet, ring til metodene i PageLayer-klassen (for hver webside) for å utføre handlinger / verifisering.
- Gjenta trinn 3 til alle handlingene er utført, og lukk deretter driveren.
//package com.automation.test; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; public class MainClass { public static void main(String() args) { System.setProperty('webdriver.chrome.driver','./exefiles/chromedriver.exe'); WebDriver driver= new ChromeDriver(); driver.manage().window().maximize(); driver.get('URL mentioned here'); // Creating object of HomePage and driver instance is passed as parameter to constructor of Homepage.Java HomePage homePage= new HomePage(driver); // Type EmailAddress homePage.typeEmailId('abc@ymail.com'); // EmailId value is passed as paramter which in turn will be assigned to the method in HomePage.Java // Type Password Value homePage.typePassword('password123'); // Password value is passed as paramter which in turn will be assigned to the method in HomePage.Java // Click on SignIn Button homePage.clickSignIn(); // Creating an object of LoginPage and driver instance is passed as parameter to constructor of SearchPage.Java SearchPage searchPage= new SearchPage(driver); //Verify that Success Message is displayed Assert.assertTrue(searchPage.MessageDisplayed()); //Quit browser driver.quit(); } }
Kommentarhierarki som brukes til å deklarere WebElements
Kommentarer brukes til å lage en lokaliseringsstrategi for UI Elements.
# 1) @FindBy
Når det gjelder Pagefactory, fungerer @FindBy som en magisk tryllestav. Det tilfører all kraften til konseptet. Du er nå klar over at @FindBy-merknaden i Pagefactory utfører det samme som driver.findElement () i den vanlige sideobjektmodellen. Den brukes til å finne WebElement / WebElements med ett kriterium .
# 2) @FindBys
Den brukes til å finne WebElement med mer enn ett kriterium og må matche alle gitte kriterier. Disse kriteriene bør nevnes i et foreldre-barn forhold. Med andre ord, dette bruker OG betinget forhold for å lokalisere WebElements ved hjelp av kriteriene som er spesifisert. Den bruker flere @ FindBy for å definere hvert kriterium.
For eksempel:
HTML-kildekode for et WebElement:
I POM:
@FindBys({ @FindBy(id = 'searchId_1'), @FindBy(name = 'search_field') }) WebElementSearchButton;
I eksemplet ovenfor ligger WebElement 'SearchButton' bare hvis den samsvarer med begge deler kriteriene hvis id-verdi er “searchId_1” og navnverdien er “search_field”. Vær oppmerksom på at de første kriteriene tilhører en overordnet tag og det andre kriteriet for en underordnet tag.
# 3) @FindAll
Den brukes til å finne WebElement med mer enn ett kriterium og den må samsvare med minst ett av de gitte kriteriene. Dette bruker ELLER betingede forhold for å finne WebElements. Den bruker flere @ FindBy for å definere alle kriteriene.
For eksempel:
HTML kildekode:
I POM:
@FindBys({ @FindBy(id = 'UsernameNameField_1'), // doesn’t match @FindBy(name = 'User_Id') //matches @FindBy(className = “UserName_r”) //matches }) WebElementUserName;
I eksemplet ovenfor ligger WebElement ‘Brukernavn hvis det samsvarer med minst en av kriteriene nevnt.
# 4) @CacheLookUp
Når WebElement oftere brukes i testtilfeller, ser Selenium opp for WebElement hver gang testskriptet kjøres. I de tilfellene hvor visse WebElements brukes globalt for alle TC ( For eksempel, Innloggingsscenario skjer for hver TC), denne merknaden kan brukes til å opprettholde disse WebElements i hurtigminnet når den leses for første gang.
Dette hjelper igjen koden til å kjøre raskere fordi hver gang den ikke trenger å søke etter WebElement på siden, snarere kan den få sin referanse fra minnet.
Dette kan være som et prefiks med alle @FindBy, @FindBys og @FindAll.
For eksempel:
@CacheLookUp @FindBys({ @FindBy(id = 'UsernameNameField_1'), @FindBy(name = 'User_Id') @FindBy(className = “UserName_r”) }) WebElementUserName;
Vær også oppmerksom på at denne merknaden bare skal brukes til WebElements hvis attributtverdi (som xpath, id-navn, klassenavn osv.) Ikke endres ganske ofte. Når WebElement er lokalisert for første gang, opprettholder den referansen i hurtigminnet.
Så skjer det en endring i WebElement-attributtet etter noen dager, Selenium vil ikke være i stand til å finne elementet, fordi det allerede har sin gamle referanse i hurtigbufferminnet og ikke vil vurdere den nylige endringen i WebElement.
Mer på PageFactory.initElements ()
Nå som vi forstår strategien til Pagefactory for initialisering av webelementene ved hjelp av InitElements (), la oss prøve å forstå de forskjellige versjonene av metoden.
Metoden som vi kjenner tar driverobjektet og det gjeldende klasseobjektet som inndataparametere og returnerer sideobjektet ved implisitt og proaktivt å initialisere alle elementene på siden.
I praksis er bruken av konstruktøren som vist i avsnittet ovenfor mer å foretrekke fremfor de andre måtene for bruken.
Alternative måter å ringe metoden på er:
#1) I stedet for å bruke 'denne' pekeren, kan du opprette det gjeldende klasseobjektet, sende driverforekomsten til det og kalle den statiske metoden initElements med parametere, dvs. driverobjektet og klasseobjektet som nettopp ble opprettet.
public PagefactoryClass(WebDriver driver) { //version 2 PagefactoryClass page=new PagefactoryClass(driver); PageFactory.initElements(driver, page); }
#to) Den tredje måten å initialisere elementer ved bruk av Pagefactory-klassen er ved å bruke api kalt “refleksjon”. Ja, i stedet for å lage et klasseobjekt med et 'nytt' nøkkelord, kan classname.class sendes som en del av inndataparameteren initElements ().
public PagefactoryClass(WebDriver driver) { //version 3 PagefactoryClass page=PageFactory.initElements(driver, PagefactoryClass.class); }
ofte stilte spørsmål
Q # 1) Hva er de forskjellige lokaliseringsstrategiene som brukes til @FindBy?
Svar: Det enkle svaret på dette er at det ikke er noen forskjellige lokaliseringsstrategier som brukes til @FindBy.
De bruker de samme 8 lokaliseringsstrategiene som findElement () -metoden i den vanlige POM bruker:
- id
- Navn
- klassenavn
- xpath
- css
- tagName
- linkText
- partialLinkText
Q # 2) Er det forskjellige versjoner av bruken av @FindBy-merknader også?
Svar: Når det er et webelement som skal søkes, bruker vi merknaden @FindBy. Vi vil utdype alternative måter å bruke @FindBy sammen med de forskjellige lokaliseringsstrategiene også.
Vi har allerede sett hvordan du bruker versjon 1 av @FindBy:
@FindBy(id = 'cidkeyword') WebElement Symbol;
Versjon 2 av @FindBy er ved å sende inngangsparameteren som Hvordan og Ved hjelp av .
Hvordan ser etter lokaliseringsstrategien der webelementet vil bli identifisert. Nøkkelordet ved hjelp av definerer lokaliseringsverdien.
Se nedenfor for bedre forståelse,
- How.ID søker i elementet ved hjelp av id strategi og elementet den prøver å identifisere har id = cidkeyword.
@FindBy(how = How.ID, using = ' cidkeyword') WebElement Symbol;
- How.CLASS_NAME søker i elementet ved hjelp av klassenavn strategi og elementet den prøver å identifisere har klasse = newclass.
@FindBy(how = How.CLASS_NAME, using = 'newclass') WebElement Symbol;
Q # 3) Er det forskjell på de to versjonene av @FindBy?
Svar: Svaret er nei, det er ingen forskjell mellom de to versjonene. Det er bare at den første versjonen er den kortere og enklere sammenlignet med den andre versjonen.
Sp # 4) Hva bruker jeg i sidefabrikken i tilfelle det er en liste over webelementer som skal lokaliseres?
Svar: I det vanlige mønsteret for sideobjektdesign har vi driver.findElements () for å finne flere elementer som tilhører samme klasse eller taggenavn, men hvordan finner vi slike elementer når det gjelder sideobjektmodell med Pagefactory? Den enkleste måten å oppnå slike elementer på er å bruke den samme merknaden @FindBy.
Jeg forstår at denne linjen ser ut til å være en hodeskrape for mange av dere. Men ja, det er svaret på spørsmålet.
La oss se på eksemplet nedenfor:
Ved å bruke den vanlige sideobjektmodellen uten Pagefactory, bruker du driver.findElements til å finne flere elementer som vist nedenfor:
private List multipleelements_driver_findelements = driver.findElements (By.class(“last”));
Det samme kan oppnås ved hjelp av sideobjektmodellen med Pagefactory som gitt nedenfor:
@FindBy (how = How.CLASS_NAME, using = 'last') private List multipleelements_FindBy;
I utgangspunktet gjør det å knytte elementene til en liste av typen WebElement, uansett om Pagefactory er brukt eller ikke mens du identifiserer og lokaliserer elementene.
Q # 5) Kan både design av sideobjekt uten sidefabrikk og med Pagefactory brukes i samme program?
Svar: Ja, både sideobjektdesign uten Pagefactory og med Pagefactory kan brukes i samme program. Du kan gå gjennom programmet gitt nedenfor i Svar på spørsmål nr. 6 for å se hvordan begge brukes i programmet.
En ting å huske er at Pagefactory-konseptet med hurtigbufret funksjon bør unngås på dynamiske elementer, mens sideobjektdesign fungerer bra for dynamiske elementer. Imidlertid passer Pagefactory bare til statiske elementer.
Sp # 6) Finnes det alternative måter å identifisere elementer basert på flere kriterier?
youtube til mp3 lenger enn 30 minutter
Svar: Alternativet for å identifisere elementer basert på flere kriterier er å bruke kommentarene @FindAll og @FindBys. Disse merknadene hjelper til med å identifisere enkeltelementer eller flere elementer, avhengig av verdiene hentet fra kriteriene som er gitt i den.
# 1) @FindAll:
@FindAll kan inneholde flere @FindBy og returnerer alle elementene som samsvarer med alle @FindBy i en enkelt liste. @FindAll brukes til å markere et felt på et sideobjekt for å indikere at oppslaget skal bruke en serie @FindBy-koder. Deretter vil den søke etter alle elementene som samsvarer med noen av FindBy-kriteriene.
Merk at elementene ikke garanteres å være i dokumentrekkefølge.
Syntaksen for å bruke @FindAll er som nedenfor:
@FindAll( { @FindBy(how = How.ID, using = 'foo'), @FindBy(className = 'bar') } )
Forklaring: @FindAll vil søke og identifisere separate elementer som samsvarer med hvert av @FindBy-kriteriene og liste dem ut. I eksemplet ovenfor vil det først søke i et element hvis id = ”foo” og deretter identifisere det andre elementet med className = ”bar”.
Forutsatt at det var ett element identifisert for hvert FindBy-kriterium, vil @FindAll resultere i henholdsvis å liste ut 2 elementer. Husk at det kan være flere elementer identifisert for hvert kriterium. Dermed, med enkle ord, @ Finn alle fungerer tilsvarer ELLER operatøren på @FindBy-kriteriene bestått.
# 2) @FindBys:
FindBys brukes til å markere et felt på et sideobjekt for å indikere at oppslag skal bruke en serie @FindBy-koder i en kjede som beskrevet i ByChained. Når de nødvendige WebElement-objektene må samsvare med alle gitte kriterier, bruk @FindBys-merknaden.
Syntaksen for å bruke @FindBys er som nedenfor:
@FindBys( { @FindBy(name=”foo”) @FindBy(className = 'bar') } )
Forklaring: @FindBys vil søke og identifisere elementer som samsvarer med alle @FindBy-kriteriene og liste dem ut. I eksemplet ovenfor vil det søke i elementer hvis navn = ”foo” og className = ”bar”.
@FindAll vil føre til å liste ut 1 element hvis vi antar at det var ett element identifisert med navnet og className i de gitte kriteriene.
Hvis det ikke er ett element som tilfredsstiller alle FindBy-betingelsene som er bestått, vil resultatet av @FindBys være null elementer. Det kan være en liste over webelementer som er identifisert hvis alle forholdene tilfredsstiller flere elementer. Med enkle ord, @ FindBys fungerer tilsvarer OG operatøren på @FindBy-kriteriene bestått.
La oss se gjennomføringen av alle ovennevnte merknader gjennom et detaljert program:
Vi vil endre www.nseindia.com-programmet gitt i forrige avsnitt for å forstå implementeringen av kommentarene @FindBy, @FindBys og @FindAll
# 1) Objektregisteret til PagefactoryClass oppdateres som nedenfor:
Liste newlist = driver.findElements (By.tagName (“a”));
@FindBy (hvordan = hvordan. TAG_NAME , bruker = “a”)
privat Listefunnverdi;
@FindAll ({ @FindBy (className = “sel”), @FindBy (xpath = ”// a (@ id =’ tab5 ′) ”)})
privat Liste findallvalue;
@FindBys ({ @FindBy (className = “sel”), @FindBy (xpath = ”// a (@ id =’ tab5 ′) ”)})
privat Liste findbysvalue;
# 2) En ny metode seeHowFindWorks () er skrevet i PagefactoryClass og blir påkalt som den siste metoden i hovedklassen.
Metoden er som nedenfor:
private void seeHowFindWorks() { System.out.println('driver.findElements(By.tagName()) '+newlist.size()); System.out.println('count of @FindBy- list elements '+findbyvalue.size()); System.out.println('count of @FindAll elements '+findallvalue.size()); for(int i=0;i Nedenfor vises resultatet som vises på konsollvinduet etter gjennomføring av programmet:

La oss nå prøve å forstå koden i detalj:
#1) Gjennom designmønsteret for sideobjektet identifiserer elementet 'newlist' alle kodene med anker 'a'. Med andre ord får vi opptelling av alle lenkene på siden.
Vi lærte at sidefabrikken @FindBy gjør den samme jobben som driver.findElement (). Elementet findbyvalue er opprettet for å få antall lenker på siden gjennom en søkestrategi som har et sidefabrikksbegrep.
Det viser seg å være riktig at både driver.findElement () og @FindBy gjør den samme jobben og identifiserer de samme elementene. Hvis du ser på skjermbildet av det resulterende konsollvinduet ovenfor, er antallet lenker som er identifisert med elementet newlist og findbyvalue, det samme. 299 lenker funnet på siden.
Resultatet viste som nedenfor:
driver.findElements(By.tagName()) 299 count of @FindBy- list elements 299
#to) Her utdyper vi arbeidet med @FindAll-merknaden som gjelder listen over webelementene med navnet findallvalue.
Når du ser nøye på hvert @FindBy-kriterium i @FindAll-kommentaren, søker det første @FindBy-kriteriet etter elementer med className = 'sel' og det andre @FindBy-kriteriet søker etter et bestemt element med XPath = “// a (@ id = 'tab5')
La oss nå trykke på F12 for å inspisere elementene på siden nseindia.com og få visse klarheter om elementer som tilsvarer @FindBy-kriteriene.
Det er to elementer på siden som tilsvarer className = ”sel”:
til) Elementet 'Fundamentals' har listelappen dvs.
med className = ”sel”. Se øyeblikksbilde nedenfor

b) Et annet element 'Order Book' har en XPath med et ankermerke som har klassenavnet som 'sel'.

c) Den andre @FindBy med XPath har en ankerkode hvis id er ' tab5 ”. Det er bare ett element identifisert som svar på søket, som er grunnleggende.
Se øyeblikksbildet nedenfor:

Da nseindia.com-testen ble utført, fikk vi antall elementer som ble søkt etter.
@FindAll som 3. Elementene for findallvalue når de ble vist var: Fundamentals som 0thindekselement, ordrebok som 1St.indekselement og Fundamentals igjen som 2ndindekselement. Vi har allerede lært at @FindAll identifiserer elementer for hvert @ FindBy-kriterium separat.
I henhold til samme protokoll, for det første kriteriesøket, dvs. className = ”sel”, identifiserte den to elementer som tilfredsstilte betingelsen, og den hentet 'Fundamentals' og 'Order Book'.
Deretter flyttet den til neste @ FindBy-kriterier og i henhold til xpath gitt for den andre @ FindBy, kunne den hente elementet 'Fundamentals'. Dette er grunnen til at den endelig identifiserte henholdsvis 3 elementer.
Dermed får den ikke elementene som tilfredsstiller noen av @FindBy-forholdene, men den håndterer hver av @FindBy separat og identifiserer elementene på samme måte. I tillegg, i det gjeldende eksemplet, så vi også at den ikke ser om elementene er unike ( F.eks. Elementet 'Fundamentals' i dette tilfellet som ble vist to ganger som en del av resultatet av de to @FindBy-kriteriene)
# 3) Her utdyper vi arbeidet med @FindBys-merknaden som gjelder listen over nettelementene med navnet findbysvalue. Også her søker det første @FindBy-kriteriet etter elementer med className = ’sel’ og det andre @FindBy-kriteriet søker etter et bestemt element med xpath = “// a (@ id =” tab5 ”).
Nå som vi vet, er elementene som er identifisert for den første @FindBy-tilstanden, 'Fundamentals' og 'Order Book', og det av det andre @FindBy-kriteriet er 'Fundamentals'.
Så, hvordan vil @FindBys resultant være annerledes enn @FindAll? Vi lærte i forrige seksjon at @FindBys tilsvarer AND-betinget operatør, og det ser derfor etter et element eller listen over elementer som tilfredsstiller alle @FindBy-tilstanden.
I henhold til vårt nåværende eksempel er verdien 'Fundamentals' det eneste elementet som har class = 'sel' og id = 'tab5', og tilfredsstiller begge betingelsene. Dette er grunnen til at @FindBys størrelse i testtasken er 1, og den viser verdien som 'Fundamentals'.
Caching The Elements In Pagefactory
Hver gang en side lastes inn, blir alle elementene på siden slått opp igjen ved å påkalle et anrop gjennom @FindBy eller driver.findElement (), og det er et nytt søk etter elementene på siden.
Det meste av tiden når elementene er dynamiske eller endrer seg i løpet av kjøretiden, spesielt hvis de er AJAX-elementer, er det absolutt fornuftig at det med hvert sidelast er et nytt søk etter alle elementene på siden.
Når nettsiden har statiske elementer, kan caching av elementet hjelpe på flere måter. Når elementene er bufret, trenger det ikke å finne elementene igjen når siden lastes inn, i stedet kan den referere til det lagrede elementet. Dette sparer mye tid og løfter bedre ytelse.
Pagefactory gir denne funksjonen for å cache elementene ved hjelp av en kommentar @CacheLookUp .
Merknaden forteller sjåføren å bruke den samme forekomsten av lokalisatoren fra DOM for elementene og ikke å søke dem igjen mens initElements-metoden til sidefabrikken fremtredende bidrar til lagring av det bufrede statiske elementet. InitiLements gjør elementenes caching-jobb.
Dette gjør sidefabrikkskonseptet spesielt over det vanlige mønsteret for design av sider. Den kommer med sine egne fordeler og ulemper som vi vil diskutere litt senere. For eksempel er påloggingsknappen på Facebook-hjemmesiden et statisk element som kan caches og er et ideelt element å bli bufret.
La oss nå se på hvordan vi implementerer merknaden @CacheLookUp
Du må først importere en pakke for Cachelookup som nedenfor:
import org.openqa.selenium.support.CacheLookup
Nedenfor er kodebiten som viser definisjonen av et element ved hjelp av @CacheLookUp. Så snart UniqueElement blir søkt for første gang, lagrer initElement () den hurtigbufrede versjonen av elementet, slik at neste gang driveren ikke ser etter elementet, refererer den til samme cache og utfører handlingen på elementet til høyre borte.
@FindBy(id = 'unique') @CacheLookup private WebElement UniqueElement;
La oss nå se gjennom et faktisk program for hvordan handlinger på det bufrede webelementet er raskere enn det på det ikke bufret webelementet:
Forbedring av nseindia.com-programmet videre har jeg skrevet en annen ny metode monitorPerformance () der jeg oppretter et hurtigbufret element for søkeboksen og et ikke-hurtigbufret element for samme søkefelt.
Så prøver jeg å få taket på elementet 3000 ganger for både bufret og ikke-hurtigbufret element og prøver å måle tiden det tar å fullføre oppgaven av både hurtigbufret og ikke-hurtigbufret element.
Jeg har vurdert 3000 ganger slik at vi er i stand til å se en synlig forskjell i timingene for de to. Jeg forventer at det bufrede elementet skal fullføre å få tagnamnet 3000 ganger på kortere tid sammenlignet med elementet for ikke-bufret element.
Vi vet nå hvorfor det hurtigbufrede elementet skal fungere raskere, dvs. at sjåføren blir bedt om ikke å slå opp elementet etter første oppslag, men fortsette å jobbe direkte med det, og det er ikke tilfelle med ikke-hurtigbufret element der elementoppslaget er gjort for alle 3000 ganger, og deretter utføres handlingen på den.
Nedenfor er koden for metoden monitorPerformance ():
private void monitorPerformance() { //non cached element long NoCache_StartTime = System.currentTimeMillis(); for(int i = 0; i <3000; i ++) { Searchbox.getTagName(); } long NoCache_EndTime = System.currentTimeMillis(); long NoCache_TotalTime=(NoCache_EndTime-NoCache_StartTime)/1000; System.out.println('Response time without caching Searchbox ' + NoCache_TotalTime+ ' seconds'); //cached element long Cached_StartTime = System.currentTimeMillis(); for(int i = 0; i < 3000; i ++) { cachedSearchbox.getTagName(); } long Cached_EndTime = System.currentTimeMillis(); long Cached_TotalTime=(Cached_EndTime - Cached_StartTime)/1000; System.out.println('Response time by caching Searchbox ' + Cached_TotalTime+ ' seconds'); }
Ved kjøring vil vi se resultatet nedenfor i konsollvinduet:
I henhold til resultatet er oppgaven på ikke-hurtigbufret element fullført i 82 sekunder mens tiden det tok å fullføre oppgaven på hurtigbufret element bare var 37 sekunder. Dette er faktisk en synlig forskjell i responstid for både bufret og ikke-bufret element.

Sp # 7) Hva er fordeler og ulemper med merknaden @CacheLookUp i Pagefactory-konseptet?
Svar:
Fordeler @CacheLookUp og situasjoner som er mulige for bruken:
@CacheLookUp er mulig når elementene er statiske eller ikke endres i det hele tatt mens siden er lastet inn. Slike elementer endrer ikke kjøretiden. I slike tilfeller anbefales det å bruke merknaden for å forbedre den totale hastigheten på testutførelsen.
Ulemper med kommentaren @CacheLookUp:
Den største ulempen med å ha elementer bufret med kommentaren er frykten for å få StaleElementReferenceExceptions ofte.
Dynamiske elementer oppdateres ganske ofte med de som er utsatt for endring raskt over noen få sekunder eller minutter av tidsintervallet.
Nedenfor er noen få slike forekomster av de dynamiske elementene:
- Å ha et stoppeklokke på websiden som holder timeren oppdatert hvert sekund.
- En ramme som kontinuerlig oppdaterer værmeldingen.
- En side som rapporterer de live Sensex-oppdateringene.
Disse er ikke ideelle eller gjennomførbare for bruk av merknaden @CacheLookUp i det hele tatt. Hvis du gjør det, risikerer du å få unntaket StaleElementReferenceExceptions.
Ved caching av slike elementer, under testutførelse, endres DOM-en til elementene, men driveren ser etter den versjonen av DOM som allerede var lagret under hurtigbufring. Dette gjør at det foreldede elementet blir slått opp av føreren som ikke lenger eksisterer på websiden. Dette er grunnen til at StaleElementReferenceException blir kastet.
Fabrikklasser:
Pagefactory er et konsept bygget på flere fabrikklasser og grensesnitt. Vi vil lære om noen få fabrikklasser og grensesnitt her i denne delen. Få av disse vil vi se på AjaxElementLocatorFactory , ElementLocatorFactory og StandardElementFactory.
Har vi noen gang lurt på om Pagefactory gir noen måte å innlemme Implisitt eller Eksplisitt vent på elementet til en bestemt tilstand er oppfylt ( Eksempel: Inntil et element er synlig, aktivert, klikkbart, etc.)? Hvis ja, her er et passende svar på det.
AjaxElementLocatorFactory er en av de viktigste bidragsyterne blant alle fabrikklassene. Fordelen med AjaxElementLocatorFactory er at du kan tilordne en tidsavbruddsverdi for et webelement til Object-sideklassen.
Selv om Pagefactory ikke gir en eksplisitt ventefunksjon, er det imidlertid en variant som implisitt venter med klassen AjaxElementLocatorFactory . Denne klassen kan brukes innlemmet når applikasjonen bruker Ajax-komponenter og -elementer.
Slik implementerer du det i koden. Innen konstruktøren, når vi bruker metoden initElements (), kan vi bruke AjaxElementLocatorFactory for å gi en implisitt venting på elementene.
PageFactory.initElements(driver, this); can be replaced with PageFactory.initElements( new AjaxElementLocatorFactory(driver, 20), this);
Ovenstående andre linje i koden innebærer at sjåføren skal angi en tidsavbrudd på 20 sekunder for alle elementene på siden når hver av dens laster, og hvis noe av elementet ikke blir funnet etter en ventetid på 20 sekunder, kastes 'NoSuchElementException' for det manglende elementet.
Du kan også definere ventetiden som nedenfor:
public pageFactoryClass(WebDriver driver) { ElementLocatorFactory locateMe = new AjaxElementLocatorFactory(driver, 30); PageFactory.initElements(locateMe, this); this.driver = driver; }
Ovennevnte kode fungerer perfekt fordi klassen AjaxElementLocatorFactory implementerer grensesnittet ElementLocatorFactory.
Her refererer foreldregrensesnittet (ElementLocatorFactory) til objektet til barneklassen (AjaxElementLocatorFactory). Derfor brukes Java-konseptet 'upcasting' eller 'runtime polymorphism' mens du tildeler en timeout ved hjelp av AjaxElementLocatorFactory.
Når det gjelder hvordan det fungerer teknisk, oppretter AjaxElementLocatorFactory først en AjaxElementLocator ved hjelp av en SlowLoadableComponent som kanskje ikke er ferdig lastet når belastningen () returnerer. Etter en samtale om å laste (), skal metoden isLoaded () fortsette å mislykkes til komponenten er fulladet.
Med andre ord, alle elementene vil bli slått opp hver gang når et element er tilgjengelig i koden ved å påkalle et anrop til locator.findElement () fra AjaxElementLocator-klassen som deretter bruker en tidsavbrudd til den lastes gjennom SlowLoadableComponent-klassen.
I tillegg, etter å ha tilordnet tidsavbrudd via AjaxElementLocatorFactory, vil ikke elementene med @CacheLookUp-merknaden lenger bli hurtigbufret, siden merknaden vil bli ignorert.
Det er også en variasjon i hvordan du kan Ring initiativer () metode og hvordan du burde ikke Ring AjaxElementLocatorFactory for å tildele timeout for et element.
# 1) Du kan også spesifisere et elementnavn i stedet for driverobjektet som vist nedenfor i metoden initElements ():
PageFactory.initElements( , this);
initElements () -metoden i ovennevnte variant påkaller internt et anrop til klassen DefaultElementFactory, og DefaultElementFactory's konstruktør godtar SearchContext-grensesnittobjektet som en inputparameter. Webdriverobjekt og et webelement hører begge til SearchContext-grensesnittet.
I dette tilfellet vil initElements () -metoden initialiseres på forhånd bare til det nevnte elementet, og ikke alle elementene på websiden vil bli initialisert.
#to) Her er imidlertid en interessant vri på dette faktum som sier hvordan du ikke skal kalle AjaxElementLocatorFactory objekt på en bestemt måte. Hvis jeg bruker ovennevnte variant av initElements () sammen med AjaxElementLocatorFactory, vil den mislykkes.
Eksempel: Koden nedenfor, dvs. å sende elementnavn i stedet for driverobjekt til AjaxElementLocatorFactory-definisjonen, vil ikke fungere da konstruktøren for AjaxElementLocatorFactory-klassen tar bare webdriverobjektet som inndataparameter, og derfor vil SearchContext-objektet med webelement ikke fungere for det.
PageFactory.initElements(new AjaxElementLocatorFactory(, 10), this);
Q # 8) Er det mulig å bruke sidefabrikken i forhold til det vanlige mønsteret for sideobjektdesign?
Svar: Dette er det viktigste spørsmålet folk har, og det er derfor jeg tenkte å ta opp det på slutten av opplæringen. Vi kjenner nå ‘inn og ut’ om Pagefactory med utgangspunkt i konseptene, brukte merknader, tilleggsfunksjoner den støtter, implementering via kode, fordeler og ulemper.
Likevel forblir vi med dette viktige spørsmålet om at hvis sidefabrikken har så mange gode ting, hvorfor skal vi ikke holde fast ved bruken av den.
Pagefactory kommer med konseptet CacheLookUp som vi så ikke er mulig for dynamiske elementer som verdiene til elementet blir oppdatert ofte. Så, sidefaktorisk uten CacheLookUp, er det et alternativ å gå bra? Ja, hvis stiene er statiske.
Imidlertid er undergangen at moderne tidsapplikasjon er fylt med tunge dynamiske elementer der vi vet at sideobjektdesignet uten sidefabrikk til slutt fungerer bra, men fungerer sidefabrikksbegrepet like bra med dynamiske xpaths? Kanskje ikke. Her er et raskt eksempel:
På nettsiden nseindia.com ser vi en tabell som gitt nedenfor.

Xpath av tabellen er
'//*(@id='tab9Content')/table/tbody/tr(+count+)/td(1)'
Vi ønsker å hente verdier fra hver rad for den første kolonnen 'Kjøp Antall'. For å gjøre dette må vi øke radtelleren, men kolonneindeksen vil forbli 1. Det er ingen måte at vi kan overføre denne dynamiske XPath i @FindBy-merknaden, da merknaden godtar verdier som er statiske og ingen variabler kan sendes videre den.
Her mislykkes sidefabrikken helt mens den vanlige POM fungerer bra med den. Du kan enkelt bruke en for loop til å øke radindeksen ved å bruke slike dynamiske xpaths i metoden driver.findElement ().
Konklusjon
Page Object Model er et designkonsept eller mønster som brukes i Selenium automation framework.
Å navngi konveksjon av metoder er brukervennlig i Page Object Model. Koden i POM er lett å forstå, gjenbrukbar og vedlikeholdbar. I POM, hvis det er noen endring i webelementet, er det nok å gjøre endringene i sin respektive klasse, i stedet for å redigere alle klassene.
Pagefactory akkurat som den vanlige POM er et fantastisk konsept å bruke. Vi må imidlertid vite hvor den vanlige POM er mulig og hvor Pagefactory passer bra. I de statiske applikasjonene (der både XPath og elementene er statiske), kan Pagefactory implementeres med fordel med tilleggsfordeler med bedre ytelse.
Alternativt, når applikasjonen involverer både dynamiske og statiske elementer, kan du ha en blandet implementering av pom med Pagefactory og det uten Pagefactory i henhold til muligheten for hvert webelement.
Forfatter: Denne opplæringen er skrevet av Shobha D. Hun jobber som prosjektleder og har 9+ års erfaring innen manuell, automatisering (Selenium, IBM Rational Functional Tester, Java) og API Testing (SOAPUI og være trygg på Java) .
Nå over til deg, for videre implementering av Pagefactory.
Happy Exploring !!!
=> Besøk her for å lære selen fra grunnen.
Anbefalt lesing
- 30+ beste selenopplæringsprogrammer: Lær selen med virkelige eksempler
- Effektiv Selen Scripting og feilsøking av scenarier - Selenium Tutorial # 27
- Feilsøking av selen-skript med logger (Log4j-opplæring) - Selen-opplæring # 26
- Introduksjon til JUnit Framework and Its Usage in Selenium Script - Selenium Tutorial # 11
- 7 faktorer som påvirker testestimering av Selenium Automation Project - Selenium Tutorial # 32
- Påstander i selen ved bruk av Junit And TestNG Frameworks
- Hvordan bruke TestNG Framework for å lage selenskript - TestNG Selen Tutorial # 12
- Lær hvordan du bruker TestNG-merknader i selen (med eksempler)