Сторінка Object Model & Factory в Selenium

Що таке об’єктна модель сторінки?

Об'єктна модель сторінки (POM) це шаблон дизайну, який широко використовується в автоматизації тестування, який створює репозиторій об’єктів для елементів веб-інтерфейсу користувача. Перевагою моделі є те, що вона зменшує дублювання коду та покращує обслуговування тестів.

За цією моделлю для кожної веб-сторінки в додатку має бути відповідний клас сторінки. Цей клас Page ідентифікує WebElements цієї веб-сторінки, а також містить методи Page, які виконують операції над цими WebElements. Назви цих методів слід надавати відповідно до завдання, яке вони виконують, тобто, якщо завантажувач чекає появи платіжного шлюзу, ім’я методу POM може бути waitForPaymentScreenDisplay().

Об'єктна модель сторінки

Чому об’єктна модель сторінки?

Запуск автоматизації інтерфейсу користувача в Selenium WebDriver НЕ складне завдання. Потрібно просто знайти елементи, виконати над ними операції.

Розгляньте цей простий скрипт для входу на веб-сайт

Об'єктна модель сторінки

Як ви бачите, усе, що ми робимо, це знаходимо елементи та заповнюємо значення для цих елементів.

Це невеликий сценарій. Обслуговування сценарію виглядає легко. Але з часом набір тестів буде розширюватися. Коли ви додаєте все більше і більше рядків до свого коду, все стає складніше.

Основна проблема з підтримкою сценаріїв полягає в тому, що якщо 10 різних сценаріїв використовують той самий елемент сторінки, при будь-якій зміні в цьому елементі вам потрібно змінити всі 10 сценаріїв. Це займає багато часу та може викликати помилки.

Кращий підхід до обслуговування сценаріїв полягає у створенні окремого файлу класу, який би знаходив веб-елементи, заповнював їх або перевіряв їх. Цей клас можна повторно використовувати в усіх сценаріях, які використовують цей елемент. У майбутньому, якщо буде змінено веб-елемент, нам потрібно буде внести зміни лише в 1 файл класу, а не в 10 різних сценаріях.

Цей підхід називається Page Object Model in Selenium. Це допомагає зробити код більш читабельним, зручним для обслуговування та повторним використанням.

Об'єктна модель сторінки

Переваги ПОМ

  1. Шаблон дизайну об’єкта сторінки каже, що операції та потоки в інтерфейсі користувача мають бути відокремлені від перевірки. Ця концепція робить наш код чистішим і зрозумілішим.
  2. Друга перевага полягає в тому, що репозиторій об’єктів не залежить від тестових випадків, тому ми можемо використовувати той самий репозиторій об’єктів для різних цілей з різними інструментами. Наприклад, ми можемо інтегрувати об’єктну модель сторінки Selenium з TestNG/JUnit для функціональних Тестування і в той же час з JBehave/Cucumber для приймальних випробувань.
  3. Код стає меншим і оптимізованим через багаторазово використовувані методи сторінок у класах POM.
  4. Методи отримують більш реалістичні назви, які можна легко зіставити з операціями, що відбуваються в інтерфейсі користувача. тобто якщо після натискання кнопки ми потрапляємо на домашню сторінку, назва методу буде схожою на 'gotoHomePage()'.

Як реалізувати POM?

Простий POM:

Це базова структура структури об’єктної моделі сторінки, де всі веб-елементи AUT і метод, який працює з цими веб-елементами, зберігається у файлі класу. Таке завдання, як перевірка, має бути окремою частиною методів тестування.

Впровадити POM

Повний приклад

TestCase: Перейдіть на демонстраційний сайт Guru99.

Крок 1) Перейдіть на демонстраційний сайт Guru99

Впровадити POM

Крок 2) На домашній сторінці перевірте текст «Guru99 Bank».

Впровадити POM

Крок 3) Увійдіть у програму

Впровадити POM

Крок 4) Переконайтеся, що домашня сторінка містить текст як «Ідентифікатор менеджера: демо»

Впровадити POM

Тут ми маємо справу з 2 сторінками

  1. Увійти сторінку
  2. Домашня сторінка (відображається після входу)

Відповідно, створюємо 2 POM в Selenium класів

Guru99 Сторінка входу POM

package pages;

import org.openqa.selenium.By;

import org.openqa.selenium.WebDriver;

public class Guru99Login {

    WebDriver driver;

    By user99GuruName = By.name("uid");

    By password99Guru = By.name("password");

