page object model with page factory selenium tutorial
Цей поглиблений посібник пояснює все про об’єктну модель сторінки (POM) із використанням прикладів Pagefactory. Ви також можете навчитися впровадженню POM у селені:
У цьому посібнику ми розберемося, як створити об'єктну модель сторінки за допомогою підходу Page Factory. Ми зосередимося на:
- Заводський клас
- Як створити базовий POM за допомогою шаблону Page Factory
- Різні анотації, що використовуються у підході до фабричних сторінок
Перш ніж ми побачимо, що таке Pagefactory і як його можна використовувати разом з об'єктною моделлю Page, давайте зрозуміємо, що таке Page Object Model, яка широко відома як POM.
=> Завітайте сюди, щоб побачити серію навчальних селенів для всіх.
Що ви дізнаєтесь:
- Що таке об'єктна модель сторінки (POM)?
- Що таке Pagefactory?
- POM за допомогою Page Factory
- Часті запитання
- Висновок
Що таке об'єктна модель сторінки (POM)?
Теоретичні термінології описують Модель об'єкта сторінки як шаблон дизайну, що використовується для побудови сховища об’єктів для веб-елементів, доступних у тестованому додатку. Мало хто називає це структурою автоматизації селену для даного тестованого додатка.
Однак те, що я зрозумів щодо терміна Page Object Model, це:
# 1) Це шаблон дизайну, де у вас є окремий файл класу Java, що відповідає кожному екрану або сторінці програми. Файл класу може містити сховище об'єктів елементів інтерфейсу, а також методи.
# два) Якщо на сторінці є величезні веб-елементи, клас сховища об’єктів для сторінки може бути відокремлений від класу, що включає методи для відповідної сторінки.
Приклад: Якщо сторінка «Зареєструвати обліковий запис» має багато полів введення, тоді міг бути клас RegisterAccountObjects.java, який формує сховище об’єктів для елементів інтерфейсу на сторінці облікових записів реєстру.
Можна створити окремий файл класу RegisterAccount.java, що розширює або успадковує RegisterAccountObjects, що включає всі методи, що виконують різні дії на сторінці.
# 3) Крім того, під пакетом може бути загальний пакет із файлом {roperties, тестовими даними Excel та загальними методами.
Приклад: DriverFactory, який можна було дуже легко використовувати на всіх сторінках програми
Розуміння POM на прикладі
Перевірте тут щоб дізнатись більше про POM.
Нижче наведено знімок веб-сторінки:

Натискання кожного з цих посилань призведе до перенаправлення користувача на нову сторінку.
Ось короткий знімок того, як будується структура проекту з Selenium за допомогою об’єктної моделі Page, що відповідає кожній сторінці веб-сайту. Кожен клас Java включає сховище об'єктів та методи виконання різних дій на сторінці.
Крім того, буде інший файл JUNIT або TestNG або файл класу Java, що викликає виклики до файлів класів цих сторінок.

Чому ми використовуємо об'єктну модель сторінки?
Існує суєта про використання цього потужного фреймворку Selenium, який називається POM або об'єктна модель сторінки. Тепер виникає запитання: «Навіщо використовувати POM?».
Проста відповідь на це полягає в тому, що POM - це комбінація керованих даними, модульних та гібридних каркасів. Це підхід до систематичної організації сценаріїв таким чином, що полегшує службу контролю якості підтримувати код без зайвих клопотів, а також допомагає запобігти надмірному чи дублюванню коду.
Наприклад, якщо на певній сторінці змінюється значення локатора, то дуже легко визначити та зробити цю швидку зміну лише у сценарії відповідної сторінки, не впливаючи на код в іншому місці.
Ми використовуємо концепцію об'єктної моделі сторінок у Selenium Webdriver з таких причин:
- У цій моделі POM створено сховище об'єктів. Він не залежить від тестових випадків і може бути використаний повторно для іншого проекту.
- Конвенція імен методів дуже проста, зрозуміла і більш реалістична.
- В рамках об’єктної моделі Page ми створюємо класи сторінок, які можна використовувати повторно в іншому проекті.
- Об'єктна модель Page легка для розробленого фреймворку завдяки ряду переваг.
- У цій моделі створюються окремі класи для різних сторінок веб-програми, таких як сторінка входу, домашня сторінка, сторінка відомостей про співробітника, сторінка зміни пароля тощо.
- Якщо в будь-якому елементі веб-сайту є якісь зміни, тоді нам потрібно внести зміни лише в одному класі, а не у всіх класах.
- Сценарій, розроблений, є більш багаторазовим, читабельним та ремонтопридатним у підході до об'єктної моделі сторінки.
- Структура його проекту досить проста і зрозуміла.
- Може використовувати PageFactory в об’єктній моделі сторінки для того, щоб ініціалізувати веб-елемент і зберігати елементи в кеші.
- TestNG також може бути інтегрований у підхід до об'єктної моделі сторінки.
Впровадження простого POM в селені
# 1) Сценарій для автоматизації
Тепер ми автоматизуємо даний сценарій, використовуючи Page Object Model.
Сценарій пояснюється нижче:
Крок 1: Запустіть сайт “https: //demo.vtiger.com”.
Крок 2: Введіть дійсний обліковий запис.
Крок 3: Увійдіть на сайт.
Крок 4: Перевірте домашню сторінку.
Крок 5: Вийти з сайту.
Крок 6: Закрийте браузер.
# 2) Селенові сценарії для вищевказаного сценарію в POM
Тепер ми створюємо структуру POM в Eclipse, як пояснено нижче:
Крок 1: Створіть проект в Eclipse - Структура на основі POM:
а) Створити проект “Модель об’єкта сторінки”.

б) Створити 3 пакети за проектом.
- бібліотека
- сторінки
- тестові кейси
Бібліотека: Під це ми ставимо ті коди, які потрібно викликати знову і знову в наших тестових випадках, таких як запуск браузера, знімки екрана тощо. Користувач може додавати більше класів під нього на основі потреби проекту.
Сторінки: Відповідно до цього, класи створюються для кожної сторінки у веб-програмі і можуть додавати більше класів сторінок на основі кількості сторінок у програмі.
Тестові кейси: Під цим ми пишемо тестовий кейс для входу та можемо додати більше тестових кейсів, якщо це потрібно для перевірки всієї програми.

