page object model with page factory selenium tutorial
Acest tutorial detaliat explică totul despre modelul de obiect de pagină (POM) cu Pagefactory folosind exemple. Puteți afla, de asemenea, implementarea POM în seleniu:
În acest tutorial, vom înțelege cum să creați un model de obiect de pagină folosind abordarea Factory Factory. Ne vom concentra pe:
- Clasa fabricii
- Cum se creează un POM de bază folosind modelul de fabrică a paginii
- Diferite adnotări utilizate în abordarea fabricii de pagini
Înainte de a vedea ce este Pagefactory și cum poate fi folosit împreună cu modelul de obiect Page, să înțelegem ce este Page Object Model, cunoscut în mod obișnuit sub numele de POM.
=> Vizitați aici pentru a vedea seria de antrenament Selenium pentru toți.
Ce veți învăța:
- Ce este modelul de obiect de pagină (POM)?
- Ce este Pagefactory?
- POM folosind Fabrica de pagini
- întrebări frecvente
- Concluzie
Ce este modelul de obiect de pagină (POM)?
Terminologiile teoretice descriu Model de obiect de pagină ca model de proiectare utilizat pentru a construi un depozit de obiecte pentru elementele web disponibile în aplicația testată. Puțini alții se referă la acesta ca un cadru pentru automatizarea Selenium pentru aplicația dată testată.
Totuși, ceea ce am înțeles despre termenul Model de obiect de pagină este:
# 1) Este un model de proiectare în care aveți un fișier de clasă Java separat corespunzător fiecărui ecran sau pagină din aplicație. Fișierul de clasă ar putea include depozitul de obiecte al elementelor UI, precum și metodele.
#Două) În cazul în care pe o pagină există elemente web imense, clasa de depozit de obiecte pentru o pagină poate fi separată de clasa care include metode pentru pagina corespunzătoare.
Exemplu: Dacă pagina Înregistrare cont are multe câmpuri de intrare, atunci ar putea exista o clasă RegisterAccountObjects.java care formează depozitul de obiecte pentru elementele UI de pe pagina conturilor de înregistrare.
Ar putea fi creat un fișier de clasă separat RegisterAccount.java care extinde sau moștenește RegisterAccountObjects care include toate metodele care efectuează diferite acțiuni pe pagină.
# 3) În plus, ar putea exista un pachet generic cu un fișier {roperties, date de testare Excel și metode comune sub un pachet.
Exemplu: DriverFactory care ar putea fi utilizat foarte ușor pe toate paginile din aplicație
Înțelegerea POM cu un exemplu
Verifica Aici pentru a afla mai multe despre POM.
Mai jos este un instantaneu al paginii web:

Dacă faceți clic pe fiecare dintre aceste linkuri, veți redirecționa utilizatorul către o pagină nouă.
Iată instantaneul modului în care este construită structura proiectului cu Selenium folosind modelul de obiect Page corespunzător fiecărei pagini de pe site. Fiecare clasă Java include depozit de obiecte și metode pentru efectuarea acțiunilor diferite în cadrul paginii.
În plus, va exista un alt JUNIT sau TestNG sau un fișier de clasă Java care invocă apeluri către fișiere de clasă ale acestor pagini.

De ce folosim modelul de obiect de pagină?
Există un buzz în jurul utilizării acestui cadru puternic Selenium numit POM sau model de obiect de pagină. Acum, întrebarea apare ca „De ce să folosiți POM?”.
Răspunsul simplu la acest lucru este că POM este o combinație de cadre bazate pe date, modulare și hibride. Este o abordare a organizării sistematice a scripturilor în așa fel încât să faciliteze controlul calității pentru a menține codul fără probleme și, de asemenea, ajută la prevenirea codului redundant sau duplicat.
De exemplu, dacă există o modificare a valorii localizatorului pe o anumită pagină, atunci este foarte ușor să identificați și să faceți acea schimbare rapidă numai în scriptul paginii respective, fără a afecta codul în altă parte.
Utilizăm conceptul Page Object Model în Selenium Webdriver din următoarele motive:
- Un depozit de obiecte este creat în acest model POM. Este independent de cazurile de testare și poate fi reutilizat pentru un proiect diferit.
- Convenția de numire a metodelor este foarte ușoară, ușor de înțeles și mai realistă.
- Sub modelul obiectului Pagină, creăm clase de pagini care pot fi refolosite într-un alt proiect.
- Modelul de obiecte Page este ușor pentru cadrul dezvoltat datorită câtorva avantaje ale acestuia.
- În acest model, sunt create clase separate pentru diferite pagini ale unei aplicații web, cum ar fi pagina de conectare, pagina de pornire, pagina de detalii a angajaților, pagina de modificare a parolei etc.
- Dacă există vreo modificare în orice element al unui site web, trebuie să facem modificări doar într-o singură clasă și nu în toate clasele.
- Scriptul conceput este mai reutilizabil, mai lizibil și mai ușor de întreținut în abordarea modelului de obiect de pagină.
- Structura sa de proiect este destul de ușoară și de înțeles.
- Poate utiliza PageFactory în modelul de obiect de pagină pentru a inițializa elementul web și a stoca elemente în cache.
- TestNG poate fi, de asemenea, integrat în abordarea Modelului de obiect de pagină.
Implementarea POM simplu în seleniu
# 1) Scenariu de automatizat
Acum automatizăm scenariul dat folosind Modelul de obiecte de pagină.
Scenariul este explicat mai jos:
Pasul 1: Lansați site-ul „https: //demo.vtiger.com”.
Pasul 2: Introduceți acreditarea validă.
Pasul 3: Autentificați-vă pe site.
Pasul 4: Verificați pagina principală.
Pasul 5: Deconectați-vă de pe site.
Pasul 6: Închideți browserul.
# 2) Scripturi de seleniu pentru scenariul de mai sus în POM
Acum creăm structura POM în Eclipse, după cum se explică mai jos:
Pasul 1: Creați un proiect în Eclipse - Structură bazată pe POM:
a) Creați proiectul „Model de obiect de pagină”.

b) Creați 3 pachete în cadrul proiectului.
- bibliotecă
- pagini
- cazuri de testare
Bibliotecă: Sub aceasta, punem acele coduri care trebuie apelate din nou și din nou în cazurile noastre de testare, cum ar fi lansarea browserului, capturi de ecran, etc. Utilizatorul poate adăuga mai multe clase sub acesta, în funcție de necesitatea proiectului.
Pagini: Sub aceasta, sunt create clase pentru fiecare pagină din aplicația web și pot adăuga mai multe clase de pagini pe baza numărului de pagini din aplicație.
Cazuri de testare: În acest sens, scriem cazul de testare pentru conectare și putem adăuga mai multe cazuri de testare, după cum este necesar pentru a testa întreaga aplicație.