    By titleText =By.className("barone");

    By login = By.name("btnLogin");

    public Guru99Login(WebDriver driver){

        this.driver = driver;

    }

    //Set user name in textbox

    public void setUserName(String strUserName){

        driver.findElement(user99GuruName).sendKeys(strUserName);

    }

    //Set password in password textbox

    public void setPassword(String strPassword){

         driver.findElement(password99Guru).sendKeys(strPassword);

    }

    //Click on login button

    public void clickLogin(){

            driver.findElement(login).click();

    }

    //Get the title of Login Page

    public String getLoginTitle(){

     return    driver.findElement(titleText).getText();

    }

    /**

     * This POM method will be exposed in test case to login in the application

     * @param strUserName

     * @param strPasword

     * @return

     */

    public void loginToGuru99(String strUserName,String strPasword){

        //Fill user name

        this.setUserName(strUserName);

        //Fill password

        this.setPassword(strPasword);

        //Click Login button

        this.clickLogin();        
    }

}

Домашня сторінка Guru99 POM в Selenium

package pages;

import org.openqa.selenium.By;

import org.openqa.selenium.WebDriver;

public class Guru99HomePage {

    WebDriver driver;

    By homePageUserName = By.xpath("//table//tr[@class='heading3']");

    

    public Guru99HomePage(WebDriver driver){

        this.driver = driver;

    }

    //Get the User name from Home Page

        public String getHomePageDashboardUserName(){

         return    driver.findElement(homePageUserName).getText();

        }

}

Guru99 Простий POM в Selenium Тестовий випадок

package test;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.firefox.FirefoxDriver;

import org.testng.Assert;

import org.testng.annotations.BeforeTest;

import org.testng.annotations.Test;

import pages.Guru99HomePage;

import pages.Guru99Login;

public class Test99GuruLogin {

    String driverPath = "C:\\geckodriver.exe";
    
    WebDriver driver;

    Guru99Login objLogin;

    Guru99HomePage objHomePage;

    @BeforeTest

    public void setup(){

	System.setProperty("webdriver.gecko.driver", driverPath);
        
        driver = new FirefoxDriver();

        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

        driver.get("https://demo.guru99.com/V4/");

    }

    /**

     * This test case will login in https://demo.guru99.com/V4/

     * Verify login page title as guru99 bank

     * Login to application

     * Verify the home page using Dashboard message

     */

    @Test(priority=0)

    public void test_Home_Page_Appear_Correct(){

        //Create Login Page object

    objLogin = new Guru99Login(driver);

    //Verify login page title

    String loginPageTitle = objLogin.getLoginTitle();

    Assert.assertTrue(loginPageTitle.toLowerCase().contains("guru99 bank"));

    //login to application

    objLogin.loginToGuru99("mgr123", "mgr!23");

    // go the next page

    objHomePage = new Guru99HomePage(driver);

    //Verify home page

    Assert.assertTrue(objHomePage.getHomePageDashboardUserName().toLowerCase().contains("manger id : mgr123"));

    }

У чому полягає Page Factory Selenium?

Page Factory в Selenium це вбудована концепція каркаса об’єктної моделі сторінки для Selenium WebDriver, але він дуже оптимізований. Він використовується для ініціалізації об’єктів Page або для створення екземпляра самого об’єкта Page. Він також використовується для ініціалізації елементів класу Page без використання «FindElement/s».

Тут також ми дотримуємося концепції поділу сховища об’єктів сторінки та методів тестування. Крім того, за допомогою класу PageFactory в Selenium, використовуємо анотації @FindBy щоб знайти WebElement. Ми використовуємо метод initElements для ініціалізації веб-елементів

Page Factory In Selenium

@FindBy може прийняти tagName, partialLinkText, name, linkText, id, css, className, xpath як атрибути.

Давайте розглянемо той самий приклад, що й вище, із використанням Page Factory

Сторінка входу Guru99 із Page Factory

package PageFactory;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.WebElement;

import org.openqa.selenium.support.FindBy;

import org.openqa.selenium.support.PageFactory;

public class Guru99Login {

    /**

     * All WebElements are identified by @FindBy annotation

     */

    WebDriver driver;

    @FindBy(name="uid")

    WebElement user99GuruName;

    @FindBy(name="password")

    WebElement password99Guru;    

    @FindBy(className="barone")

    WebElement titleText;

    @FindBy(name="btnLogin")

    WebElement login;