в) Класи під пакетами показані на зображенні нижче.

Крок два: Створіть наступні класи під пакетом бібліотеки.
Browser.java: У цьому класі визначено 3 браузери (Firefox, Chrome та Internet Explorer), які викликаються в тестовому випадку для входу. Виходячи з вимоги, користувач може протестувати додаток і в різних браузерах.
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: У цьому класі написана програма скріншоту, яка викликається в тестовому випадку, коли користувач хоче зробити знімок екрана про те, чи тест не пройшов або пройшов.
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(); } } }Крок 3: Створіть класи сторінок в пакеті Page.
HomePage.java: Це клас домашньої сторінки, в якому визначено всі елементи домашньої сторінки та методи.
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: Це клас сторінки входу, в якому визначено всі елементи сторінки входу та методи.
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(); } }Крок 4: Створіть тестові кейси для сценарію входу.
LoginTestCase.java: Це клас LoginTestCase, де виконується тест. Користувач також може створити більше тестових кейсів відповідно до потреб проекту.
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(); } }Крок 5: Виконайте “LoginTestCase.java“.
Крок 6: Вихід об'єктної моделі сторінки:
- Запустіть браузер Chrome.
- Демонстраційний веб-сайт відкрито у браузері.
- Увійдіть на демонстраційний сайт.
- Перевірте домашню сторінку.
- Вийти з сайту.
- Закрийте браузер.
Тепер давайте розберемо основну концепцію цього підручника, яка привертає увагу, тобто “Pagefactory”.
Що таке Pagefactory?
PageFactory - це спосіб реалізації “об’єктної моделі сторінки”. Тут ми дотримуємося принципу розділення сховища об’єктів сторінки та методів тестування. Це вбудована концепція об'єктної моделі сторінок, яка дуже оптимізована.
Давайте тепер матимемо більше ясності щодо терміна Pagefactory.
# 1) По-перше, концепція, що називається Pagefactory, забезпечує альтернативний спосіб з точки зору синтаксису та семантики для створення сховища об'єктів для веб-елементів на сторінці.
# два) По-друге, він використовує дещо іншу стратегію для ініціалізації веб-елементів.
# 3) Репозиторій об'єктів для веб-елементів інтерфейсу користувача може бути побудований за допомогою:
- Звичайний «POM без Pagefactory» і,
- Крім того, ви можете використовувати «POM з Pagefactory».
Нижче наведено зображення того самого:

Зараз ми розглянемо всі аспекти, які відрізняють звичайний POM від POM від Pagefactory.
а) Різниця в синтаксисі пошуку елемента за допомогою звичайного POM проти POM з Pagefactory.
Наприклад , Натисніть тут щоб знайти поле пошуку, яке відображається на сторінці.

POM без Pagefactory:
# 1) Нижче наведено спосіб пошуку поля пошуку за допомогою звичайного POM:
WebElement searchNSETxt=driver.findElement(By.id(“searchBox”));# 2) Наведений нижче крок передає значення “інвестиція” у поле Search NSE.
searchNSETxt.sendkeys(“investment”);POM Використання Pagefactory:
# 1) Ви можете знайти поле пошуку за допомогою Pagefactory, як показано нижче.
Анотація @FindBy використовується в Pagefactory для ідентифікації елемента, тоді як POM без Pagefactory використовує driver.findElement () метод пошуку елемента.
Друге твердження для Pagefactory після @FindBy присвоює тип WebElement клас, який працює точно так само, як присвоєння імені елементу типу WebElement класу як тип повернення методу driver.findElement () що використовується в звичайному POM (пошукNSETxt у цьому прикладі).
Ми розглянемо @FindBy докладніші анотації у наступній частині цього посібника.
@FindBy(id = 'searchBox') WebElement searchNSETxt;# два) Наведений нижче крок передає значення «інвестиція» у поле Search NSE, і синтаксис залишається таким же, як у звичайного POM (POM без Pagefactory).
searchNSETxt.sendkeys(“investment”);б) Різниця в стратегії ініціалізації веб-елементів із використанням звичайного POM проти POM з Pagefactory.
Використання POM без Pagefactory:
Нижче наведено фрагмент коду для встановлення шляху драйвера Chrome. Екземпляр WebDriver створюється з іменем драйвера, а ChromeDriver призначається „драйверу”. Потім той самий об’єкт драйвера використовується для запуску веб-сайту Національної фондової біржі, пошуку searchBox та введення значення рядка в поле.
Суть, яку я хотів би виділити тут, полягає в тому, що коли це POM без фабричної сторінки, екземпляр драйвера створюється спочатку, і кожен веб-елемент щоразу ініціюється, коли відбувається виклик цього веб-елемента за допомогою driver.findElement () або драйвера .findElements ().
Ось чому на новому кроці driver.findElement () для елемента структура DOM знову сканується і на цій сторінці робиться оновлена ідентифікація елемента.
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”);Використання POM з Pagefactory:
Окрім використання анотації @FindBy замість методу driver.findElement (), наведений нижче фрагмент коду додатково використовується для Pagefactory. Статичний метод initElements () класу PageFactory використовується для ініціалізації всіх елементів інтерфейсу на сторінці, як тільки сторінка завантажується.
public PagefactoryClass(WebDriver driver) { this.driver = driver; PageFactory.initElements(driver, this); } Вищевказана стратегія робить підхід PageFactory дещо відмінним від звичайного POM. У звичайному POM веб-елемент повинен бути явно ініціалізований, тоді як у підході Pagefactory всі елементи ініціалізуються за допомогою initElements () без явної ініціалізації кожного веб-елемента.
Наприклад: Якщо WebElement був оголошений, але не ініціалізований у звичайному POM, тоді виникає помилка 'ініціалізувати змінну' або NullPointerException. Отже, у звичайному POM кожен WebElement повинен бути явно ініціалізований. PageFactory має перевагу над звичайним POM у цьому випадку.
Не давайте ініціалізувати веб-елемент BDate (POM без Pagefactory), ви можете бачити, що помилка «Ініціалізувати змінну» відображає і пропонує користувачеві ініціалізувати її до нуля, отже, ви не можете припустити, що елементи ініціалізуються неявно при їх знаходженні.

Елемент BDate явно ініціалізований (POM без Pagefactory):