c) Clasele de sub pachete sunt prezentate în imaginea de mai jos.

Etapa Două: Creați următoarele clase sub pachetul de bibliotecă.
Browser.java: În această clasă, sunt definite 3 browsere (Firefox, Chrome și Internet Explorer) și se numește în cazul testului de conectare. Pe baza cerinței, utilizatorul poate testa aplicația și în diferite browsere.
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: În această clasă, se scrie un program de captură de ecran și este apelat în cazul testului atunci când utilizatorul dorește să facă o captură de ecran dacă testul eșuează sau trece.
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(); } } }Pasul 3 : Creați clase de pagini în pachetul de pagini.
HomePage.java: Aceasta este clasa de pagină de pornire, în care sunt definite toate elementele paginii de pornire și metodele.
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: Aceasta este clasa de pagină de conectare, în care sunt definite toate elementele paginii de conectare și metodele.
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(); } }Pasul 4: Creați cazuri de testare pentru scenariul de conectare.
LoginTestCase.java: Aceasta este clasa LoginTestCase, unde se execută cazul de testare. Utilizatorul poate crea, de asemenea, mai multe cazuri de testare în funcție de nevoile proiectului.
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(); } }Pasul 5: Executați „LoginTestCase.java“.
Pasul 6: Rezultatul modelului obiectului paginii:
- Lansați browserul Chrome.
- Site-ul web demonstrativ este deschis în browser.
- Conectați-vă la site-ul demonstrativ.
- Verificați pagina de pornire.
- Deconectați-vă de pe site.
- Închideți browserul.
Acum, haideți să explorăm conceptul principal al acestui tutorial care atrage atenția, adică „Pagefactory”.
Ce este Pagefactory?
PageFactory este o modalitate de implementare a „Modelului de obiecte de pagină”. Aici, urmăm principiul separării depozitului de obiecte de pagină și metodelor de testare. Este un concept încorporat al Page Object Model, care este foarte optimizat.
Să avem acum mai multă claritate în ceea ce privește termenul Pagefactory.
# 1) În primul rând, conceptul numit Pagefactory, oferă o modalitate alternativă în ceea ce privește sintaxa și semantica pentru crearea unui depozit de obiecte pentru elementele web de pe o pagină.
#Două) În al doilea rând, folosește o strategie ușor diferită pentru inițializarea elementelor web.
# 3) Depozitul de obiecte pentru elementele web UI ar putea fi construit folosind:
- „POM fără Pagefactory” obișnuit și,
- Alternativ, puteți utiliza „POM cu Pagefactory”.
Mai jos este prezentată o reprezentare picturală a aceluiași:

Acum vom analiza toate aspectele care diferențiază POM obișnuit de POM cu Pagefactory.
a) Diferența în sintaxa localizării unui element folosind POM obișnuit vs POM cu Pagefactory.
De exemplu , Faceți clic pe Aici pentru a localiza câmpul de căutare care apare pe pagină.

POM fără Pagefactory:
# 1) Mai jos este modul în care localizați câmpul de căutare utilizând POM obișnuit:
WebElement searchNSETxt=driver.findElement(By.id(“searchBox”));# 2) Pasul de mai jos trece valoarea „investiție” în câmpul Căutare NSE.
searchNSETxt.sendkeys(“investment”);POM folosind Pagefactory:
# 1) Puteți localiza câmpul de căutare folosind Pagefactory așa cum se arată mai jos.
Adnotarea @FindBy este utilizat în Pagefactory pentru a identifica un element în timp ce POM fără Pagefactory folosește driver.findElement () metoda de localizare a unui element.
A doua afirmație pentru Pagefactory după @FindBy atribuie un tip WebElement clasă care funcționează exact similar cu atribuirea unui nume de element de tip WebElement clasă ca tip de returnare a metodei driver.findElement () care este utilizat în POM obișnuit (searchNSETxt în acest exemplu).
Ne vom uita la @FindBy adnotări în detaliu în următoarea parte a acestui tutorial.
@FindBy(id = 'searchBox') WebElement searchNSETxt;#Două) Pasul de mai jos trece valoarea „investiție” în câmpul Căutare NSE și sintaxa rămâne aceeași cu cea a POM obișnuit (POM fără Pagefactory).
searchNSETxt.sendkeys(“investment”);b) Diferența în strategia de inițializare a elementelor web folosind POM obișnuit vs POM cu Pagefactory.
Utilizarea POM fără Pagefactory:
Mai jos este prezentat un fragment de cod pentru a seta calea driverului Chrome. O instanță WebDriver este creată cu numele driverului și ChromeDriver este atribuit „driverului”. Același obiect driver este apoi folosit pentru a lansa site-ul web National Stock Exchange, localiza searchBox și introduceți valoarea șirului în câmp.
Ideea pe care doresc să o subliniez aici este că, atunci când este POM fără fabrică de pagini, instanța driverului este creată inițial și fiecare element web este inițializat de fiecare dată când există un apel către acel element web folosind driver.findElement () sau driver .findElements ().
Acesta este motivul pentru care, cu un nou pas de driver.findElement () pentru un element, structura DOM este scanată din nou și identificarea actualizată a elementului se face pe acea pagină.
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”);Utilizarea POM cu Pagefactory:
Pe lângă utilizarea adnotării @FindBy în locul metodei driver.findElement (), fragmentul de cod de mai jos este utilizat suplimentar pentru Pagefactory. Metoda static initElements () a clasei PageFactory este utilizată pentru a inițializa toate elementele UI de pe pagină imediat ce pagina se încarcă.
public PagefactoryClass(WebDriver driver) { this.driver = driver; PageFactory.initElements(driver, this); } Strategia de mai sus face abordarea PageFactory ușor diferită de POM obișnuit. În POM obișnuit, elementul web trebuie inițializat în mod explicit, în timp ce în abordarea Pagefactory toate elementele sunt inițializate cu initElements () fără a inițializa în mod explicit fiecare element web.
De exemplu: Dacă WebElement a fost declarat, dar nu a fost inițializat în POM obișnuit, atunci se inițiază eroarea „initialize variable” sau NullPointerException. Prin urmare, în POM obișnuit, fiecare element web trebuie inițializat în mod explicit. PageFactory vine cu un avantaj față de POM obișnuit în acest caz.
Să nu inițializăm elementul web BDate (POM fără Pagefactory), puteți vedea că se afișează eroarea „Initialize variable” și solicită utilizatorului să o inițializeze la nul, prin urmare, nu puteți presupune că elementele sunt inițializate implicit la localizarea lor.

Element BDate inițializat explicit (POM fără Pagefactory):