    public Guru99Login(WebDriver driver){

        this.driver = driver;

        //This initElements method will create all WebElements

        PageFactory.initElements(driver, this);

    }

    //Set user name in textbox

    public void setUserName(String strUserName){

        user99GuruName.sendKeys(strUserName);     
    }

    //Set password in password textbox

    public void setPassword(String strPassword){

    password99Guru.sendKeys(strPassword);

    }

    //Click on login button

    public void clickLogin(){

            login.click();

    }  

    //Get the title of Login Page

    public String getLoginTitle(){

     return    titleText.getText();

    }

    /**

     * This POM method will be exposed in test case to login in the application

     * @param strUserName

     * @param strPasword

     * @return

     */

    public void loginToGuru99(String strUserName,String strPasword){

        //Fill user name

        this.setUserName(strUserName);

        //Fill password

        this.setPassword(strPasword);

        //Click Login button

        this.clickLogin();           

    }

}

Домашня сторінка Guru99 із Page Factory

package PageFactory;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.WebElement;

import org.openqa.selenium.support.FindBy;

import org.openqa.selenium.support.PageFactory;

public class Guru99HomePage {

    WebDriver driver;

    @FindBy(xpath="//table//tr[@class='heading3']")

    WebElement homePageUserName;    

    public Guru99HomePage(WebDriver driver){

        this.driver = driver;

        //This initElements method will create all WebElements

        PageFactory.initElements(driver, this);

    }   

    //Get the User name from Home Page

        public String getHomePageDashboardUserName(){

         return    homePageUserName.getText();

        }

}

Guru99 TestCase із концепцією Page Factory

package test;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.firefox.FirefoxDriver;

import org.testng.Assert;

import org.testng.annotations.BeforeTest;

import org.testng.annotations.Test;

import PageFactory.Guru99HomePage;

import PageFactory.Guru99Login;

public class Test99GuruLoginWithPageFactory {

    String driverPath = "C:\\geckodriver.exe";
    
    WebDriver driver;

    Guru99Login objLogin;

    Guru99HomePage objHomePage; 

    @BeforeTest

    public void setup(){

        System.setProperty("webdriver.gecko.driver", driverPath);
        
        driver = new FirefoxDriver();

        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

        driver.get("https://demo.guru99.com/V4/");

    }

    /**

     * This test go to https://demo.guru99.com/V4/

     * Verify login page title as guru99 bank

     * Login to application

     * Verify the home page using Dashboard message

     */

    @Test(priority=0)

    public void test_Home_Page_Appear_Correct(){

        //Create Login Page object

    objLogin = new Guru99Login(driver);

    //Verify login page title

    String loginPageTitle = objLogin.getLoginTitle();

    Assert.assertTrue(loginPageTitle.toLowerCase().contains("guru99 bank"));

    //login to application

    objLogin.loginToGuru99("mgr123", "mgr!23");

    // go the next page

    objHomePage = new Guru99HomePage(driver);

    //Verify home page

    Assert.assertTrue(objHomePage.getHomePageDashboardUserName().toLowerCase().contains("manger id : mgr123"));

    }

}

Повна структура проекту виглядатиме так, як показано на схемі:

Page Factory в Selenium

AjaxElementLocatorFactory

AjaxElementLocatorFactory це концепція ледачого завантаження PageFactory в Selenium. Він використовується для пошуку веб-елементів лише тоді, коли елементи використовуються в будь-якій операції. Він призначає тайм-аут для WebElements класу сторінки об’єкта. Одна з ключових переваг використання шаблону PageFactory в Selenium є класом AjaxElementLocatorFactory.

Тут, коли над елементом виконується операція, очікування його видимості починається лише з цього моменту. Якщо елемент не знайдено протягом заданого інтервалу часу, Тестовий випадок виконання викличе виняток "NoSuchElementException".

Фабрика локаторів AjaxElement

Підсумки

  1. Об'єктна модель сторінки в Selenium WebDriver — це шаблон проектування сховища об’єктів.
  2. Selenium об’єктна модель сторінки створює наш тестовий код, який можна підтримувати та використовувати повторно.
  3. Page Factory — це оптимізований спосіб створення репозиторію об’єктів у рамках концепції Page Object Model.
  4. AjaxElementLocatorFactory — це концепція відкладеного завантаження у Page Factory — шаблон дизайну об’єкта сторінки для ідентифікації WebElements лише тоді, коли вони використовуються в будь-якій операції.

Завантажити Selenium Файли проекту для демонстрації в цьому посібнику

Детальніше ЧИТАТИ