Тепер давайте розглянемо кілька прикладів повної програми, що використовує PageFactory, щоб виключити будь-яку неоднозначність у розумінні аспекту реалізації.
Приклад 1:
- Перейдіть на сторінку „http://www.nseindia.com/“
- У спадному меню поруч із полем пошуку виберіть „Похідні валюти”.
- Шукайте 'USDINR'. Перевірте текст „Долар США-Індійська рупія - USDINR“ на отриманій сторінці.
Структура програми:
- Створюється PagefactoryClass.java, що включає сховище об'єктів із використанням концепції фабрики сторінок для nseindia.com, який є конструктором для ініціалізації всіх веб-елементів, метод selectCurrentDerivative () для вибору значення в поле випадаючого вікна пошуку, selectSymbol () для вибору символу на сторінка, яка відображається далі, і verifytext (), щоб перевірити, чи відповідає заголовок сторінки належним чином чи ні.
- NSE_MainClass.java - це файл основного класу, який викликає всі перераховані вище методи та виконує відповідні дії на сайті 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 Приклад 2:
- Перейдіть на сторінку https://www.shoppersstop.com/brands
- Перейдіть до посилання високого каррі.
- Переконайтеся, що сторінка високого каррі містить текст “Почати щось нове”.
Структура програми
- shopperstopPagefactory.java, що включає сховище об’єктів з використанням концепції pagefactory для shoppersstop.com, який є конструктором для ініціалізації всіх веб-елементів, створюється метод closeExtraPopup () для обробки спливаючого вікна попередження, clickOnHauteCurryLink (), щоб натиснути на Haute Curry Пов’яжіть і verifyStartNewSomething (), щоб перевірити, чи містить сторінка Haute Curry текст “Почати щось нове”.
- Shopperstop_CallPagefactory.java - це файл основного класу, який викликає всі вищезазначені методи та виконує відповідні дії на сайті 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 за допомогою Page Factory
Відео-підручники - POM with Page Factory
Частина І
Частина ІІ
Клас Factory використовується для спрощення та спрощення використання Page Objects.
- По-перше, нам потрібно знайти веб-елементи за допомогою анотацій @FindBy на класах сторінок .
- Потім ініціалізуйте елементи за допомогою initElements () під час створення екземпляра класу сторінки.
# 1) @FindBy:
Анотація @FindBy використовується у PageFactory для пошуку та оголошення веб-елементів за допомогою різних локаторів.Тут ми передаємо атрибут, а також його значення, яке використовується для пошуку веб-елемента, до анотації @FindBy, а потім оголошується WebElement.
Існує 2 способи використання анотації.
Наприклад:
@FindBy(how = How.ID, using='EmailAddress') WebElement Email; @FindBy(id='EmailAddress') WebElement Email;Однак перший - це стандартний спосіб декларування WebElements.
«Як» це клас, і він має статичні змінні, такі як ID, XPATH, CLASSNAME, LINKTEXT тощо.
«Використання» - Призначити значення статичній змінній.
У вищесказаному приклад , ми використали атрибут ‘id’, щоб знайти веб-елемент ‘Email’. Подібним чином ми можемо використовувати такі локатори з анотаціями @FindBy:
- className
- css
- ім'я
- xpath
- tagName
- linkText
- частковийLinkText
# 2) initElements ():
InitElements - це статичний метод класу PageFactory, який використовується для ініціалізації всіх веб-елементів, розташованих за допомогою анотації @FindBy. Таким чином, створення екземплярів класів Page легко.
initElements(WebDriver driver, java.lang.Class pageObjectClass) Ми також повинні розуміти, що POM дотримується принципів OOPS.
- WebElements оголошуються як змінні приватного члена (Приховування даних).
- Прив’язка WebElements до відповідних методів (інкапсуляція).
Кроки для створення POM за допомогою шаблону сторінки
# 1) Створіть окремий файл класу Java для кожної веб-сторінки.
# два) У кожному класі всі WebElements повинні бути оголошені як змінні (за допомогою анотації - @FindBy) та ініціалізовані методом initElement (). Задекларовані WebElements повинні бути ініціалізовані для використання в методах дії.
# 3) Визначте відповідні методи, що діють на ці змінні.
Візьмемо приклад простого сценарію:
- Відкрийте URL-адресу програми.
- Введіть адресу електронної пошти та пароль.
- Клацніть на кнопку Вхід.
- Перевірте успішне повідомлення для входу на сторінці пошуку.
Шар сторінки
Тут ми маємо 2 сторінки,
- Домашня сторінка - Сторінка, яка відкривається при введенні URL-адреси і куди ми вводимо дані для входу.
- SearchPage - Сторінка, яка відображається після успішного входу.
У Layer Page кожна сторінка у веб-програмі оголошується як окремий клас Java, і там згадуються її локатори та дії.
Кроки для створення POM на прикладі реального часу
# 1) Створіть клас Java для кожної сторінки:
У цьому приклад , ми отримаємо доступ до 2 веб-сторінок, “Домашня сторінка” та “Пошук”.
Отже, ми створимо 2 класи Java у Page Layer (або в пакеті, скажімо, com.automation.pages).
Package Name :com.automation.pages HomePage.java SearchPage.java # 2) Визначте WebElements як змінні за допомогою Annotation @FindBy:
Ми взаємодіяли б із:
- Електронна пошта, пароль, поле кнопки входу на домашній сторінці.
- Успішне повідомлення на сторінці пошуку.
Тож ми визначимо WebElements за допомогою @FindBy
Наприклад: Якщо ми збираємося ідентифікувати адресу електронної пошти за допомогою атрибута id, тоді її декларація змінної є
//Locator for EmailId field @FindBy(how=How.ID,using='EmailId') private WebElementEmailIdAddress; # 3) Створіть методи для дій, що виконуються на WebElements.
Нижче виконуються дії на WebElements:
- Введіть дію в полі Адреса електронної пошти.
- Введіть дію в поле Пароль.
- Натисніть дію на кнопці входу.
Наприклад, Користувацькі методи створюються для кожної дії в WebElement як,
public void typeEmailId(String Id){ driver.findElement(EmailAddress).sendKeys(Id) }Тут Id передається як параметр у методі, оскільки вхід буде надісланий користувачем з основного тесту.
Примітка :Конструктор повинен бути створений в кожному класі на рівні сторінки, щоб отримати екземпляр драйвера з основного класу в тестовому шарі, а також ініціалізувати WebElements (об'єкти сторінки), оголошені в класі сторінки, використовуючи PageFactory.InitElement () .
Ми не ініціюємо драйвер тут, швидше його екземпляр отримується від основного класу, коли створюється об'єкт класу Page Layer.
InitElement () - використовується для ініціалізації оголошених WebElements, використовуючи екземпляр драйвера з основного класу. Іншими словами, WebElements створюються за допомогою екземпляра драйвера. Тільки після ініціалізації WebElements їх можна використовувати в методах для виконання дій.
Для кожної сторінки створюються два класи Java, як показано нижче:
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. } } Тестовий шар
У цьому класі реалізовані тестові кейси. Ми створюємо окремий пакет, скажімо, com.automation.test, а потім створюємо тут клас Java (MainClass.java)
Кроки для створення тестових випадків:
- Ініціалізуйте драйвер і відкрийте програму.
- Створіть об'єкт класу PageLayer (для кожної веб-сторінки) і передайте екземпляр драйвера як параметр.
- Використовуючи створений об’єкт, зателефонуйте методам у класі PageLayer (для кожної веб-сторінки), щоб виконати дії / перевірку.
- Повторюйте крок 3, доки не будуть виконані всі дії, а потім закрийте драйвер.
//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(); } } Ієрархія типів анотацій, що використовується для оголошення WebElements
Анотації використовуються для побудови стратегії розташування елементів інтерфейсу.
# 1) @FindBy
Що стосується Pagefactory, @FindBy діє як чарівна паличка. Це додає всі сили концепції. Тепер ви знаєте, що анотація @FindBy у Pagefactory виконує те саме, що і анотація driver.findElement () у звичайній об'єктній моделі сторінки. Він використовується для пошуку WebElement / WebElements з одним критерієм .
# 2) @FindBys
Він використовується для пошуку WebElement за допомогою більше одного критерію і повинні відповідати всім наведеним критеріям. Ці критерії слід згадувати у стосунках батьків та дітей. Іншими словами, це використовує умовне відношення AND для пошуку WebElements, використовуючи вказані критерії. Він використовує кілька @FindBy для визначення кожного критерію.
Наприклад:
Вихідний код HTML WebElement:
У POM:
@FindBys({ @FindBy(id = 'searchId_1'), @FindBy(name = 'search_field') }) WebElementSearchButton;У наведеному вище прикладі WebElement ‘SearchButton’ знаходиться лише в тому випадку, якщо він є відповідає обом критерії, значення ідентифікатора яких - 'searchId_1', а значення імені - 'поле_пошуку'. Зверніть увагу, що перший критерій належить батьківському тегу, а другий критерій дочірньому тегу.
# 3) @FindAll
Він використовується для пошуку WebElement за допомогою більше одного критерію і він повинен відповідати принаймні одному із заданих критеріїв. Тут використовуються умовні зв’язки АБО для того, щоб знайти WebElements. Він використовує множинний @FindBy для визначення всіх критеріїв.
Наприклад:
HTML SourceCode:
У POM:
@FindBys({ @FindBy(id = 'UsernameNameField_1'), // doesn’t match @FindBy(name = 'User_Id') //matches @FindBy(className = “UserName_r”) //matches }) WebElementUserName;У наведеному вище прикладі WebElement ‘Ім'я користувача знаходиться, якщо воно є відповідає принаймні одному згаданих критеріїв.
# 4) @CacheLookUp
Коли WebElement частіше використовується в тестових випадках, Selenium шукає WebElement кожного разу, коли запускається тестовий скрипт. У тих випадках, коли певні WebElements глобально використовуються для всіх TC ( Наприклад, Сценарій входу відбувається для кожного TC), ця анотація може використовуватися для підтримки цих WebElements в кеш-пам'яті після її першого прочитання.
Це, в свою чергу, допомагає коду виконуватися швидше, оскільки кожен раз, коли йому не потрібно шукати WebElement на сторінці, швидше він може отримати посилання з пам'яті.
Це може бути префіксом до будь-якого з @FindBy, @FindBys та @FindAll.
Наприклад:
@CacheLookUp @FindBys({ @FindBy(id = 'UsernameNameField_1'), @FindBy(name = 'User_Id') @FindBy(className = “UserName_r”) }) WebElementUserName;Також зауважте, що цю анотацію слід використовувати лише для WebElements, значення атрибута (як xpath, ім'я ідентифікатора, назва класу тощо) не змінюється досить часто. Щойно WebElement знаходиться вперше, він зберігає посилання в кеш-пам’яті.
Отже, через кілька днів відбувається зміна атрибута WebElement, Selenium не зможе знайти елемент, оскільки він уже має старе посилання в кеш-пам’яті і не враховуватиме нещодавню зміну WebElement.
Докладніше на PageFactory.initElements ()
Тепер, коли ми розуміємо стратегію Pagefactory щодо ініціалізації веб-елементів за допомогою InitElements (), спробуємо зрозуміти різні версії методу.
Метод, як ми знаємо, бере в якості вхідних параметрів об’єкт драйвера та об’єкт поточного класу і повертає об’єкт сторінки шляхом неявної та активної ініціалізації всіх елементів на сторінці.
На практиці використання конструктора, як показано у наведеному вище розділі, є кращим за інші способи його використання.
Альтернативні способи виклику методу:
# 1) Замість використання вказівника “this” ви можете створити поточний об’єкт класу, передати йому екземпляр драйвера та викликати статичний метод initElements з параметрами, тобто об’єкт драйвера та об’єкт класу, який щойно створений.
public PagefactoryClass(WebDriver driver) { //version 2 PagefactoryClass page=new PagefactoryClass(driver); PageFactory.initElements(driver, page); } # два) Третій спосіб ініціалізації елементів за допомогою класу Pagefactory - це використання api, що називається «відображенням». Так, замість створення об’єкта класу з ключовим словом “new”, classname.class може бути переданий як частина вхідного параметра initElements ().
public PagefactoryClass(WebDriver driver) { //version 3 PagefactoryClass page=PageFactory.initElements(driver, PagefactoryClass.class); } Часті запитання
Q # 1) Які різні стратегії локатора використовуються для @FindBy?
Відповідь: Проста відповідь на це - немає різних стратегій локатора, які використовуються для @FindBy.
Вони використовують ті самі 8 стратегій локатора, що і метод findElement () у звичайному POM:
- ідентифікатор
- ім'я
- className
- xpath
- css
- tagName
- linkText
- частковийLinkText
Q # 2) Чи існують різні версії для використання анотацій @FindBy?
Відповідь: Коли є веб-елемент для пошуку, ми використовуємо анотацію @FindBy. Ми детально розглянемо альтернативні способи використання @FindBy, а також різні стратегії локатора.
Ми вже бачили, як використовувати версію 1 @FindBy:
@FindBy(id = 'cidkeyword') WebElement Symbol;Версія 2 @FindBy - це передача вхідного параметра як Як і Використовуючи .
Як шукає стратегію локатора, за допомогою якої буде ідентифікований веб-елемент. Ключове слово використання визначає значення локатора.
Див. Нижче для кращого розуміння,
- How.ID здійснює пошук елемента за допомогою ідентифікатор стратегія і елемент, який він намагається ідентифікувати, має id = cidkeyword.
@FindBy(how = How.ID, using = ' cidkeyword') WebElement Symbol; - How.CLASS_NAME здійснює пошук елемента за допомогою className стратегія та елемент, який він намагається ідентифікувати, має class = новийклас.
@FindBy(how = How.CLASS_NAME, using = 'newclass') WebElement Symbol; Запитання №3) Чи існує різниця між двома версіями @FindBy?
Відповідь: Відповідь: Ні, між цими двома версіями немає різниці. Просто перша версія коротша і легша порівняно з другою версією.
Q # 4) Що я використовую у pagefactory, якщо є список веб-елементів, які потрібно розмістити?
Відповідь: У звичайному шаблоні дизайну об’єкта сторінки у нас є driver.findElements () для визначення місця розташування декількох елементів, що належать до одного і того ж класу або імені тегу, але як нам знайти такі елементи у випадку об’єктної моделі сторінки з Pagefactory? Найпростіший спосіб досягти таких елементів - використовувати ту саму анотацію @FindBy.
Я розумію, що цей рядок, здається, є для багатьох з вас подряпиною. Але так, це відповідь на запитання.
Давайте розглянемо наведений нижче приклад:
Використовуючи звичайну об'єктну модель сторінки без Pagefactory, ви використовуєте driver.findElements для пошуку кількох елементів, як показано нижче:
private List multipleelements_driver_findelements = driver.findElements (By.class(“last”));Те саме можна досягти за допомогою об'єктної моделі сторінки з Pagefactory, як зазначено нижче:
@FindBy (how = How.CLASS_NAME, using = 'last') private List multipleelements_FindBy;В основному, присвоєння елементів списку типу WebElement робить фокус незалежно від того, використовується Pagefactory чи ні під час ідентифікації та розміщення елементів.
Q # 5) Чи можна як дизайн об'єкта Page без pagefactory, так і Pagefactory використовувати в одній програмі?
Відповідь: Так, як дизайн об'єкта сторінки без Pagefactory, так і з Pagefactory можна використовувати в одній програмі. Ви можете пройти програму, наведену нижче в Відповідь на питання No6 щоб побачити, як обидва використовуються в програмі.
Необхідно пам’ятати, що слід уникати концепції Pagefactory з кешованою функцією для динамічних елементів, тоді як дизайн об’єкта сторінки добре працює для динамічних елементів. Однак Pagefactory підходить лише для статичних елементів.
Q # 6) Чи існують альтернативні способи ідентифікації елементів на основі кількох критеріїв?
як видалити елементи з масиву
Відповідь: Альтернативою для ідентифікації елементів на основі кількох критеріїв є використання анотацій @FindAll та @FindBys. Ці анотації допомагають ідентифікувати окремі або кілька елементів залежно від значень, отриманих із переданих у ньому критеріїв.
# 1) @FindAll:
@FindAll може містити кілька @FindBy і повертатиме всі елементи, які відповідають будь-якому @FindBy в одному списку. @FindAll використовується для позначення поля на об'єкті сторінки, щоб вказати, що для пошуку слід використовувати ряд тегів @FindBy. Потім буде здійснено пошук усіх елементів, які відповідають будь-якому з критеріїв FindBy.
Зверніть увагу, що елементи не гарантовано розташовані в порядку документу.
Синтаксис для використання @FindAll наведений нижче:
@FindAll( { @FindBy(how = How.ID, using = 'foo'), @FindBy(className = 'bar') } ) Пояснення: @FindAll здійснить пошук та ідентифікацію окремих елементів, що відповідають кожному з критеріїв @FindBy, та їх перелік. У наведеному вище прикладі він спочатку здійснить пошук елемента, id = ”foo”, а потім ідентифікує другий елемент з className = ”bar”.
Припускаючи, що для кожного критерію FindBy був ідентифікований один елемент, @FindAll призведе до переліку 2 елементів відповідно. Пам’ятайте, для кожного критерію може бути визначено кілька елементів. Таким чином, простими словами, @ FindAll діє еквівалентно АБО оператора за пройденими критеріями @FindBy.
# 2) @FindBys:
FindBys використовується для позначення поля на об'єкті сторінки, щоб вказати, що для пошуку слід використовувати ряд тегів @FindBy в ланцюжку, як описано в ByChained. Коли необхідні об'єкти WebElement повинні відповідати всім заданим критеріям, використовуйте анотацію @FindBys.
Синтаксис для використання @FindBys такий:
@FindBys( { @FindBy(name=”foo”) @FindBy(className = 'bar') } ) Пояснення: @FindBys здійснить пошук та ідентифікацію елементів, що відповідають усім критеріям @FindBy, та їх перелік. У наведеному вище прикладі він буде шукати елементи, чиє ім’я = ”foo” та className = ”bar”.
Результат @FindAll призведе до перерахування 1 елемента, якщо ми припустимо, що в заданих критеріях був один елемент, ідентифікований з іменем та className.
Якщо немає жодного елемента, що задовольняє всім пройденим умовам FindBy, то результатом @FindBys буде нуль елементів. Може бути визначений список веб-елементів, якщо всі умови задовольняють декілька елементів. Простими словами, @ FindBys діє еквівалентно І оператора за пройденими критеріями @FindBy.
Давайте побачимо реалізацію всіх вищезазначених анотацій через детальну програму:
Ми змінимо програму www.nseindia.com, наведену в попередньому розділі, щоб зрозуміти реалізацію анотацій @FindBy, @FindBys та @FindAll
# 1) Сховище об’єктів PagefactoryClass оновлюється, як показано нижче:
Список newlist = driver.findElements (By.tagName (“a”));
@FindBy (як = Як. TAG_NAME , використовуючи = 'a')
приватний Список findbyvalue;
@FindAll ({ @FindBy (className = “sel”), @FindBy (xpath = ”// a (@ id =’ tab5 ′) ”)}))
приватний Список findallvalue;
@FindBys ({ @FindBy (className = “sel”), @FindBy (xpath = ”// a (@ id =’ tab5 ′) ”)}))
приватний Список findbysvalue;
# 2) Новий метод seeHowFindWorks () записаний у PagefactoryClass і викликається як останній метод у головному класі.
Спосіб наведений нижче:
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 Нижче наведено результат, показаний у вікні консолі після виконання програми:

Спробуємо тепер розібратися в коді докладно:
# 1) За допомогою шаблону дизайну об’єкта сторінки елемент «newlist» ідентифікує всі теги з якорем «a». Іншими словами, ми отримуємо підрахунок усіх посилань на сторінці.
Ми дізналися, що pagefactory @FindBy виконує ту ж роботу, що і драйвер.findElement (). Елемент findbyvalue створений для отримання підрахунку всіх посилань на сторінці за допомогою стратегії пошуку, що має концепцію pagefactory.
Це доводить правильним, що і driver.findElement (), і @FindBy виконують однакову роботу та ідентифікують однакові елементи. Якщо ви подивитеся на скріншот вікна результуючої консолі вище, кількість посилань, ідентифікованих за допомогою елемента newlist та findbyvalue, дорівнює, тобто 299 посилання, знайдені на сторінці.
Результат показаний нижче:
driver.findElements(By.tagName()) 299 count of @FindBy- list elements 299 # два) Тут ми детально розглянемо роботу анотації @FindAll, яка стосуватиметься списку веб-елементів з іменем findallvalue.
Уважно розглядаючи кожен критерій @FindBy в анотації @FindAll, перший критерій @FindBy шукає елементи з className = 'sel', а другий критерій @FindBy шукає певний елемент із XPath = “// a (@ id = 'tab5')
Давайте тепер натиснути F12, щоб перевірити елементи на сторінці nseindia.com та отримати певні чіткості щодо елементів, що відповідають критеріям @FindBy.
На сторінці є два елементи, що відповідають className = ”sel”:
до) Елемент 'Основи' має тег списку, тобто
з className = ”sel”. Дивіться Знімок нижче

б) Інший елемент “Книга замовлень” має XPath з прив’язним тегом, який має назву класу як “sel”.

в) Другий @FindBy з XPath має прив'язувальний тег, який ідентифікатор є ' tab5 '. У відповідь на пошук є лише один елемент, який є Основами.
Дивіться знімок нижче:

Коли був виконаний тест nseindia.com, ми отримали кількість елементів, за якими шукали.
@FindAll as 3. Елементами для findallvalue при відображенні були: Основи як 0гоіндексний елемент, Книга замовлень як 1вуліндексний елемент та Основи знову як 2йіндексний елемент. Ми вже дізналися, що @FindAll ідентифікує елементи для кожного критерію @FindBy окремо.
Згідно з тим самим протоколом, для пошуку за першим критерієм, тобто className = ”sel”, він ідентифікував два елементи, що відповідають умові, та отримав „Основи” та „Книгу замовлень”.
Потім він перемістився до наступного критерію @FindBy і за xpath, заданим для другого @FindBy, він міг отримати елемент «Основи». Ось чому він нарешті визначив 3 елементи відповідно.
Таким чином, він не отримує елементів, що задовольняють жодним з умов @FindBy, але він працює окремо з кожним з @FindBy та ідентифікує елементи так само. Крім того, у поточному прикладі ми також побачили, що він не спостерігає, якщо елементи унікальні ( Наприклад Елемент 'Основи' в цьому випадку, який відображається двічі як частина результату двох критеріїв @FindBy)
# 3) Тут ми детально розглянемо роботу анотації @FindBys, яка стосуватиметься списку веб-елементів з ім'ям findbysvalue. Тут також перший критерій @FindBy шукає елементи з className = ’sel’, а другий критерій @FindBy шукає певний елемент із xpath = “// a (@ id =” tab5 ”).
Тепер, коли ми знаємо, елементами, визначеними для першої умови @FindBy, є 'Основи' та 'Книга замовлень', а для другого критерію @FindBy - 'Основи'.
Отже, як результат @FindBys буде відрізнятися від @FindAll? У попередньому розділі ми дізналися, що @FindBys еквівалентний умовному оператору І, отже, він шукає елемент або список елементів, що задовольняє всім умовам @FindBy.
Відповідно до нашого поточного прикладу, значення 'Основи' є єдиним елементом, який має class = 'sel' та id = 'tab5', що задовольняє обом умовам. Ось чому розмір @FindBys у тестовому корпусі дорівнює 1, і значення відображається як 'Основи'.
Кешування елементів у Pagefactory
Щоразу, коли сторінка завантажується, всі елементи на сторінці знову шукаються, викликаючи виклик через @FindBy або driver.findElement (), і відбувається новий пошук елементів на сторінці.
Більшу частину часу, коли елементи динамічні або постійно змінюються під час виконання, особливо якщо це елементи AJAX, безумовно, має сенс, що з кожним завантаженням сторінки відбувається новий пошук усіх елементів на сторінці.
Коли веб-сторінка містить статичні елементи, кешування елемента може допомогти різними способами. Коли елементи кешуються, йому не потрібно знаходити елементи знову при завантаженні сторінки, натомість він може посилатися на сховище кешованих елементів. Це економить багато часу та підвищує продуктивність.
Pagefactory забезпечує цю функцію кешування елементів за допомогою анотації @CacheLookUp .
Анотація повідомляє водієві використовувати той самий екземпляр локатора з DOM для елементів і не шукати їх знову, тоді як метод initElements pagefactory помітно сприяє збереженню кешованого статичного елемента. InitElements виконують роботу кешування елементів.
Це робить концепцію pagefactory особливою у порівнянні зі звичайним шаблоном дизайну об'єкта сторінки. Він має свої плюси і мінуси, про які ми поговоримо трохи пізніше. Наприклад, кнопка входу на домашній сторінці Facebook - це статичний елемент, який можна кешувати та є ідеальним елементом для кешування.
Давайте зараз розглянемо, як реалізувати анотацію @CacheLookUp
Спочатку потрібно імпортувати пакет для Cachelookup, як показано нижче:
import org.openqa.selenium.support.CacheLookupНижче наведено фрагмент, що відображає визначення елемента за допомогою @CacheLookUp. Як тільки UniqueElement здійснюється перший пошук, initElement () зберігає кешовану версію елемента, щоб наступного разу драйвер не шукав елемент, замість цього він посилається на той самий кеш і виконує дію з елементом праворуч далеко.
@FindBy(id = 'unique') @CacheLookup private WebElement UniqueElement; Давайте тепер подивимося через фактичну програму того, як дії над кешованим веб-елементом швидше, ніж над некешованим веб-елементом:
Покращуючи програму nseindia.com, я написав ще один новий метод monitorPerformance (), в якому я створюю кешований елемент для вікна пошуку та некешований елемент для того самого вікна пошуку.
Потім я намагаюся отримати тег елемента 3000 разів як для кешованого, так і для некешованого елемента, і намагаюся визначити час, необхідний для виконання завдання як кешованим, так і некешованим елементом.
Я розглядав 3000 разів, щоб ми могли побачити видиму різницю в термінах для двох. Я очікую, що кешований елемент повинен завершити отримання тегу в 3000 разів за менший час порівняно з некешованим елементом.
Тепер ми знаємо, чому кешований елемент повинен працювати швидше, тобто драйвер отримує вказівку не шукати елемент після першого пошуку, а безпосередньо продовжувати працювати над ним, і це не стосується некешованого елемента, для якого виконується пошук елемента для всі 3000 разів, а потім на ньому виконується дія.
Нижче наведено код для методу 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'); } Після виконання ми побачимо наступний результат у вікні консолі:
Відповідно до результату, завдання на некешованому елементі виконано в 82 секунд, поки час, необхідний для виконання завдання на кешованому елементі, був лише 37 секунд. Це справді видима різниця у часі відгуку як кешованого, так і некешованого елемента.

Q # 7) Які плюси та мінуси анотації @CacheLookUp у концепції Pagefactory?
Відповідь:
Плюси @CacheLookUp та ситуації, можливі для його використання:
@CacheLookUp є можливим, коли елементи статичні або взагалі не змінюються під час завантаження сторінки. Такі елементи не змінюють час роботи. У таких випадках доцільно використовувати анотацію для поліпшення загальної швидкості виконання тесту.
Мінуси анотації @CacheLookUp:
Найбільшим недоліком кешування елементів з анотацією є страх часто отримувати StaleElementReferenceExceptions.
Динамічні елементи досить часто оновлюються з тими, що сприйнятливі до швидких змін протягом декількох секунд або хвилин інтервалу часу.
Нижче наведено кілька таких примірників динамічних елементів:
- Маючи секундомір на веб-сторінці, який постійно оновлює таймер щосекунди.
- Кадр, який постійно оновлює звіт про погоду.
- Сторінка, що повідомляє про оновлення Sensex.
Вони не є ідеальними або здійсненними для використання анотації @CacheLookUp взагалі. Якщо ви це зробите, ви ризикуєте отримати виняток StaleElementReferenceExceptions.
Під час кешування таких елементів під час виконання тесту DOM елементів змінюється, однак драйвер шукає версію DOM, яка вже була збережена під час кешування. Це змушує застарілий елемент шукати драйвер, який більше не існує на веб-сторінці. Ось чому викидається StaleElementReferenceException.
Заводські класи:
Pagefactory - це концепція, побудована на декількох заводських класах та інтерфейсах. У цьому розділі ми дізнаємося про декілька заводських класів та інтерфейсів. Мало з яких ми розглянемо AjaxElementLocatorFactory , ElementLocatorFactory і DefaultElementFactory.
Чи замислювались ми коли-небудь про те, чи надає Pagefactory будь-який спосіб включити неявний або явний очікування елемента, поки не буде виконана певна умова ( Приклад: Поки елемент не видно, не ввімкнено, не можна натискати тощо)? Якщо так, ось відповідна відповідь на нього.
AjaxElementLocatorFactory є одним із вагомих факторів, що сприяють серед усіх заводських класів. Перевага AjaxElementLocatorFactory полягає в тому, що ви можете призначити значення часу очікування для веб-елемента класу сторінки об’єкта.
Хоча Pagefactory не передбачає явної функції очікування, однак, існує варіант неявного очікування за допомогою класу AjaxElementLocatorFactory . Цей клас можна використовувати включено, коли програма використовує компоненти та елементи Ajax.
Ось як ви реалізуєте це в коді. У конструкторі, коли ми використовуємо метод initElements (), ми можемо використовувати AjaxElementLocatorFactory, щоб забезпечити неявне очікування елементів.
PageFactory.initElements(driver, this); can be replaced with PageFactory.initElements( new AjaxElementLocatorFactory(driver, 20), this);Наведений вище другий рядок коду означає, що драйвер повинен встановити тайм-аут 20 секунд для всіх елементів на сторінці, коли кожен з його завантажень, і якщо якийсь елемент не знайдений після очікування 20 секунд, буде видано 'NoSuchElementException' для цього відсутнього елемента.
Ви також можете визначити очікування, як показано нижче:
public pageFactoryClass(WebDriver driver) { ElementLocatorFactory locateMe = new AjaxElementLocatorFactory(driver, 30); PageFactory.initElements(locateMe, this); this.driver = driver; } Наведений код чудово працює, оскільки клас AjaxElementLocatorFactory реалізує інтерфейс ElementLocatorFactory.
Тут батьківський інтерфейс (ElementLocatorFactory) посилається на об'єкт дочірнього класу (AjaxElementLocatorFactory). Отже, концепція Java 'оновлення' або 'поліморфізм виконання' використовується при призначенні часу очікування за допомогою AjaxElementLocatorFactory.
Що стосується того, як це працює технічно, AjaxElementLocatorFactory спочатку створює AjaxElementLocator, використовуючи SlowLoadableComponent, який, можливо, не закінчив завантаження, коли load () повертається. Після виклику load () метод isLoaded () повинен продовжувати виходити з ладу до повного завантаження компонента.
Іншими словами, всі елементи будуть шукатись свіжо кожного разу, коли елемент отримуватиме доступ до коду, викликаючи виклик locator.findElement () з класу AjaxElementLocator, який потім застосовує час очікування до завантаження через клас SlowLoadableComponent.
Крім того, після призначення часу очікування через AjaxElementLocatorFactory, елементи з анотацією @CacheLookUp більше не будуть кешуватися, оскільки анотація буде проігнорована.
Існує також варіація того, як ти можеш зателефонуйте initElements () і як ви не повинен зателефонуйте AjaxElementLocatorFactory призначити час очікування елементу.
# 1) Ви також можете вказати ім'я елемента замість об'єкта драйвера, як показано нижче в методі initElements ():
PageFactory.initElements( , this);initElements () у наведеному вище варіанті внутрішньо викликає виклик класу DefaultElementFactory, а конструктор DefaultElementFactory приймає об’єкт інтерфейсу SearchContext як вхідний параметр. Об’єкт веб-драйвера та веб-елемент належать до інтерфейсу SearchContext.
У цьому випадку метод initElements () попередньо ініціалізується лише до згаданого елемента, і не всі елементи веб-сторінки будуть ініціалізовані.
# два) Однак тут є цікавий поворот цього факту, який стверджує, що не слід викликати AjaxElementLocatorFactory конкретно. Якщо я використовую наведений вище варіант initElements () разом з AjaxElementLocatorFactory, він не вдасться.
Приклад: Наведений нижче код, тобто передача імені елемента замість об’єкта драйвера визначенню AjaxElementLocatorFactory не працюватиме, оскільки конструктор для класу AjaxElementLocatorFactory бере в якості вхідного параметра лише об’єкт веб-драйвера, а отже, об’єкт SearchContext із веб-елементом для нього не працюватиме.
PageFactory.initElements(new AjaxElementLocatorFactory(, 10), this); Q # 8) Чи є використання pagefactory можливим варіантом порівняно зі звичайним шаблоном дизайну об'єкта сторінки?
Відповідь: Це найважливіше питання, яке виникає у людей, і тому я думав розглянути його в кінці підручника. Тепер ми знаємо „вхід і вихід” щодо Pagefactory, починаючи з його концепцій, використовуваних анотацій, додаткових функцій, які він підтримує, реалізації за допомогою коду, плюсів і мінусів.
Проте ми залишаємося з цим важливим питанням: якщо pagefactory має стільки хороших речей, чому б нам не дотримуватися його використання.
Pagefactory поставляється з концепцією CacheLookUp, яку ми побачили неможливою для динамічних елементів, таких як значення елемента, які часто оновлюються. Отже, pagefactory без CacheLookUp, чи це хороший варіант? Так, якщо xpaths статичні.
Однак падіння полягає в тому, що сучасний додаток наповнений важкими динамічними елементами, де ми знаємо, що дизайн об’єкта сторінки без pagefactory працює в кінцевому рахунку добре, але чи однаково добре працює концепція pagefactory з динамічними xpaths? Можливо, не. Ось короткий приклад:
На веб-сторінці nseindia.com ми бачимо таблицю, подану нижче.

Шлях таблиці -
'//*(@id='tab9Content')/table/tbody/tr(+count+)/td(1)'Ми хочемо отримати значення з кожного рядка для першого стовпця 'Купити кількість'. Для цього нам потрібно буде збільшити лічильник рядків, але індекс стовпця залишиться 1. Немає можливості передати цей динамічний XPath в анотації @FindBy, оскільки анотація приймає статичні значення, і жодна змінна не може бути передана це.
Ось де pagefactory повністю виходить з ладу, тоді як звичайний POM чудово з ним працює. Ви можете легко використовувати цикл for, щоб збільшити індекс рядка, використовуючи такі динамічні xpaths у методі driver.findElement ().
Висновок
Модель об'єкта сторінки - це концепція дизайну або шаблон, що використовується в рамках автоматизації Selenium.
Конвекція методів присвоєння імен зручна в користуванні в об'єктній моделі сторінок. Код у POM легко зрозуміти, багаторазово використовувати та підтримувати. У POM, якщо в веб-елементі є якісь зміни, досить внести зміни у відповідний клас, а не редагувати всі класи.
Pagefactory, як і звичайний POM, - це чудова концепція для застосування. Однак ми повинні знати, де звичайний POM є можливим, а Pagefactory добре підходить. У статичних додатках (де і XPath, і елементи є статичними) Pagefactory може бути вільно реалізований з додатковими перевагами кращої продуктивності.
Крім того, коли додаток включає як динамічні, так і статичні елементи, у вас може бути змішана реалізація pom з Pagefactory та такою без Pagefactory відповідно до можливості для кожного веб-елемента.
Автор: Цей навчальний посібник написаний Шобхою Д. Вона працює керівником проекту та має понад 9 років досвіду в галузі ручного керування, автоматизації (Selenium, IBM Rational Functional Tester, Java) та тестування API (SOAPUI та Rest assured in Java). .
Тепер до вас для подальшого впровадження Pagefactory.
Щасливого вивчення !!!
=> Завітайте сюди, щоб вивчити селен з нуля.
Рекомендована література
- 30+ найкращих підручників із селену: вивчіть селен на реальних прикладах
- Ефективні сценарії сценаріїв та усунення несправностей селену - Підручник селену No27
- Налагодження сценаріїв селену за допомогою журналів (Підручник Log4j) - Підручник селену No26
- Вступ до JUnit Framework та його використання в сценарії селену - Підручник з селену No11
- 7 факторів, що впливають на тестову оцінку проекту автоматизації селену - Підручник з селену № 32
- Твердження в селені за допомогою середовищ Junit та TestNG
- Як використовувати TestNG Framework для створення сценаріїв селену - Підручник No12 для TestNG
- Дізнайтеся, як використовувати анотації TestNG у селені (з прикладами)