Acum, să analizăm câteva cazuri ale unui program complet care utilizează PageFactory pentru a exclude orice ambiguitate în înțelegerea aspectului implementării.
Exemplul 1:
- Accesați „http://www.nseindia.com/”
- Din meniul derulant de lângă câmpul de căutare, selectați „Derivate valutare”.
- Căutați „USDINR”. Verificați textul „Dolar SUA-Rupie indiană - USDINR” pe pagina rezultată.
Structura programului:
- PagefactoryClass.java care include un depozit de obiecte folosind conceptul de fabrică de pagini pentru nseindia.com, care este un constructor pentru inițializarea tuturor elementelor web, este creat, selectați metoda CurrentDerivative () pentru a selecta valoarea din câmpul derulant Searchbox, selectați Symbol () pentru a selecta un simbol pe pagină care apare în continuare și verifytext () pentru a verifica dacă antetul paginii este așa cum era de așteptat sau nu.
- NSE_MainClass.java este fișierul principal de clasă care apelează toate metodele de mai sus și efectuează acțiunile respective pe site-ul NSE.
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 Exemplul 2:
- Accesați „https://www.shoppersstop.com/brands”
- Navigați la linkul Haute Curry.
- Verificați dacă pagina Haute Curry conține textul „Începeți ceva nou”.
Structura programului
- se creează shopperstopPagefactory.java care include un depozit de obiecte folosind conceptul pagefactory pentru shoppersstop.com care este un constructor pentru inițializarea tuturor elementelor web, se creează metode closeExtraPopup () pentru a gestiona o casetă pop-up de alertă care se deschide, faceți clic pe OnHauteCurryLink () pentru a face clic pe Haute Curry Conectați și verificațiStartNewSomething () pentru a verifica dacă pagina Haute Curry conține textul „Începeți ceva nou”.
- Shopperstop_CallPagefactory.java este fișierul principal de clasă care apelează toate metodele de mai sus și efectuează acțiunile respective pe site-ul NSE.
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 folosind Fabrica de pagini
Tutoriale video - POM cu Page Factory
Partea I
Part II
O clasă Factory este utilizată pentru a face mai ușor și mai ușor folosirea Page Objects.
- În primul rând, trebuie să găsim elementele web prin adnotare @FindBy în clasele de pagini .
- Apoi inițializați elementele folosind initElements () atunci când instanțiați clasa de pagină.
# 1) @FindBy:
Adnotarea @FindBy este utilizată în PageFactory pentru localizarea și declararea elementelor web folosind diferite localizatoare.Aici, trecem atributul, precum și valoarea sa utilizată pentru localizarea elementului web la adnotarea @FindBy și apoi este declarat WebElement.
Există 2 moduri în care adnotarea poate fi utilizată.
De exemplu:
@FindBy(how = How.ID, using='EmailAddress') WebElement Email; @FindBy(id='EmailAddress') WebElement Email;Cu toate acestea, prima este modalitatea standard de declarare a WebElements.
'Cum' este o clasă și are variabile statice precum ID, XPATH, CLASSNAME, LINKTEXT etc.
„Folosind” - Pentru a atribui o valoare unei variabile statice.
În cele de mai sus exemplu , am folosit atributul „id” pentru a localiza elementul web „Email”. În mod similar, putem folosi următorii localizatori cu adnotările @FindBy:
- numele clasei
- css
- Nume
- xpath
- nume eticheta
- linkText
- partialLinkText
# 2) initElements ():
InitElements este o metodă statică a clasei PageFactory, care este utilizată pentru a inițializa toate elementele web localizate prin adnotarea @FindBy. Astfel, instanțierea claselor de pagină ușor.
initElements(WebDriver driver, java.lang.Class pageObjectClass) De asemenea, ar trebui să înțelegem că POM respectă principiile OOPS.
- Elementele Web sunt declarate variabile de membru privat (ascunderea datelor).
- Legarea WebElements cu metodele corespunzătoare (Encapsulare).
Pași pentru a crea POM folosind modelul de fabrică a paginii
# 1) Creați un fișier de clasă Java separat pentru fiecare pagină web.
#Două) În fiecare clasă, toate elementele Web ar trebui declarate ca variabile (folosind adnotare - @FindBy) și inițializate folosind metoda initElement (). Elementele Web declarate trebuie inițializate pentru a fi utilizate în metodele de acțiune.
# 3) Definiți metodele corespunzătoare care acționează asupra acelor variabile.
Să luăm un exemplu de scenariu simplu:
- Deschideți adresa URL a unei aplicații.
- Tastați Adresa de e-mail și datele de parolă.
- Faceți clic pe butonul Login.
- Verificați mesajul de conectare reușit pe pagina de căutare.
Strat de pagină
Aici avem 2 pagini,
- Pagina principala - Pagina care se deschide la introducerea adresei URL și unde introducem datele pentru autentificare.
- SearchPage - O pagină care se afișează după o autentificare reușită.
În Page Layer, fiecare pagină din aplicația web este declarată ca o clasă Java separată și localizatorii și acțiunile sale sunt menționate acolo.
Pași pentru a crea POM cu un exemplu în timp real
# 1) Creați o clasă Java pentru fiecare pagină:
In acest exemplu , vom accesa 2 pagini web, paginile „Acasă” și „Căutare”.
Prin urmare, vom crea 2 clase Java în Page Layer (sau, într-un pachet, com.automation.pages).
Package Name :com.automation.pages HomePage.java SearchPage.java # 2) Definiți WebElements ca variabile utilizând Adnotare @FindBy:
Am interacționa cu:
- E-mail, parolă, câmp buton Login pe pagina principală.
- Mesaj de succes pe pagina de căutare.
Deci, vom defini WebElements folosind @FindBy
De exemplu: Dacă vom identifica adresa de e-mail utilizând atributul id, atunci declarația sa variabilă este
//Locator for EmailId field @FindBy(how=How.ID,using='EmailId') private WebElementEmailIdAddress; # 3) Creați metode pentru acțiuni efectuate pe WebElements.
Mai jos sunt efectuate acțiuni pe WebElements:
- Tastați acțiune în câmpul Adresă de e-mail.
- Tastați acțiune în câmpul Parolă.
- Faceți clic pe acțiune pe butonul Login.
De exemplu, Metodele definite de utilizator sunt create pentru fiecare acțiune pe WebElement ca,
public void typeEmailId(String Id){ driver.findElement(EmailAddress).sendKeys(Id) }Aici, ID-ul este trecut ca parametru în metodă, deoarece intrarea va fi trimisă de utilizator din cazul principal de testare.
Notă :Trebuie creat un constructor în fiecare dintre clasele din Stratul de pagină, pentru a obține instanța driverului din clasa Principală din Test Layer și, de asemenea, pentru a inițializa WebElements (Obiecte de pagină) declarate în clasa de pagină utilizând PageFactory.InitElement () .
Nu inițiem driverul aici, mai degrabă instanța sa este primită de la Clasa principală atunci când se creează obiectul clasei Page Layer.
InitElement () - este folosit pentru a inițializa elementele Web declarate, folosind instanța driverului din clasa principală. Cu alte cuvinte, WebElements sunt create folosind instanța driverului. Numai după ce elementele Web sunt inițializate, ele pot fi utilizate în metodele de efectuare a acțiunilor.
Două clase Java sunt create pentru fiecare pagină, după cum se arată mai jos:
HomePage.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 Layer
Test Case sunt implementate în această clasă. Creăm un pachet separat, spunem, com.automation.test și apoi creăm aici o clasă Java (MainClass.java)
Pași pentru a crea cazuri de testare:
- Inițializați driverul și deschideți aplicația.
- Creați un obiect al clasei PageLayer (pentru fiecare pagină web) și treceți instanța driverului ca parametru.
- Folosind obiectul creat, faceți un apel către metodele din Clasa PageLayer (pentru fiecare pagină web) pentru a efectua acțiuni / verificare.
- Repetați pasul 3 până când sunt efectuate toate acțiunile și apoi închideți driverul.
//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(); } } Ierarhie tip adnotare utilizată pentru declararea elementelor web
Adnotările sunt folosite pentru a ajuta la construirea unei strategii de localizare pentru elementele UI.
# 1) @FindBy
Când vine vorba de Pagefactory, @FindBy acționează ca o baghetă magică. Acesta adaugă toată puterea conceptului. Acum știți că adnotarea @FindBy în Pagefactory funcționează la fel ca cea a driver.findElement () în modelul obișnuit de pagină. Este folosit pentru a localiza WebElement / WebElements cu un singur criteriu .
# 2) @FindBys
Este folosit pentru a localiza WebElement cu mai mult de un criteriu și trebuie să corespundă tuturor criteriilor date. Aceste criterii ar trebui menționate într-o relație părinte-copil. Cu alte cuvinte, acest lucru folosește relația AND condițională pentru a localiza WebElements folosind criteriile specificate. Folosește mai multe @FindBy pentru a defini fiecare criteriu.
De exemplu:
Codul sursă HTML al unui WebElement:
În POM:
@FindBys({ @FindBy(id = 'searchId_1'), @FindBy(name = 'search_field') }) WebElementSearchButton;În exemplul de mai sus, WebElement ‘SearchButton’ este localizat numai dacă acesta se potrivește ambelor criteriile a căror valoare de identificare este „searchId_1” și valoarea numelui este „search_field”. Vă rugăm să rețineți că primele criterii aparțin unei etichete părinte și al doilea criteriu pentru o etichetă copil.
# 3) @FindAll
Este folosit pentru a localiza WebElement cu mai mult de un criteriu și trebuie să corespundă cel puțin unuia dintre criteriile date. Aceasta folosește relații condiționate SAU pentru a localiza WebElements. Folosește mai multe @FindBy pentru a defini toate criteriile.
De exemplu:
Cod sursă HTML:
În POM:
@FindBys({ @FindBy(id = 'UsernameNameField_1'), // doesn’t match @FindBy(name = 'User_Id') //matches @FindBy(className = “UserName_r”) //matches }) WebElementUserName;În exemplul de mai sus, WebElement „Nume utilizator este localizat dacă este se potrivește cel puțin cu unul dintre criteriile menționate.
# 4) @CacheLookUp
Când WebElement este utilizat mai des în cazuri de testare, Selenium caută WebElement de fiecare dată când se execută scriptul de testare. În acele cazuri, în care anumite elemente Web sunt utilizate la nivel global pentru toate TC ( De exemplu, Scenariul de conectare se întâmplă pentru fiecare TC), această adnotare poate fi utilizată pentru a menține acele WebElements în memoria cache odată ce a fost citită pentru prima dată.
La rândul său, acest lucru ajută codul să se execute mai repede, deoarece de fiecare dată când nu trebuie să caute WebElement în pagină, mai degrabă își poate obține referința din memorie.
Acesta poate fi un prefix cu oricare dintre @FindBy, @FindBys și @FindAll.
De exemplu:
@CacheLookUp @FindBys({ @FindBy(id = 'UsernameNameField_1'), @FindBy(name = 'User_Id') @FindBy(className = “UserName_r”) }) WebElementUserName;Rețineți, de asemenea, că această adnotare trebuie utilizată numai pentru elementele Web a căror valoare de atribut (cum ar fi xpath, numele de identificare, numele clasei etc.) nu se schimbă destul de des. Odată ce WebElement este localizat pentru prima dată, acesta își păstrează referința în memoria cache.
Deci, atunci se întâmplă o modificare a atributului WebElement după câteva zile, Selenium nu va putea localiza elementul, deoarece are deja vechea sa referință în memoria cache și nu va lua în considerare modificarea recentă a WebElement.
Mai multe despre PageFactory.initElements ()
Acum că înțelegem strategia Pagefactory privind inițializarea elementelor web folosind InitElements (), să încercăm să înțelegem diferitele versiuni ale metodei.
Metoda așa cum o știm ia obiectul driver și obiectul clasei curente ca parametri de intrare și returnează obiectul paginii inițializând implicit și proactiv toate elementele de pe pagină.
În practică, utilizarea constructorului așa cum se arată în secțiunea de mai sus este mai preferabilă decât celelalte moduri de utilizare a acestuia.
Modalități alternative de apelare a metodei sunt:
# 1) În loc să utilizați indicatorul „acest”, puteți crea obiectul de clasă curent, treceți instanța driverului către acesta și apelați metoda statică initElements cu parametri, adică obiectul driver și obiectul de clasă care tocmai a fost creat.
public PagefactoryClass(WebDriver driver) { //version 2 PagefactoryClass page=new PagefactoryClass(driver); PageFactory.initElements(driver, page); } #Două) A treia modalitate de inițializare a elementelor folosind clasa Pagefactory este folosind api numită „reflecție”. Da, în loc să creeze un obiect de clasă cu un cuvânt cheie „nou”, classname.class poate fi transmis ca parte a parametrului de intrare initElements ().
public PagefactoryClass(WebDriver driver) { //version 3 PagefactoryClass page=PageFactory.initElements(driver, PagefactoryClass.class); } întrebări frecvente
Q # 1) Care sunt diferitele strategii de localizare utilizate pentru @FindBy?
Răspuns: Răspunsul simplu la acest lucru este că nu există strategii diferite de localizare care sunt utilizate pentru @FindBy.
Folosesc aceleași 8 strategii de localizare pe care le folosește metoda findElement () în POM obișnuit:
- id
- Nume
- numele clasei
- xpath
- css
- nume eticheta
- linkText
- partialLinkText
Q # 2) Există versiuni diferite de utilizare a adnotărilor @FindBy?
Răspuns: Când există un element web de căutat, folosim adnotarea @FindBy. Vom detalia modalitățile alternative de utilizare a @FindBy împreună cu diferitele strategii de localizare.
Am văzut deja cum să folosim versiunea 1 a @FindBy:
@FindBy(id = 'cidkeyword') WebElement Symbol;Versiunea 2 a @FindBy este prin trecerea parametrului de intrare ca Cum și Folosind .
Cum caută strategia de localizare cu ajutorul căreia ar fi identificat elementul web. Cuvântul cheie folosind definește valoarea localizatorului.
Vedeți mai jos pentru o mai bună înțelegere,
- How.ID caută elementul folosind id strategia și elementul pe care încearcă să îl identifice are id = cuvânt cheie.
@FindBy(how = How.ID, using = ' cidkeyword') WebElement Symbol; - Cum.CLASS_NAME caută elementul folosind numele clasei strategia și elementul pe care încearcă să îl identifice are clasa = newclass.
@FindBy(how = How.CLASS_NAME, using = 'newclass') WebElement Symbol; Î # 3) Există vreo diferență între cele două versiuni ale @FindBy?
Răspuns: Răspunsul este Nu, nu există nicio diferență între cele două versiuni. Doar că prima versiune este mai scurtă și mai ușoară în comparație cu a doua versiune.
Q # 4) Ce folosesc în pagina de fabricație în cazul în care există o listă de elemente web care trebuie localizate?
Răspuns: În modelul obișnuit de proiectare a obiectelor de pagină, avem driver.findElements () pentru a localiza mai multe elemente aparținând aceleiași clase sau nume de etichete, dar cum putem localiza astfel de elemente în cazul modelului de obiect de pagină cu Pagefactory? Cel mai simplu mod de a realiza astfel de elemente este să folosiți aceeași adnotare @FindBy.
Am înțeles că această linie pare a fi un zgâriet pentru mulți dintre voi. Dar da, este răspunsul la întrebare.
Să ne uităm la exemplul de mai jos:
Folosind modelul obișnuit de obiecte de pagină fără Pagefactory, utilizați driver.findElements pentru a localiza mai multe elemente așa cum se arată mai jos:
private List multipleelements_driver_findelements = driver.findElements (By.class(“last”));Același lucru poate fi realizat folosind modelul de obiect de pagină cu Pagefactory așa cum este prezentat mai jos:
@FindBy (how = How.CLASS_NAME, using = 'last') private List multipleelements_FindBy;Practic, atribuirea elementelor unei liste de tip WebElement face trucul indiferent dacă Pagefactory a fost sau nu folosită în timp ce identifică și localizează elementele.
Q # 5) Poate atât proiectarea obiectului Page, fără pagefactory, cât și Pagefactory, să fie folosite în același program?
Răspuns: Da, atât proiectarea obiectului de pagină fără Pagefactory, cât și cu Pagefactory pot fi utilizate în același program. Puteți parcurge programul prezentat mai jos în Răspuns pentru întrebarea nr. 6 pentru a vedea cum sunt utilizate ambele în program.
Un lucru de reținut este că conceptul Pagefactory cu caracteristica cache ar trebui evitat pe elementele dinamice, în timp ce proiectarea obiectelor de pagină funcționează bine pentru elementele dinamice. Cu toate acestea, Pagefactory se potrivește numai elementelor statice.
Q # 6) Există modalități alternative de identificare a elementelor bazate pe criterii multiple?
cum se face o matrice de șiruri Java
Răspuns: Alternativa pentru identificarea elementelor bazate pe mai multe criterii este utilizarea adnotărilor @FindAll și @FindBys. Aceste adnotări ajută la identificarea elementelor unice sau multiple, în funcție de valorile preluate din criteriile trecute în ea.
# 1) @FindAll:
@FindAll poate conține mai multe @FindBy și va returna toate elementele care se potrivesc cu orice @FindBy dintr-o singură listă. @FindAll este utilizat pentru a marca un câmp pe un obiect de pagină pentru a indica faptul că căutarea ar trebui să utilizeze o serie de etichete @FindBy. Apoi va căuta toate elementele care corespund oricărui criteriu FindBy.
Rețineți că elementele nu sunt garantate pentru a fi în ordinea documentelor.
Sintaxa de a utiliza @FindAll este următoarea:
@FindAll( { @FindBy(how = How.ID, using = 'foo'), @FindBy(className = 'bar') } ) Explicaţie: @FindAll va căuta și identifica elemente separate care corespund fiecărui criteriu @FindBy și le va enumera. În exemplul de mai sus, va căuta mai întâi un element al cărui id = ”foo” și apoi va identifica al doilea element cu className = ”bar”.
Presupunând că a fost identificat un element pentru fiecare criteriu FindBy, @FindAll va avea ca rezultat listarea a 2 elemente, respectiv. Amintiți-vă, ar putea exista mai multe elemente identificate pentru fiecare criteriu. Astfel, în cuvinte simple, @ Găsiți toate acționează echivalent cu SAU operator pe criteriile @FindBy trecute.
# 2) @FindBys:
FindBys este folosit pentru a marca un câmp pe un obiect de pagină pentru a indica faptul că căutarea ar trebui să utilizeze o serie de etichete @FindBy într-un lanț, așa cum este descris în ByChained. Când obiectele WebElement necesare trebuie să corespundă tuturor criteriilor date, utilizați adnotarea @FindBys.
Sintaxa de a utiliza @FindBys este următoarea:
@FindBys( { @FindBy(name=”foo”) @FindBy(className = 'bar') } ) Explicaţie: @FindBys va căuta și identifica elemente conforme cu toate criteriile @FindBy și le va lista. În exemplul de mai sus, va căuta elemente al căror nume = ”foo” și className = ”bara”.
@FindAll va avea ca rezultat listarea unui element dacă presupunem că a existat un element identificat cu numele și className în criteriile date.
Dacă nu există un element care să îndeplinească toate condițiile FindBy trecute, atunci rezultatul @FindBys va fi zero elemente. Ar putea exista o listă de elemente web identificate dacă toate condițiile satisfac mai multe elemente. Cu cuvinte simple, @ FindBys acționează echivalent cu ȘI operator pe criteriile @FindBy trecute.
Să vedem implementarea tuturor adnotărilor de mai sus printr-un program detaliat:
Vom modifica programul www.nseindia.com dat în secțiunea anterioară pentru a înțelege implementarea adnotărilor @FindBy, @FindBys și @FindAll
# 1) Depozitul de obiecte al PagefactoryClass este actualizat după cum urmează:
Listează lista nouă = driver.findElements (By.tagName („a”));
@FindBy (cum = Cum. NUME ETICHETA , folosind = „a”)
privat List findbyvalue;
@Găsiți toate ({ @FindBy (className = „sel”), @FindBy (xpath = ”// a (@ id =’ tab5 ′) ”)})
privat List findallvalue;
@FindBys ({ @FindBy (className = „sel”), @FindBy (xpath = ”// a (@ id =’ tab5 ′) ”)})
privat List findbysvalue;
# 2) O nouă metodă seeHowFindWorks () este scrisă în PagefactoryClass și este invocată ca ultima metodă din clasa Main.
Metoda este următoarea:
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 Dat mai jos este rezultatul afișat în fereastra consolei după executarea programului:

Să încercăm acum să înțelegem codul în detaliu:
# 1) Prin intermediul modelului de proiectare a obiectelor de pagină, elementul „listă nouă” identifică toate etichetele cu ancora „a”. Cu alte cuvinte, obținem un număr de toate linkurile de pe pagină.
Am aflat că pagefactory @FindBy face aceeași treabă ca și driver.findElement (). Elementul findbyvalue este creat pentru a obține numărul tuturor linkurilor de pe pagină printr-o strategie de căutare care are un concept pagefactory.
Se dovedește corect că atât driver.findElement (), cât și @FindBy fac aceeași treabă și identifică aceleași elemente. Dacă vă uitați la captura de ecran a ferestrei consolei rezultate de mai sus, numărul de linkuri identificate cu elementul newlist și cel al findbyvalue sunt egale, adică 299 linkuri găsite pe pagină.
Rezultatul a arătat după cum urmează:
driver.findElements(By.tagName()) 299 count of @FindBy- list elements 299 #Două) Aici vom detalii despre funcționarea adnotării @FindAll care va fi legată de lista elementelor web cu numele findallvalue.
Privind cu atenție fiecare criteriu @FindBy din adnotarea @FindAll, primul criteriu @FindBy caută elemente cu className = 'sel' și al doilea criteriu @FindBy caută un anumit element cu XPath = „// a (@ id = 'tab5')
Să apăsăm acum F12 pentru a inspecta elementele de pe pagina nseindia.com și pentru a obține anumite clarități asupra elementelor care corespund criteriilor @FindBy.
Există două elemente pe pagină corespunzătoare claseiNume = ”sel”:
la) Elementul „Noțiuni fundamentale” are eticheta listă, adică
cu className = ”sel”. Vedeți Instantaneul de mai jos

b) Un alt element „Comandă” are un XPath cu o etichetă de ancorare care are numele clasei ca „sel”.

c) Al doilea @FindBy cu XPath are o etichetă de ancorare a cărei id este ' fila 5 ”. Există doar un element identificat ca răspuns la căutare, care este Fundamentals.
Vedeți Instantaneul de mai jos:

Când s-a executat testul nseindia.com, am obținut numărul de elemente căutate de.
@FindAll ca 3. Elementele pentru findallvalue atunci când sunt afișate au fost: Noțiuni de bază ca 0aelement index, Comandă ca 1Sfelement index și elemente fundamentale din nou ca 2ndelement index. Am aflat deja că @FindAll identifică separat elementele pentru fiecare criteriu @FindBy.
Conform aceluiași protocol, pentru prima căutare de criterii, adică className = ”sel”, a identificat două elemente care îndeplinesc condiția și a preluat „Noțiuni fundamentale” și „Carnet de comenzi”.
Apoi a trecut la următorul criteriu @FindBy și, conform xpath-ului dat pentru al doilea @FindBy, ar putea prelua elementul „Fundamentals”. Acesta este motivul pentru care, în final, a identificat 3 elemente, respectiv.
Astfel, nu obține elementele care îndeplinesc niciuna dintre condițiile @FindBy, dar tratează separat cu fiecare dintre @FindBy și identifică elementele la fel. În plus, în exemplul actual, am văzut, de asemenea, că nu urmărește dacă elementele sunt unice ( De exemplu. Elementul „Noțiuni fundamentale” în acest caz, care a fost afișat de două ori ca parte a rezultatului celor două criterii @FindBy)
# 3) Aici vom detalii despre funcționarea adnotării @FindBys care va fi referitoare la lista elementelor web cu numele findbysvalue. Și aici, primul criteriu @FindBy caută elemente cu className = ’sel’ și al doilea criteriu @FindBy caută un anumit element cu xpath = „// a (@ id =” tab5 ”).
Acum că știm, elementele identificate pentru prima condiție @FindBy sunt „Noțiuni fundamentale” și „Carnet de comenzi”, iar cel de-al doilea criteriu @FindBy este „Noțiuni fundamentale”.
Deci, cum va fi diferit @FindBys rezultatul decât @FindAll? Am aflat în secțiunea anterioară că @FindBys este echivalent cu operatorul condițional AND și, prin urmare, caută un element sau lista de elemente care să satisfacă toate condițiile @FindBy.
Conform exemplului nostru actual, valoarea „Fundamentale” este singurul element care are class = ”sel” și id = ”tab5”, satisfăcând ambele condiții. Acesta este motivul pentru care dimensiunea @FindBys în caseta de testare este 1 și afișează valoarea ca „Noțiuni de bază”.
Memorarea în cache a elementelor în Pagefactory
De fiecare dată când o pagină este încărcată, toate elementele de pe pagină sunt căutate din nou prin invocarea unui apel prin @FindBy sau driver.findElement () și există o nouă căutare a elementelor de pe pagină.
De cele mai multe ori, când elementele sunt dinamice sau se schimbă continuu în timpul rulării, mai ales dacă sunt elemente AJAX, cu siguranță are sens că la fiecare încărcare a paginii există o nouă căutare a tuturor elementelor de pe pagină.
Când pagina web are elemente statice, stocarea în cache a elementului poate ajuta în mai multe moduri. Când elementele sunt stocate în cache, nu trebuie să localizeze elementele din nou la încărcarea paginii, ci poate face referință la depozitul de elemente cache. Acest lucru economisește mult timp și crește performanța mai bună.
Pagefactory oferă această caracteristică de memorare în cache a elementelor folosind o adnotare @CacheLookUp .
Adnotarea îi spune conducătorului auto să utilizeze aceeași instanță a localizatorului din DOM pentru elemente și să nu le caute din nou, în timp ce metoda initElements din pagefactory contribuie în mod vizibil la stocarea elementului static cache. InitElements realizează sarcina de cache a elementelor.
Acest lucru face ca conceptul pagefactory să fie special peste modelul obișnuit de proiectare a obiectelor de pagină. Acesta vine cu propriile sale argumente pro și contra, despre care vom discuta puțin mai târziu. De exemplu, butonul de conectare de pe pagina de pornire Facebook este un element static, care poate fi memorat în cache și este un element ideal pentru a fi memorat în cache.
Să vedem acum cum să implementăm adnotarea @CacheLookUp
Va trebui mai întâi să importați un pachet pentru Cachelookup după cum urmează:
import org.openqa.selenium.support.CacheLookupMai jos este fragmentul care afișează definiția unui element folosind @CacheLookUp. De îndată ce UniqueElement este căutat pentru prima dată, initElement () stochează versiunea cache a elementului, astfel încât data viitoare driverul să nu caute elementul, în schimb, se referă la același cache și efectuează acțiunea pe elementul din dreapta. departe.
@FindBy(id = 'unique') @CacheLookup private WebElement UniqueElement; Să vedem acum printr-un program real cum acțiunile asupra elementului web cache sunt mai rapide decât cele pe elementul web non-cache:
Îmbunătățind în continuare programul nseindia.com am scris o altă metodă nouă monitorPerformance () în care creez un element în cache pentru caseta Căutare și un element non-cache pentru aceeași Casetă de căutare.
Apoi, încerc să obțin tagname-ul elementului de 3000 de ori atât pentru elementul memorat în cache, cât și pentru cel non-cache și încerc să măsoară timpul necesar pentru a finaliza sarcina atât de către elementul cache, cât și de cel non-cache.
Am luat în considerare de 3000 de ori, astfel încât să putem vedea o diferență vizibilă în calendarele pentru cele două. Mă voi aștepta ca elementul memorat în cache să finalizeze obținând numele de 3000 de ori într-un timp mai redus, în comparație cu cel al elementului non-cache.
Acum știm de ce elementul memorat în cache ar trebui să funcționeze mai repede, adică șoferul este instruit să nu caute elementul după prima căutare, ci să continue să lucreze direct la el și nu este cazul elementului non-cache unde se efectuează căutarea elementului pentru toate de 3000 de ori și apoi acțiunea se execută asupra acestuia.
Mai jos este codul pentru metoda 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'); } La execuție, vom vedea rezultatul de mai jos în fereastra consolei:
Conform rezultatului, sarcina elementului non-cache este finalizată în 82 secunde în timp ce timpul necesar pentru a finaliza sarcina pe elementul cache a fost doar 37 secunde. Aceasta este într-adevăr o diferență vizibilă în timpul de răspuns atât al elementului memorat în cache, cât și al elementului non-cache.

Q # 7) Care sunt avantajele și dezavantajele adnotării @CacheLookUp în conceptul Pagefactory?
Răspuns:
Pro @CacheLookUp și situații fezabile pentru utilizarea sa:
@CacheLookUp este fezabil atunci când elementele sunt statice sau nu se modifică deloc în timp ce pagina este încărcată. Astfel de elemente nu modifică timpul de rulare. În astfel de cazuri, este recomandabil să utilizați adnotarea pentru a îmbunătăți viteza generală de execuție a testului.
Contra adnotării @CacheLookUp:
Cel mai mare dezavantaj de a avea elemente în cache cu adnotarea este teama de a obține frecvent StaleElementReferenceExceptions.
Elementele dinamice sunt reîmprospătate destul de des cu cele susceptibile de a se schimba rapid în câteva secunde sau minute din intervalul de timp.
Mai jos sunt câteva astfel de cazuri ale elementelor dinamice:
- Având un cronometru pe pagina web care actualizează temporizatorul în fiecare secundă.
- Un cadru care actualizează constant raportul meteo.
- O pagină care raportează actualizările live Sensex.
Acestea nu sunt deloc ideale sau fezabile pentru utilizarea adnotării @CacheLookUp. Dacă faceți acest lucru, riscați să obțineți excepția StaleElementReferenceExceptions.
La memorarea în cache a acestor elemente, în timpul execuției testului, DOM-ul elementelor este modificat, totuși driverul caută versiunea DOM care a fost deja stocată în timpul cache-ului. Acest lucru face ca elementul învechit să fie căutat de driver, care nu mai există pe pagina web. Acesta este motivul pentru care StaleElementReferenceException este aruncat.
Clase de fabrică:
Pagefactory este un concept construit pe mai multe clase și interfețe din fabrică. Vom afla despre câteva clase de fabrica și interfețe aici în această secțiune. Puține dintre care ne vom uita sunt AjaxElementLocatorFactory , ElementLocatorFactory și DefaultElementFactory.
Ne-am întrebat vreodată dacă Pagefactory oferă vreo modalitate de a încorpora așteptarea implicită sau explicită a elementului până când se îndeplinește o anumită condiție ( Exemplu: Până când un element este vizibil, activat, clicabil etc.)? Dacă da, iată un răspuns adecvat la acesta.
AjaxElementLocatorFactory este unul dintre contribuitorii semnificativi din toate clasele de fabrici. Avantajul AjaxElementLocatorFactory este că puteți atribui o valoare de expirare pentru un element web clasei de pagini Object.
Deși Pagefactory nu oferă o caracteristică de așteptare explicită, totuși, există o variantă de așteptare implicită folosind clasa AjaxElementLocatorFactory . Această clasă poate fi utilizată încorporată atunci când aplicația folosește componente și elemente Ajax.
Iată cum îl implementați în cod. În cadrul constructorului, când folosim metoda initElements (), putem folosi AjaxElementLocatorFactory pentru a oferi o așteptare implicită asupra elementelor.
PageFactory.initElements(driver, this); can be replaced with PageFactory.initElements( new AjaxElementLocatorFactory(driver, 20), this);A doua linie de mai sus a codului implică faptul că driverul va seta un timeout de 20 de secunde pentru toate elementele de pe pagină atunci când fiecare dintre încărcările sale și dacă vreunul dintre elemente nu este găsit după o așteptare de 20 de secunde, este aruncat „NoSuchElementException” pentru acel element lipsă.
De asemenea, puteți defini așteptarea după cum urmează:
public pageFactoryClass(WebDriver driver) { ElementLocatorFactory locateMe = new AjaxElementLocatorFactory(driver, 30); PageFactory.initElements(locateMe, this); this.driver = driver; } Codul de mai sus funcționează perfect, deoarece clasa AjaxElementLocatorFactory implementează interfața ElementLocatorFactory.
Aici, interfața părinte (ElementLocatorFactory) se referă la obiectul clasei copil (AjaxElementLocatorFactory). Prin urmare, conceptul Java de „upcasting” sau „polimorfism de execuție” este utilizat în timpul atribuirii unui timeout folosind AjaxElementLocatorFactory.
În ceea ce privește modul în care funcționează tehnic, AjaxElementLocatorFactory creează mai întâi un AjaxElementLocator utilizând un SlowLoadableComponent care s-ar putea să nu fi terminat încărcarea la revenirea load (). După un apel to load (), metoda isLoaded () ar trebui să continue să eșueze până când componenta s-a încărcat complet.
Cu alte cuvinte, toate elementele vor fi căutate proaspăt de fiecare dată când un element este accesat în cod invocând un apel către locator.findElement () din clasa AjaxElementLocator care apoi aplică un timeout până la încărcarea prin clasa SlowLoadableComponent.
În plus, după alocarea expirării prin AjaxElementLocatorFactory, elementele cu adnotare @CacheLookUp nu vor mai fi memorate în cache, deoarece adnotarea va fi ignorată.
Există, de asemenea, o variantă a modului poti suna initElements () metoda și modul în care tu nu ar trebui suna AjaxElementLocatorFactory pentru a aloca timeout pentru un element.
# 1) Puteți specifica, de asemenea, un nume de element în locul obiectului driver, așa cum se arată mai jos în metoda initElements ():
PageFactory.initElements( , this);Metoda initElements () din varianta de mai sus invocă intern un apel către clasa DefaultElementFactory și constructorul DefaultElementFactory acceptă obiectul interfeței SearchContext ca parametru de intrare. Obiectul driverului web și un element web aparțin ambelor interfețe SearchContext.
În acest caz, metoda initElements () va inițializa în avans numai elementul menționat și nu toate elementele de pe pagina web vor fi inițializate.
#Două) Cu toate acestea, iată o întorsătură interesantă la acest fapt care afirmă cum nu ar trebui să apelați obiectul AjaxElementLocatorFactory într-un mod specific. Dacă folosesc varianta de mai sus a initElements () împreună cu AjaxElementLocatorFactory, atunci va eșua.
Exemplu: Codul de mai jos, adică trecerea numelui elementului în locul obiectului driver la definiția AjaxElementLocatorFactory nu va funcționa ca constructor pentru clasa AjaxElementLocatorFactory ia doar obiectul driverului Web ca parametru de intrare și, prin urmare, obiectul SearchContext cu elementul web nu ar funcționa pentru el.
PageFactory.initElements(new AjaxElementLocatorFactory(, 10), this); Q # 8) Utilizarea paginii de fabrică este o opțiune fezabilă peste modelul obișnuit de proiectare a obiectelor de pagină?
Răspuns: Aceasta este cea mai importantă întrebare pe care o au oamenii și de aceea m-am gândit să mă adresez la sfârșitul tutorialului. Acum știm „intrarea și ieșirea” despre Pagefactory pornind de la conceptele sale, adnotările utilizate, caracteristicile suplimentare pe care le acceptă, implementarea prin cod, avantajele și dezavantajele.
Cu toate acestea, rămânem cu această întrebare esențială că, dacă pagefactory are atât de multe lucruri bune, de ce nu ar trebui să rămânem la utilizarea acesteia.
Pagefactory vine cu conceptul de CacheLookUp, pe care l-am văzut că nu este fezabil pentru elemente dinamice, cum ar fi valorile elementului care se actualizează des. Deci, pagefactory fără CacheLookUp, este o opțiune bună pentru a merge? Da, dacă xpath-urile sunt statice.
Cu toate acestea, dezavantajul este că aplicația de epocă modernă este plină de elemente dinamice grele, unde știm că proiectarea obiectului de pagină fără pagefactory funcționează bine în cele din urmă, dar conceptul pagefactory funcționează la fel de bine cu xpaths dinamici? Poate nu. Iată un exemplu rapid:
Pe pagina web nseindia.com, vedem un tabel așa cum este prezentat mai jos.

Xpath-ul tabelului este
'//*(@id='tab9Content')/table/tbody/tr(+count+)/td(1)'Dorim să preluăm valori din fiecare rând pentru prima coloană „Cumpărați cantitatea”. Pentru a face acest lucru, va trebui să incrementăm contorul rândului, dar indexul coloanei va rămâne 1. Nu există nicio modalitate prin care să putem trece acest XPath dinamic în adnotarea @FindBy, deoarece adnotarea acceptă valori care sunt statice și nu se poate transmite nicio variabilă aceasta.
Aici pagina pagefactory eșuează complet, în timp ce POM obișnuit funcționează excelent cu ea. Puteți utiliza cu ușurință o buclă for pentru a crește indexul rândurilor folosind astfel de xpath-uri dinamice în metoda driver.findElement ().
Concluzie
Page Object Model este un concept sau model de proiectare utilizat în cadrul de automatizare Selenium.
Denumirea convecției metodelor este ușor de utilizat în Modelul de obiecte de pagină. Codul din POM este ușor de înțeles, reutilizabil și menținut. În POM, dacă există vreo modificare în elementul web, atunci este suficient să faceți modificările în clasa respectivă, mai degrabă decât să editați toate clasele.
Pagefactory la fel ca POM obișnuit este un concept minunat de aplicat. Cu toate acestea, trebuie să știm unde este fezabil POM obișnuit și unde se potrivește bine Pagefactory. În aplicațiile statice (în care atât XPath cât și elementele sunt statice), Pagefactory poate fi implementat în mod liberal, cu beneficii suplimentare de performanță mai bună.
Alternativ, atunci când aplicația implică atât elemente dinamice, cât și elemente statice, este posibil să aveți o implementare mixtă a pomului cu Pagefactory și fără Pagefactory, conform fezabilității pentru fiecare element web.
Autor: Acest tutorial a fost scris de Shobha D. Lucrează ca șef de proiect și vine cu peste 9 ani de experiență în testare manuală, automatizare (Selenium, IBM Rational Functional Tester, Java) și testare API (SOAPUI și Rest sure in Java) .
Acum, la dvs., pentru implementarea ulterioară a Pagefactory.
Explorare fericită !!!
=> Vizitați aici pentru a afla Seleniu de la zero.
Lectură recomandată
- 30+ Cele mai bune tutoriale despre seleniu: învățați seleniul cu exemple reale
- Scenarii eficiente cu scripturi și depanare Selenium - Tutorial Selenium # 27
- Depanarea scripturilor Selenium cu jurnale (Tutorial Log4j) - Tutorial Selenium # 26
- Introducere în JUnit Framework și utilizarea sa în Selenium Script - Selenium Tutorial # 11
- 7 factori care afectează estimarea testului proiectului de automatizare Selenium - Tutorial Selenium # 32
- Afirmații în seleniu folosind cadrele Junit și TestNG
- Cum se utilizează cadrul TestNG pentru crearea de scripturi Selenium - TestNG Selenium Tutorial # 12
- Aflați cum să utilizați adnotările TestNG în seleniu (cu exemple)





