page object model with page factory selenium tutorial
Tento podrobný výukový program vysvětluje vše o modelu objektových stránek (POM) pomocí Pagefactory pomocí příkladů. Můžete se také naučit implementaci POM v selenu:
V tomto kurzu pochopíme, jak vytvořit model objektu stránky pomocí přístupu Page Factory. Zaměříme se na:
- Tovární třída
- Jak vytvořit základní POM pomocí vzoru Page Factory
- Různé anotace používané v přístupu Page Factory
Než uvidíme, co je Pagefactory a jak jej lze použít spolu s objektovým modelem Page, pochopme, co je Page Object Model, který je obecně známý jako POM.
=> Navštivte zde a prohlédněte si sérii tréninků selenu pro všechny.
Co se naučíte:
- Co je to stránkový objektový model (POM)?
- Co je Pagefactory?
- POM pomocí Page Factory
- Často kladené otázky
- Závěr
Co je to stránkový objektový model (POM)?
Teoretické terminologie popisují Model objektu stránky jako návrhový vzor používaný k vytvoření úložiště objektů pro webové prvky dostupné v testované aplikaci. Několik dalších to označuje jako rámec pro automatizaci selenu pro danou testovanou aplikaci.
Co jsem však o termínu Page Object Model pochopil, je:
# 1) Jedná se o návrhový vzor, kde máte samostatný soubor třídy Java odpovídající každé obrazovce nebo stránce v aplikaci. Soubor třídy může obsahovat úložiště objektů prvků uživatelského rozhraní i metody.
#dva) V případě, že na stránce existují obrovské webové prvky, lze třídu úložiště objektů pro stránku oddělit od třídy, která zahrnuje metody pro příslušnou stránku.
Příklad: Pokud má stránka Registrovat účet mnoho vstupních polí, mohla by existovat třída RegisterAccountObjects.java, která tvoří úložiště objektů pro prvky uživatelského rozhraní na stránce účtů registrů.
Lze vytvořit samostatný soubor třídy RegisterAccount.java rozšiřující nebo dědějící RegisterAccountObjects, který zahrnuje všechny metody provádějící různé akce na stránce.
# 3) Kromě toho by v balíčku mohl být obecný balíček se souborem {roperties, testovacími daty aplikace Excel a běžnými metodami.
Příklad: DriverFactory, který lze velmi snadno použít na všech stránkách aplikace
Porozumění POM s příkladem
Šek tady dozvědět se více o POM.
Níže je snímek webové stránky:
Kliknutím na každý z těchto odkazů přesměrujete uživatele na novou stránku.
Zde je snímek toho, jak je struktura projektu se selenem vytvářena pomocí objektového modelu Page odpovídající každé stránce na webu. Každá třída Java obsahuje úložiště objektů a metody provádění různých akcí na stránce.
Kromě toho bude existovat další JUNIT nebo TestNG nebo soubor třídy Java vyvolávající volání souborů třídy na těchto stránkách.
Proč používáme objektový model stránky?
O používání tohoto výkonného selenového rámce zvaného POM nebo stránkový objektový model panuje rozruch. Nyní vyvstává otázka „Proč používat POM?“.
Jednoduchá odpověď na to je, že POM je kombinací datově řízeného, modulárního a hybridního rámce. Jedná se o přístup k systematické organizaci skriptů takovým způsobem, že QA usnadňuje udržování kódu bez potíží a také pomáhá předcházet nadbytečnému nebo duplicitnímu kódu.
Například pokud dojde ke změně hodnoty lokátoru na konkrétní stránce, je velmi snadné ji identifikovat a provést tuto rychlou změnu pouze ve skriptu příslušné stránky, aniž by to ovlivnilo kód jinde.
Koncept Page Object Model používáme v Selenium Webdriver z následujících důvodů:
- V tomto modelu POM je vytvořeno úložiště objektů. Je nezávislý na testovacích případech a lze jej znovu použít pro jiný projekt.
- Konvence pojmenování metod je velmi snadná, srozumitelná a realističtější.
- Pod objektovým modelem stránky vytváříme třídy stránek, které lze znovu použít v jiném projektu.
- Objektový model Page je pro vyvinutý rámec snadný díky několika výhodám.
- V tomto modelu se vytvářejí samostatné třídy pro různé stránky webové aplikace, jako je přihlašovací stránka, domovská stránka, stránka podrobností zaměstnanců, stránka pro změnu hesla atd.
- Pokud dojde k jakékoli změně v jakémkoli prvku webové stránky, musíme provést změny pouze v jedné třídě, a ne ve všech třídách.
- Navrhovaný skript je více přístupný, čitelný a udržovatelný v přístupu k modelu objektu stránky.
- Jeho struktura projektu je poměrně snadná a srozumitelná.
- Lze použít PageFactory v modelu objektu stránky za účelem inicializace webového prvku a uložení prvků do mezipaměti.
- TestNG lze také integrovat do přístupu Page Object Model.
Implementace jednoduchého POM v selenu
# 1) Scénář k automatizaci
Nyní automatizujeme daný scénář pomocí modelu objektu stránky.
Scénář je vysvětlen níže:
Krok 1: Spusťte web „https: //demo.vtiger.com“.
Krok 2: Zadejte platné pověření.
Krok 3: Přihlaste se na web.
Krok 4: Ověřte domovskou stránku.
Krok 5: Odhlaste web.
Krok 6: Zavřete prohlížeč.
# 2) Selenové skripty pro výše uvedený scénář v POM
Nyní vytvoříme strukturu POM v Eclipse, jak je vysvětleno níže:
Krok 1: Vytvořte projekt v Eclipse - struktura založená na POM:
a) Vytvořte projekt „Model objektu stránky“.
b) Vytvořte 3 balíček v rámci projektu.
- knihovna
- stránky
- testovací případy
Knihovna: Pod toto vložíme ty kódy, které je třeba volat znovu a znovu v našich testovacích případech, jako je spuštění prohlížeče, screenshoty atd. Uživatel může pod něj přidat další třídy podle potřeby projektu.
Stránky: Pod tímto se vytvářejí třídy pro každou stránku ve webové aplikaci a mohou přidávat další třídy stránek na základě počtu stránek v aplikaci.
Testovací případy: Pod tímto textem napíšeme testovací případ přihlášení a podle potřeby můžeme přidat další testovací případy k otestování celé aplikace.
c) Třídy v rámci balíčků jsou zobrazeny na obrázku níže.
Krok dva: V balíčku knihovny vytvořte následující třídy.
Browser.java: V této třídě jsou definovány 3 prohlížeče (Firefox, Chrome a Internet Explorer), které jsou volány v testovacím případě přihlášení. Na základě požadavku může uživatel otestovat aplikaci také v různých prohlížečích.
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: V této třídě je napsán program pro snímek obrazovky a je vyvolán v testovacím případě, když chce uživatel pořídit snímek obrazovky o tom, zda test selže nebo vyhovuje.
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(); } } }
Krok 3: Vytvořte třídy stránek v části Balíček stránek.
HomePage.java: Toto je třída domovské stránky, ve které jsou definovány všechny prvky domovské stránky a metody.
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: Toto je třída Přihlašovací stránka, ve které jsou definovány všechny prvky přihlašovací stránky a metody.
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(); } }
Krok 4: Vytvořte testovací případy pro scénář přihlášení.
LoginTestCase.java: Toto je třída LoginTestCase, kde je spuštěn testovací případ. Uživatel může také vytvořit více testovacích případů podle potřeby projektu.
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(); } }
Krok 5: Spusťte „LoginTestCase.java“.
Krok 6: Výstup objektového modelu stránky:
- Spusťte prohlížeč Chrome.
- Ukázkový web se otevře v prohlížeči.
- Přihlaste se na demo stránku.
- Ověřte domovskou stránku.
- Odhlaste web.
- Zavřete prohlížeč.
Nyní prozkoumáme hlavní koncept tohoto tutoriálu, který upoutá pozornost, tj. „Pagefactory“.
Co je Pagefactory?
PageFactory je způsob implementace „Page Object Model“. Zde se řídíme zásadou oddělení úložiště stránek a testovacích metod. Jedná se o zabudovaný koncept Page Object Model, který je velmi optimalizovaný.
Pojďme nyní objasnit termín Pagefactory.
# 1) Za prvé, koncept s názvem Pagefactory, poskytuje alternativní způsob, pokud jde o syntaxi a sémantiku, pro vytvoření úložiště objektů pro webové prvky na stránce.
#dva) Za druhé, používá trochu jinou strategii pro inicializaci webových prvků.
# 3) Úložiště objektů pro webové prvky uživatelského rozhraní lze vytvořit pomocí:
- Obvyklý „POM bez Pagefactory“ a
- Alternativně můžete použít „POM with Pagefactory“.
Níže je uvedeno jejich obrazové znázornění:
Nyní se podíváme na všechny aspekty, které odlišují obvyklý POM od POM pomocí Pagefactory.
a) Rozdíl v syntaxi umístění prvku pomocí obvyklého POM vs POM s Pagefactory.
Například , Klepněte na tady vyhledejte vyhledávací pole, které se zobrazí na stránce.
POM bez Pagefactory:
# 1) Níže je uvedeno, jak vyhledáte vyhledávací pole pomocí obvyklého POM:
WebElement searchNSETxt=driver.findElement(By.id(“searchBox”));
# 2) Níže uvedený krok předá hodnotu „investice“ do pole Hledat NSE.
searchNSETxt.sendkeys(“investment”);
POM pomocí Pagefactory:
# 1) Vyhledávací pole můžete vyhledat pomocí Pagefactory, jak je uvedeno níže.
Anotace @FindBy se používá v Pagefactory k identifikaci prvku, zatímco POM bez Pagefactory používá driver.findElement () metoda vyhledání prvku.
Druhé prohlášení pro Pagefactory po @FindBy je přiřazení typu WebElement třída, která funguje přesně podobně jako přiřazení názvu prvku typu WebElement třídy jako návratový typ metody driver.findElement () který se používá v obvyklém POM (v tomto příkladu searchNSETxt).
Podíváme se na @FindBy anotace podrobně v nadcházející části tohoto tutoriálu.
@FindBy(id = 'searchBox') WebElement searchNSETxt;
#dva) Níže uvedený krok předá hodnotu „investice“ do pole Hledat NSE a syntaxe zůstane stejná jako u obvyklého POM (POM bez Pagefactory).
searchNSETxt.sendkeys(“investment”);
b) Rozdíl ve strategii inicializace webových prvků pomocí obvyklých POM vs POM s Pagefactory.
Používání POM bez Pagefactory:
Níže je uveden fragment kódu pro nastavení cesty ovladače Chrome. Instance WebDriver je vytvořena s ovladačem názvu a ChromeDriver je přiřazen k „ovladači“. Stejný objekt ovladače se poté použije ke spuštění webu národní burzy cenných papírů, vyhledání pole searchBox a zadání hodnoty řetězce do pole.
Bod, který bych zde chtěl zdůraznit, je, že když je to POM bez továrny na stránky, instance ovladače je vytvořena zpočátku a každý webový prvek je nově inicializován pokaždé, když dojde k volání tohoto webového prvku pomocí driver.findElement () nebo driver .findElements ().
To je důvod, proč s novým krokem driver.findElement () pro prvek je struktura DOM znovu prohledána a na této stránce je provedena obnovená identifikace prvku.
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”);
Používání POM s Pagefactory:
Kromě použití poznámky @FindBy namísto metody driver.findElement () se pro Pagefactory navíc používá níže uvedený fragment kódu. Statická metoda initElements () třídy PageFactory se používá k inicializaci všech prvků uživatelského rozhraní na stránce, jakmile se stránka načte.
public PagefactoryClass(WebDriver driver) { this.driver = driver; PageFactory.initElements(driver, this); }
Výše uvedená strategie činí přístup PageFactory mírně odlišným od obvyklého POM. V obvyklém POM musí být webový prvek explicitně inicializován, zatímco v přístupu Pagefactory jsou všechny prvky inicializovány pomocí initElements () bez výslovné inicializace každého webového prvku.
Například: Pokud byl WebElement deklarován, ale nebyl inicializován v obvyklém POM, je vyvolána chyba „inicializovat proměnnou“ nebo NullPointerException. Proto v obvyklém POM musí být každý WebElement explicitně inicializován. PageFactory má v tomto případě výhodu oproti obvyklému POM.
Neinicializujeme webový prvek BDate (POM bez Pagefactory), můžete vidět, že chyba „Inicializovat proměnnou“ se zobrazí a vyzve uživatele, aby ji inicializoval na hodnotu null, proto nemůžete předpokládat, že se prvky implicitně inicializují při jejich vyhledání.
Explicitně inicializován prvek BDate (POM bez Pagefactory):
Nyní se podívejme na několik instancí kompletního programu pomocí PageFactory, abychom vyloučili jakoukoli nejednoznačnost v porozumění aspektu implementace.
Příklad 1:
- Přejít na „http://www.nseindia.com/“
- V rozbalovací nabídce vedle vyhledávacího pole vyberte možnost „Měnové deriváty“.
- Vyhledejte „USDINR“. Na výsledné stránce ověřte text „americký dolar-indická rupie - USDINR“.
Struktura programu:
- Vytvoří se stránka PagefactoryClass.java, která obsahuje úložiště objektů pomocí konceptu stránky stránky pro nseindia.com, což je konstruktor pro inicializaci všech webových prvků, metoda selectCurrentDerivative () pro výběr hodnoty z rozevíracího pole Vyhledávací pole, selectSymbol () pro výběr symbolu na stránka, která se zobrazí další, a verifytext () k ověření, zda je záhlaví stránky podle očekávání nebo ne.
- NSE_MainClass.java je hlavní soubor třídy, který volá všechny výše uvedené metody a provádí příslušné akce na webu 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 Příklad 2:
- Přejít na „https://www.shoppersstop.com/brands“
- Přejděte na odkaz Haute curry.
- Ověřte, zda stránka Haute Curry obsahuje text „Spustit něco nového“.
Struktura programu
- shopperstopPagefactory.java, která obsahuje úložiště objektů pomocí konceptu pagefactory pro shoppersstop.com, což je konstruktor pro inicializaci všech webových prvků, metody closeExtraPopup () pro zpracování vyskakovacího okna s upozorněním, které se otevře, klikněte na OnHauteCurryLink () a klikněte na Haute Curry Propojením a ověřenímStartNewSomething () ověřte, zda stránka Haute Curry obsahuje text „Spustit něco nového“.
- Shopperstop_CallPagefactory.java je soubor hlavní třídy, který volá všechny výše uvedené metody a provádí příslušné akce na webu 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 pomocí Page Factory
Videonávody - POM se stránkou Factory
Část I.
Část II
Třída Factory se používá k tomu, aby bylo používání objektů stránky jednodušší a jednodušší.
- Nejprve musíme najít webové prvky pomocí anotace @FindBy ve třídách stránek .
- Při instalování třídy stránky pak inicializujte prvky pomocí initElements ().
# 1) @FindBy:
@FindBy anotace se používá v PageFactory k vyhledání a deklaraci webových prvků pomocí různých lokátorů.Tady předáme atribut i jeho hodnotu použitou k vyhledání webového prvku do anotace @FindBy a poté bude deklarován WebElement.
Existují 2 způsoby, jak lze anotaci použít.
Například:
@FindBy(how = How.ID, using='EmailAddress') WebElement Email; @FindBy(id='EmailAddress') WebElement Email;
První z nich je však standardní způsob deklarace WebElements.
'Jak' je třída a má statické proměnné jako ID, XPATH, CLASSNAME, LINKTEXT atd.
'použitím' - Přiřadit hodnotu statické proměnné.
Ve výše uvedeném příklad , k vyhledání webového prvku „Email“ jsme použili atribut „id“. Podobně můžeme použít následující lokátory s anotacemi @FindBy:
- jméno třídy
- css
- název
- xpath
- název štítku
- linkText
- partialLinkText
# 2) initElements ():
InitElements je statická metoda třídy PageFactory, která se používá k inicializaci všech webových prvků umístěných pomocí anotace @FindBy. Snadné vytváření instancí tříd Page.
initElements(WebDriver driver, java.lang.Class pageObjectClass)
Měli bychom také pochopit, že POM dodržuje zásady OOPS.
- WebElements jsou deklarovány jako soukromé členské proměnné (Data Hiding).
- Vazba WebElements s odpovídajícími metodami (zapouzdření).
Kroky k vytvoření POM pomocí vzoru Page Factory
# 1) Pro každou webovou stránku vytvořte samostatný soubor třídy Java.
#dva) V každé třídě by všechny WebElements měly být deklarovány jako proměnné (pomocí anotace - @FindBy) a inicializovány pomocí metody initElement (). Deklarované WebElements musí být inicializovány, aby mohly být použity v metodách akce.
# 3) Definujte odpovídající metody působící na tyto proměnné.
Uveďme si příklad jednoduchého scénáře:
- Otevřete adresu URL aplikace.
- Zadejte e-mailovou adresu a heslo.
- Klikněte na tlačítko Přihlášení.
- Ověřte úspěšnou přihlašovací zprávu na stránce vyhledávání.
Vrstva stránky
Tady máme 2 stránky,
- Domovská stránka - Stránka, která se otevře po zadání adresy URL a kde zadáme údaje pro přihlášení.
- Hledat na stránce - Stránka, která se zobrazí po úspěšném přihlášení.
Ve vrstvě stránky je každá stránka ve webové aplikaci deklarována jako samostatná třída Java a jsou zde uvedeny její vyhledávače a akce.
Kroky k vytvoření POM s příkladem v reálném čase
# 1) Vytvořte třídu Java pro každou stránku:
V tomhle příklad , přejdeme na 2 webové stránky, stránky „Domovská stránka“ a „Hledat“.
Proto vytvoříme 2 třídy Java ve Page Layer (nebo v balíčku řekněme com.automation.pages).
Package Name :com.automation.pages HomePage.java SearchPage.java
# 2) Definujte WebElements jako proměnné pomocí anotace @FindBy:
Byli bychom v interakci s:
- Pole tlačítka E-mail, heslo, přihlášení na domovské stránce.
- Úspěšná zpráva na stránce vyhledávání.
Definujeme tedy WebElements pomocí @FindBy
Například: Pokud budeme identifikovat EmailAddress pomocí atributu id, pak je její deklarace proměnné
//Locator for EmailId field @FindBy(how=How.ID,using='EmailId') private WebElementEmailIdAddress;
# 3) Vytvořte metody pro akce prováděné na WebElements.
Na WebElements se provádějí níže uvedené akce:
- Do pole E-mailová adresa zadejte akci.
- Do pole Heslo zadejte akci.
- Klikněte na akci na přihlašovacím tlačítku.
Například, Uživatelem definované metody se vytvářejí pro každou akci na WebElement jako,
public void typeEmailId(String Id){ driver.findElement(EmailAddress).sendKeys(Id) }
Zde se Id předává jako parametr v metodě, protože vstup bude odeslán uživatelem z hlavního testovacího případu.
Poznámka :V každé ze tříd ve vrstvě stránky musí být vytvořen konstruktor, aby bylo možné získat instanci ovladače z třídy Main v testovací vrstvě a také inicializovat WebElements (objekty stránky) deklarované ve třídě stránky pomocí PageFactory.InitElement () .
Ovladač zde neinicializujeme, spíše je jeho instance přijata z hlavní třídy, když je vytvořen objekt třídy Page Layer.
InitElement () - slouží k inicializaci deklarovaných WebElements pomocí instance ovladače z hlavní třídy. Jinými slovy, WebElements se vytvářejí pomocí instance ovladače. Teprve po inicializaci WebElements je lze použít v metodách k provádění akcí.
Pro každou stránku jsou vytvořeny dvě třídy Java, jak je uvedeno níže:
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. } }
Testovací vrstva
V této třídě jsou implementovány testovací případy. Vytvoříme samostatný balíček, řekněme, com.automation.test a pak zde vytvoříme třídu Java (MainClass.java)
Kroky k vytvoření testovacích případů:
- Inicializujte ovladač a otevřete aplikaci.
- Vytvořte objekt třídy PageLayer (pro každou webovou stránku) a předejte instanci ovladače jako parametr.
- Pomocí vytvořeného objektu zavolejte metody ve třídě PageLayer (pro každou webovou stránku), abyste mohli provádět akce / ověření.
- Opakujte krok 3, dokud nebudou provedeny všechny akce, a poté zavřete ovladač.
//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(); } }
Pro deklaraci WebElements se používá hierarchie typu poznámky
Anotace se používají k vytvoření strategie umístění pro prvky uživatelského rozhraní.
# 1) @FindBy
Pokud jde o Pagefactory, @FindBy funguje jako kouzelná hůlka. Dodává koncepci veškerou sílu. Nyní víte, že anotace @FindBy v Pagefactory funguje stejně jako u driver.findElement () v obvyklém objektovém modelu stránky. Používá se k vyhledání WebElement / WebElements s jedním kritériem .
# 2) @FindBys
Používá se k vyhledání WebElement s více než jedno kritérium a musí splňovat všechna uvedená kritéria. Tato kritéria by měla být uvedena ve vztahu rodič-dítě. Jinými slovy, toto používá AND podmíněný vztah k vyhledání WebElements pomocí zadaných kritérií. K definování každého kritéria používá více @FindBy.
Například:
Zdrojový kód HTML prvku WebElement:
V POM:
@FindBys({ @FindBy(id = 'searchId_1'), @FindBy(name = 'search_field') }) WebElementSearchButton;
Ve výše uvedeném příkladu je prvek WebElement „SearchButton“ umístěn pouze v případě, že je odpovídá oběma kritéria, jejichž id hodnota je „searchId_1“ a hodnota názvu je „search_field“. Pamatujte, že první kritérium patří nadřazené značce a druhé kritérium podřízené značce.
# 3) @FindAll
Používá se k vyhledání WebElement s více než jedno kritérium a musí splňovat alespoň jedno z daných kritérií. To používá NEBO podmíněné vztahy k vyhledání WebElements. K definování všech kritérií používá více @FindBy.
Například:
Zdrojový kód HTML:
V POM:
@FindBys({ @FindBy(id = 'UsernameNameField_1'), // doesn’t match @FindBy(name = 'User_Id') //matches @FindBy(className = “UserName_r”) //matches }) WebElementUserName;
Ve výše uvedeném příkladu je WebElement „Uživatelské jméno umístěno, pokud je odpovídá alespoň jednomu uvedených kritérií.
# 4) @CacheLookUp
Když se WebElement v testovacích případech používá častěji, vyhledá Selenium WebElement pokaždé, když je spuštěn testovací skript. V těch případech, kdy se určité WebElements globálně používají pro všechny TC ( Například, Scénář přihlášení se stane pro každou TC), tuto anotaci lze použít k udržení těchto WebElements v mezipaměti, jakmile je načtena poprvé.
To zase pomáhá kódu spouštět se rychleji, protože pokaždé, když nemusí hledat WebElement na stránce, může získat odkaz z paměti.
Může to být předpona s libovolným z @FindBy, @FindBys a @FindAll.
Například:
@CacheLookUp @FindBys({ @FindBy(id = 'UsernameNameField_1'), @FindBy(name = 'User_Id') @FindBy(className = “UserName_r”) }) WebElementUserName;
Upozorňujeme, že tato anotace by měla být použita pouze pro WebElements, jejichž hodnota atributu (jako xpath, id name, class name atd.) Se nemění dost často. Jakmile je WebElement umístěn poprvé, udržuje svůj odkaz v mezipaměti.
Takže poté dojde ke změně atributu WebElement po několika dnech, Selenium nebude moci prvek najít, protože ve své mezipaměti již má svůj starý odkaz a nebude brát v úvahu nedávnou změnu ve WebElementu.
Více na PageFactory.initElements ()
Nyní, když rozumíme strategii Pagefactory při inicializaci webových prvků pomocí InitElements (), zkusme pochopit různé verze metody.
Metoda, jak víme, vezme objekt ovladače a aktuální objekt třídy jako vstupní parametry a vrátí objekt stránky implicitně a proaktivně inicializující všechny prvky na stránce.
V praxi je použití konstruktoru, jak je znázorněno ve výše uvedené části, výhodnější než jiné způsoby jeho použití.
Alternativní způsoby volání metody je:
# 1) Místo použití ukazatele „this“ můžete vytvořit aktuální objekt třídy, předat mu instanci ovladače a zavolat statickou metodu initElements s parametry, tj. Objekt ovladače a objekt třídy, který byl právě vytvořen.
public PagefactoryClass(WebDriver driver) { //version 2 PagefactoryClass page=new PagefactoryClass(driver); PageFactory.initElements(driver, page); }
#dva) Třetím způsobem, jak inicializovat prvky pomocí třídy Pagefactory, je použití rozhraní API zvaného „reflexe“. Ano, namísto vytvoření objektu třídy pomocí klíčového slova „new“ lze předat classname.class jako součást vstupního parametru initElements ().
public PagefactoryClass(WebDriver driver) { //version 3 PagefactoryClass page=PageFactory.initElements(driver, PagefactoryClass.class); }
Často kladené otázky
Otázka č. 1) Jaké jsou různé strategie lokátorů, které se používají pro @FindBy?
Odpovědět: Jednoduchá odpověď na to je, že pro @FindBy neexistují žádné jiné strategie lokátorů.
Používají stejné strategie 8 lokátorů, které používá metoda findElement () v obvyklém POM:
- id
- název
- jméno třídy
- xpath
- css
- název štítku
- linkText
- partialLinkText
Otázka č. 2) Existují různé verze pro použití anotací @FindBy?
Odpovědět: Když je třeba prohledat webový prvek, použijeme anotaci @FindBy. Vypracujeme také alternativní způsoby použití @FindBy spolu s různými lokačními strategiemi.
Už jsme viděli, jak používat verzi 1 @FindBy:
@FindBy(id = 'cidkeyword') WebElement Symbol;
Verze 2 @FindBy je předáním vstupního parametru jako Jak a Použitím .
Jak hledá strategii lokátoru, pomocí které by byl identifikován webový prvek. Klíčové slovo použitím definuje hodnotu lokátoru.
Pro lepší pochopení viz níže
- How.ID prohledá prvek pomocí id strategie a prvek, který se pokouší identifikovat, má id = klíčové slovo.
@FindBy(how = How.ID, using = ' cidkeyword') WebElement Symbol;
- How.CLASS_NAME prohledává prvek pomocí jméno třídy strategie a prvek, který se pokouší identifikovat, má class = nová třída.
@FindBy(how = How.CLASS_NAME, using = 'newclass') WebElement Symbol;
Otázka č. 3) Existuje rozdíl mezi dvěma verzemi @FindBy?
Odpovědět: Odpověď zní Ne, mezi těmito dvěma verzemi není žádný rozdíl. Jde jen o to, že první verze je ve srovnání s druhou verzí kratší a jednodušší.
Otázka č. 4) Co mám použít v pagefactory v případě, že existuje seznam webových prvků, které mají být umístěny?
Odpovědět: V obvyklém vzorovém vzoru objektu stránky máme driver.findElements () k vyhledání více prvků patřících ke stejné třídě nebo názvu značky, ale jak takové prvky vyhledáme v případě modelu objektu stránky s Pagefactory? Nejjednodušší způsob, jak dosáhnout těchto prvků, je použít stejnou anotaci @FindBy.
Chápu, že se tento řádek zdá být pro mnohé z vás škrábancem. Ale ano, je to odpověď na otázku.
Podívejme se na níže uvedený příklad:
Pomocí obvyklého objektového modelu stránky bez Pagefactory použijete driver.findElements k vyhledání více prvků, jak je znázorněno níže:
private List multipleelements_driver_findelements = driver.findElements (By.class(“last”));
Totéž lze dosáhnout pomocí modelu objektu stránky s Pagefactory, jak je uvedeno níže:
@FindBy (how = How.CLASS_NAME, using = 'last') private List multipleelements_FindBy;
Přiřazení prvků do seznamu typu WebElement v zásadě dělá trik bez ohledu na to, zda je při identifikaci a lokalizaci prvků použit Pagefactory nebo ne.
Otázka č. 5) Lze ve stejném programu použít jak návrh objektu Page bez pagefactory, tak s Pagefactory?
Odpovědět: Ano, návrh objektu stránky bez Pagefactory a Pagefactory lze použít ve stejném programu. Můžete projít programem uvedeným níže v Odpověď na otázku č. 6 abyste zjistili, jak jsou oba použity v programu.
Jedna věc, kterou si musíte pamatovat, je, že konceptu Pagefactory s funkcí v mezipaměti je třeba se vyhnout na dynamických prvcích, zatímco design objektu stránky funguje dobře pro dynamické prvky. Pagefactory však vyhovuje pouze statickým prvkům.
Otázka č. 6) Existují alternativní způsoby identifikace prvků na základě více kritérií?
jak stáhnout celý seznam skladeb z youtube bez softwaru
Odpovědět: Alternativou pro identifikaci prvků na základě více kritérií je použití anotací @FindAll a @FindBys. Tyto anotace pomáhají identifikovat jeden nebo více prvků v závislosti na hodnotách získaných z kritérií předaných v něm.
# 1) @FindAll:
@FindAll může obsahovat více @FindBy a vrátí všechny prvky, které odpovídají libovolnému @FindBy v jediném seznamu. @FindAll se používá k označení pole v objektu stránky k označení, že by vyhledávání mělo používat řadu značek @FindBy. Poté vyhledá všechny prvky, které odpovídají některému z kritérií FindBy.
U prvků není zaručeno, že budou v pořadí dokumentů.
Syntaxe pro použití @FindAll je uvedena níže:
@FindAll( { @FindBy(how = How.ID, using = 'foo'), @FindBy(className = 'bar') } )
Vysvětlení: @FindAll prohledá a identifikuje samostatné prvky vyhovující každému z kritérií @FindBy a vypsá je. Ve výše uvedeném příkladu nejprve prohledá prvek, jehož id = ”foo” a poté identifikuje druhý prvek pomocí className = ”bar”.
Za předpokladu, že u každého kritéria FindBy byl identifikován jeden prvek, výsledkem @FindAll bude vypsání 2 prvků. Nezapomeňte, že pro každé kritérium může být identifikováno více prvků. Jednoduše řečeno, @ Najít vše působí rovnocenně jako NEBO operátor předán kritériím @FindBy.
# 2) @FindBys:
FindBys se používá k označení pole na objektu stránky k označení, že vyhledávání by mělo používat řadu značek @FindBy v řetězci, jak je popsáno v ByChained. Když se požadované objekty WebElement musí shodovat se všemi danými kritérii, použijte @FindBys anotaci.
Syntaxe pro použití @FindBys je uvedena níže:
@FindBys( { @FindBy(name=”foo”) @FindBy(className = 'bar') } )
Vysvětlení: @FindBys prohledá a identifikuje prvky vyhovující všem kritériím @FindBy a vypsá je. Ve výše uvedeném příkladu bude vyhledávat prvky, jejichž name = „foo“ a className = „bar“.
@FindAll bude mít za následek vypsání 1 prvku, pokud předpokládáme, že byl v daných kritériích identifikován jeden prvek s názvem a názvem třídy.
Pokud neexistuje jeden prvek splňující všechny předané podmínky FindBy, bude výsledkem @FindBys nula prvků. Mohl by být identifikován seznam webových prvků, pokud všechny podmínky splňují více prvků. Jednoduše řečeno, @ FindBys působí rovnocenně jako A operátor předán kritériím @FindBy.
Podívejme se na implementaci všech výše uvedených anotací prostřednictvím podrobného programu:
Upravíme program www.nseindia.com uvedený v předchozí části, abychom porozuměli implementaci anotací @FindBy, @FindBys a @FindAll
# 1) Úložiště objektů PagefactoryClass je aktualizováno níže:
Seznam newlist = driver.findElements (By.tagName („a“));
@FindBy (jak = jak. NÁZEV ŠTÍTKU , pomocí = „a“)
soukromé Seznam findbyvalue;
@FindAll ({ @FindBy (className = “sel”), @FindBy (xpath = ”// a (@ id =‘ tab5 ′) ”)})
soukromé Seznam findallvalue;
@FindBys ({ @FindBy (className = “sel”), @FindBy (xpath = ”// a (@ id =‘ tab5 ′) ”)})
soukromé Seznam findbysvalue;
# 2) Nová metoda seeHowFindWorks () je zapsána do PagefactoryClass a je vyvolána jako poslední metoda ve třídě Main.
Metoda je uvedena níže:
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 Níže je uveden výsledek zobrazený v okně konzoly po provedení programu:
Pokusme se nyní podrobně porozumět kódu:
# 1) Prostřednictvím návrhového vzoru objektu stránky identifikuje prvek „nový seznam“ všechny značky s kotvou „a“. Jinými slovy, získáme počet všech odkazů na stránce.
Zjistili jsme, že pagefactory @FindBy dělá stejnou práci jako driver.findElement (). Prvek findbyvalue je vytvořen za účelem získání počtu všech odkazů na stránce prostřednictvím strategie vyhledávání s konceptem pagefactory.
Ukázalo se správné, že driver.findElement () a @FindBy dělají stejnou práci a identifikují stejné prvky. Pokud se podíváte na snímek obrazovky výsledného okna konzoly výše, počet odkazů identifikovaných u prvku newlist a u findbyvalue je stejný, tj. 299 odkazy nalezené na stránce.
Výsledek se ukázal níže:
driver.findElements(By.tagName()) 299 count of @FindBy- list elements 299
#dva) Zde zpracováváme fungování anotace @FindAll, která se bude týkat seznamu webových prvků s názvem findallvalue.
Při pohledu na každé kritérium @FindBy v anotaci @FindAll první kritérium @FindBy hledá prvky s className = 'sel' a druhé kritérium @FindBy hledá konkrétní prvek s XPath = “// a (@ id = 'tab5')
Pojďme nyní stisknout klávesu F12, abychom zkontrolovali prvky na stránce nseindia.com a získali určité věty o prvcích odpovídajících kritériím @FindBy.
Na stránce jsou dva prvky odpovídající className = ”sel”:
na) Prvek „Fundamentals“ má značku seznamu, tj.
s className = ”sel”. Viz snímek níže
b) Další prvek „Order Book“ má XPath s kotevní značkou, která má název třídy jako „sel“.
C) Druhý @FindBy s XPath má kotevní značku, jejíž id je ' tab5 “. V reakci na hledání je identifikován pouze jeden prvek, kterým je Základy.
Podívejte se na snímek níže:
Když byl spuštěn test nseindia.com, dostali jsme počet prohledávaných prvků.
@FindAll as 3. Prvky pro findallvalue při zobrazení byly: Fundamentals as the 0thindexový prvek, Kniha objednávek jako 1Svatýindexový prvek a Základy opět jako 2ndindexový prvek. Už jsme se naučili, že @FindAll identifikuje prvky pro každé kritérium @FindBy samostatně.
Podle stejného protokolu identifikoval pro první vyhledávací kritérium, tj. ClassName = „sel“, dva prvky splňující podmínku a načetl „Fundamentals“ a „Order Book“.
Poté se přesunul na další kritéria @FindBy a podle cesty xp uvedené pro druhé @FindBy by mohl načíst prvek ‚Fundamentals '. Proto nakonec identifikoval 3 prvky.
Nezíská tedy prvky splňující ani jednu z podmínek @FindBy, ale zabývá se samostatně s každou z @FindBy a identifikuje prvky podobně. V aktuálním příkladu jsme také viděli, že nesleduje, zda jsou prvky jedinečné ( Např. Prvek „Základy“ v tomto případě, který se zobrazil dvakrát jako součást výsledku dvou kritérií @FindBy)
# 3) Zde zpracováváme fungování anotace @FindBys, která se bude týkat seznamu webových prvků s názvem findbysvalue. I zde první kritérium @FindBy vyhledává prvky s className = ‘sel‘ a druhé kritérium @FindBy vyhledává konkrétní prvek pomocí xpath = “// a (@ id =” tab5 ”).
Nyní, když víme, jsou pro první podmínku @FindBy identifikovány prvky „Fundamentals“ a „Order Book“ a u druhého kritéria @FindBy je to „Fundamentals“.
Jak se tedy výsledný @FindBys bude lišit od @FindAll? V předchozí části jsme se dozvěděli, že @FindBys je ekvivalentní podmíněnému operátoru AND, a proto hledá prvek nebo seznam prvků, které splňují všechny podmínky @FindBy.
Podle našeho aktuálního příkladu je hodnota „Fundamentals“ jediným prvkem, který má class = „sel“ a id = „tab5“, čímž splňuje obě podmínky. To je důvod, proč @FindBys velikost v out testcase je 1 a zobrazuje hodnotu jako „Fundamentals“.
Ukládání prvků do mezipaměti v Pagefactory
Pokaždé, když je stránka načtena, všechny prvky na stránce jsou znovu vyhledány vyvoláním volání pomocí @FindBy nebo driver.findElement () a na stránce je nové hledání prvků.
Většinu času, kdy jsou prvky dynamické nebo se za běhu neustále mění, zejména pokud se jedná o prvky AJAX, určitě dává smysl, že při každém načtení stránky je nové vyhledávání všech prvků na stránce.
Pokud má webová stránka statické prvky, může být ukládání do mezipaměti elementu možné několika způsoby. Když jsou prvky ukládány do mezipaměti, nemusí je při načítání stránky znovu vyhledávat, místo toho může odkazovat na úložiště prvků v mezipaměti. To šetří spoustu času a zvyšuje lepší výkon.
Pagefactory poskytuje tuto funkci ukládání prvků do mezipaměti pomocí anotace @CacheLookUp .
Anotace říká ovladači, aby pro prvky použil stejnou instanci lokátoru z DOM a znovu je neprohledával, zatímco metoda initElements stránky pagefactory prominentně přispívá k ukládání statického prvku v mezipaměti. InitElements dělají práci mezipaměti prvků.
Díky tomu je koncept pagefactory speciální oproti běžnému vzorovému designu objektu stránky. Přichází s vlastními klady a zápory, o kterých si povíme něco později. Například přihlašovací tlačítko na domovské stránce Facebooku je statický prvek, který lze uložit do mezipaměti a je ideálním prvkem do mezipaměti.
Pojďme se nyní podívat na to, jak implementovat anotaci @CacheLookUp
Nejprve budete muset nejprve importovat balíček pro Cachelookup:
import org.openqa.selenium.support.CacheLookup
Níže je úryvek zobrazující definici prvku pomocí @CacheLookUp. Jakmile je UniqueElement poprvé prohledán, uloží initElement () verzi prvku uloženou v mezipaměti, takže příště ovladač nehledá prvek místo toho odkazuje na stejnou mezipaměť a provede akci vpravo od prvku pryč.
@FindBy(id = 'unique') @CacheLookup private WebElement UniqueElement;
Podívejme se nyní na skutečný program, jak jsou akce u webového prvku v mezipaměti rychlejší než u webového prvku bez mezipaměti:
Vylepšení programu nseindia.com dále Napsal jsem další novou metodu monitorPerformance (), ve které vytvořím prvek uložený v mezipaměti pro vyhledávací pole a prvek bez mezipaměti pro stejné vyhledávací pole.
Pak se pokusím získat tagname prvku 3000krát jak pro prvek uložený v mezipaměti, tak pro prvek bez mezipaměti a pokusím se měřit čas potřebný k dokončení úkolu u prvku uloženého v mezipaměti i bez mezipaměti.
Zvažoval jsem 3000krát, abychom viděli viditelný rozdíl v časování těchto dvou. Očekávám, že by prvek uložený v mezipaměti měl dokončit získání názvu značky 3000krát za kratší dobu ve srovnání s prvkem bez mezipaměti.
Nyní víme, proč by měl prvek uložený v mezipaměti fungovat rychleji, tj. Řidič je instruován, aby nevyhledával prvek po prvním vyhledávání, ale přímo na něm dále pracoval, a to není případ prvku bez mezipaměti, kde se vyhledávání prvku provádí pro vše 3000krát a poté se na něm provede akce.
Níže je uveden kód metody 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'); }
Při spuštění uvidíme v okně konzoly níže uvedený výsledek:
Podle výsledku je úkol na prvku bez mezipaměti dokončen v 82 sekund, zatímco čas potřebný k dokončení úkolu na prvku uloženém v mezipaměti byl pouze 37 sekundy. Toto je skutečně viditelný rozdíl v době odezvy prvku uloženého v mezipaměti i bez mezipaměti.
Otázka č. 7) Jaké jsou výhody a nevýhody anotace @CacheLookUp v konceptu Pagefactory?
Odpovědět:
Pros @CacheLookUp a situace možné pro jeho použití:
@CacheLookUp je proveditelné, když jsou prvky statické nebo se při načítání stránky vůbec nezmění. Tyto prvky nemění dobu běhu. V takových případech je vhodné použít anotaci ke zlepšení celkové rychlosti provedení testu.
Nevýhody anotace @CacheLookUp:
Největší nevýhodou prvků uložených v mezipaměti s anotací je strach z častého získávání StaleElementReferenceExceptions.
Dynamické prvky se obnovují poměrně často s těmi, které se mohou rychle měnit během několika sekund nebo minut časového intervalu.
Níže uvádíme několik takových instancí dynamických prvků:
- Na webové stránce jsou stopky, které každou sekundu aktualizují časovač.
- Rámeček, který neustále aktualizuje zprávu o počasí.
- Stránka vykazující aktuální aktualizace Sensexu.
Nejsou vůbec ideální nebo proveditelné pro použití anotace @CacheLookUp. Pokud tak učiníte, riskujete, že dostanete výjimku StaleElementReferenceExceptions.
Při ukládání těchto prvků do mezipaměti se během provádění testu změní DOM prvků, nicméně ovladač vyhledá verzi DOM, která již byla při ukládání do mezipaměti uložena. Díky tomu bude zastaralý prvek vyhledán ovladačem, který již na webové stránce neexistuje. To je důvod, proč je vyvolána výjimka StaleElementReferenceException.
Třídy továrny:
Pagefactory je koncept postavený na několika továrních třídách a rozhraních. Zde se v této části dozvíme o několika továrních třídách a rozhraních. Jen málo z nich se podíváme AjaxElementLocatorFactory , ElementLocatorFactory a DefaultElementFactory.
Přemýšleli jsme někdy, jestli Pagefactory poskytuje nějaký způsob, jak začlenit implicitní nebo explicitní čekání na prvek, dokud není splněna určitá podmínka ( Příklad: Dokud nebude prvek viditelný, povolený, klikatelný atd.)? Pokud ano, je zde vhodná odpověď.
AjaxElementLocatorFactory je jedním z významných přispěvatelů mezi všemi třídami továrny. Výhodou AjaxElementLocatorFactory je, že můžete třídě časového objektu přiřadit hodnotu časového limitu pro webový prvek.
Ačkoli Pagefactory neposkytuje explicitní funkci čekání, existuje však varianta implicitního čekání pomocí třídy AjaxElementLocatorFactory . Tuto třídu lze použít začleněnou, když aplikace používá komponenty a prvky Ajaxu.
Zde je způsob, jakým to implementujete do kódu. V rámci konstruktoru, když použijeme metodu initElements (), můžeme použít AjaxElementLocatorFactory k poskytnutí implicitního čekání na prvky.
PageFactory.initElements(driver, this); can be replaced with PageFactory.initElements( new AjaxElementLocatorFactory(driver, 20), this);
Výše uvedený druhý řádek kódu znamená, že ovladač nastaví časový limit 20 sekund pro všechny prvky na stránce, když je každý z jeho načtení a pokud některý z prvků není nalezen po 20 sekundách, je vyvolána výjimka „NoSuchElementException“ pro ten chybějící prvek.
Čekání můžete také definovat níže:
public pageFactoryClass(WebDriver driver) { ElementLocatorFactory locateMe = new AjaxElementLocatorFactory(driver, 30); PageFactory.initElements(locateMe, this); this.driver = driver; }
Výše uvedený kód funguje perfektně, protože třída AjaxElementLocatorFactory implementuje rozhraní ElementLocatorFactory.
Zde nadřazené rozhraní (ElementLocatorFactory) odkazuje na objekt podřízené třídy (AjaxElementLocatorFactory). Proto se při přiřazování časového limitu pomocí AjaxElementLocatorFactory používá koncept Java „upcasting“ nebo „runtime polymorphism“.
S ohledem na to, jak to funguje technicky, AjaxElementLocatorFactory nejprve vytvoří AjaxElementLocator pomocí SlowLoadableComponent, který nemusí dokončit načítání, když se vrátí load (). Po volání metody load () by metoda isLoaded () měla nadále selhat, dokud se komponenta plně nenačte.
Jinými slovy, všechny prvky budou čerstvě vyhledány pokaždé, když je k prvku v kódu přistupováno vyvoláním volání locator.findElement () ze třídy AjaxElementLocator, která poté použije časový limit do načtení prostřednictvím třídy SlowLoadableComponent.
Navíc po přiřazení časového limitu prostřednictvím AjaxElementLocatorFactory již nebudou prvky s anotací @CacheLookUp ukládány do mezipaměti, protože anotace bude ignorována.
Existuje také variace na to, jak můžeš zavolej initElements () metoda a jak neměl by zavolej AjaxElementLocatorFactory přiřadit časový limit prvku.
# 1) Můžete také zadat název prvku namísto objektu ovladače, jak je uvedeno níže v metodě initElements ():
PageFactory.initElements( , this);
Metoda initElements () ve výše uvedené variantě interně vyvolá volání třídy DefaultElementFactory a konstruktor DefaultElementFactory přijímá objekt rozhraní SearchContext jako vstupní parametr. Objekt webového ovladače a webový prvek patří do rozhraní SearchContext.
V tomto případě bude metoda initElements () předem inicializována pouze pro uvedený prvek a nebudou inicializovány všechny prvky na webové stránce.
#dva) Zde je však zajímavý obrat k této skutečnosti, který uvádí, jak byste neměli konkrétním způsobem volat objekt AjaxElementLocatorFactory. Mám-li použít výše uvedenou variantu initElements () spolu s AjaxElementLocatorFactory, pak se nezdaří.
Příklad: Níže uvedený kód, tj. Předání názvu prvku namísto objektu ovladače do definice AjaxElementLocatorFactory, nebude fungovat, protože konstruktor pro třídu AjaxElementLocatorFactory vezme jako vstupní parametr pouze objekt webového ovladače, a proto by objekt SearchContext s webovým prvkem pro něj nefungoval.
PageFactory.initElements(new AjaxElementLocatorFactory(, 10), this);
Otázka č. 8) Je použití pagefactory proveditelnou možností oproti běžnému vzorovému designu objektu stránky?
Odpovědět: Toto je nejdůležitější otázka, kterou lidé mají, a proto jsem si myslel, že se jí budu věnovat na konci tutoriálu. Nyní známe „vstup a výstup“ o Pagefactory, počínaje jejími koncepty, použitými anotacemi, dalšími podporovanými funkcemi, implementací pomocí kódu, klady a zápory.
Přesto zůstáváme u této zásadní otázky, že pokud má pagefactory tolik dobrých věcí, proč bychom se neměli držet jeho používání.
Pagefactory přichází s konceptem CacheLookUp, který jsme viděli, není proveditelný pro dynamické prvky, jako jsou často aktualizované hodnoty prvku. Takže, pagefactory bez CacheLookUp, je to dobrá volba? Ano, pokud jsou xpaths statické.
Pádem však je, že aplikace moderní doby je naplněna těžkými dynamickými prvky, kde víme, že design objektu stránky bez pagefactory funguje nakonec dobře, ale funguje koncept pagefactory stejně dobře s dynamickými xpaths? Možná ne. Zde je rychlý příklad:
Na webové stránce nseindia.com vidíme níže uvedenou tabulku.
Cesta x tabulky je
'//*(@id='tab9Content')/table/tbody/tr(+count+)/td(1)'
Chceme načíst hodnoty z každého řádku pro první sloupec „Koupit množství“. K tomu budeme muset zvýšit počítadlo řádků, ale index sloupce zůstane 1. Neexistuje způsob, jak bychom mohli předat tento dynamický XPath v anotaci @FindBy, protože anotace přijímá hodnoty, které jsou statické a nelze předat žádnou proměnnou to.
Tady je místo, kde pagefactory úplně selže, zatímco obvyklý POM s ním skvěle funguje. Můžete snadno použít smyčku for ke zvýšení indexu řádků pomocí takových dynamických xpaths v metodě driver.findElement ().
Závěr
Page Object Model je návrhový koncept nebo vzor používaný v rámci automatizace selenu.
Konvekční pojmenování metod je uživatelsky přívětivé v Page Object Model. Kód v POM je snadno srozumitelný, opakovaně použitelný a udržovatelný. Pokud v POM dojde k nějaké změně ve webovém prvku, stačí provést změny v příslušné třídě, nikoli upravovat všechny třídy.
Pagefactory, stejně jako obvyklý POM, je skvělý koncept. Musíme však vědět, kde je obvyklý POM proveditelný a kde Pagefactory dobře vyhovuje. Ve statických aplikacích (kde jsou XPath i elementy statické) lze Pagefactory liberálně implementovat s dalšími výhodami lepšího výkonu.
Alternativně, když aplikace zahrnuje dynamické i statické prvky, můžete mít smíšenou implementaci pom s Pagefactory a bez Pagefactory podle proveditelnosti pro každý webový prvek.
Autor: Tento tutoriál napsal Shobha D. Pracuje jako vedoucí projektu a má 9 a více let zkušeností s manuálními, automatizačními (Selenium, IBM Rational Functional Tester, Java) a API Testing (SOAPUI a Rest assured in Java) .
Nyní k vám, k další implementaci Pagefactory.
Happy Exploring !!!
=> Navštivte zde a dozvíte se selen od začátku.
Doporučené čtení
- 30+ nejlepších návodů na selen: Naučte se selen se skutečnými příklady
- Efektivní scénáře selenu a řešení potíží - Scénář selenu č. 27
- Ladění selenových skriptů pomocí protokolů (výuka Log4j) - výuka selenu č. 26
- Úvod do rámce JUnit a jeho použití v selenovém skriptu - výuka selenu č. 11
- 7 faktorů ovlivňujících odhad testu projektu automatizace selenu - výuka selenu č. 32
- Tvrzení v selenu pomocí rámců Junit a TestNG
- Jak používat rámec TestNG pro vytváření skriptů selenu - výukový program TestNG selenu č. 12
- Naučte se používat poznámky TestNG v selenu (s příklady)