Автоматизированное тестирование стало абсолютной необходимостью в динамичной и быстро меняющейся бизнес-среде с огромным вниманием к ускоренному выходу на рынок. Тем не менее, что касается автоматизации, автоматизированное тестирование Selenium по-прежнему дает максимальные преимущества с точки зрения тестового покрытия и покрытия браузера.
По мере развития продукта тестировщики автоматизации также находятся в боевой готовности, чтобы убедиться, что сценарии тестов соответствуют функциям, реализуемым в продукте. Например, если тесты проводятся без учета масштабируемости и ремонтопригодности, минимальные изменения в пользовательском интерфейсе веб-приложения приведут к изменению сценариев автоматизации Selenium-тестов.
Более сложной задачей является сохранение «большей отвязанности» реализации тестов от веб-элементов, используемых в сценариях тестирования. Объектная модель страницы в Selenium, также называемая POM, является популярным шаблоном проектирования в Selenium, используемым для создания хранилища объектов для хранения веб-элементов.
В этом блоге, посвященном Selenium Page Factory tutorial, мы подробно рассмотрим Page Factory в Selenium, которая делает использование Page Objects проще & легче с помощью класса фабрики в Selenium WebDriver. Page Factory в Selenium можно считать оптимизированной Page Object Model (POM) для Selenium WebDriver.
Давайте рассмотрим, что такое Page Factory в Selenium, а также углубимся в разницу между Page Factory и Page Object Model в Selenium тестировании.
Если вы новичок в Selenium и задаетесь вопросом, что это такое, рекомендуем ознакомиться с нашим руководством — Что такое Selenium?
Что такое фабрика страниц в Selenium
Page Factory — это встроенная Page Object Model (POM) для Selenium WebDriver, которая более оптимизирована, чем POM. На высоком уровне Page Factory в Selenium можно рассматривать как расширение Page Objects. Класс Page Factory в Selenium является катализатором, который облегчает и упрощает использование Page Objects.
Можно с уверенностью сказать, что Page Factory — это комбинация POM, включенного через класс Page Factory в Selenium. Ниже показано различие между Page Object Model (POM) и Page Factory на верхнем уровне:
Хотя Page Factory в Selenium может быть использована различными способами, она, безусловно, помогает улучшить аспекты сопровождаемости и повторного использования реализации тестов.
Введение в класс PageFactory в Selenium
Для поддержки паттерна проектирования Page Object (или PageObject) библиотека поддержки Selenium WebDriver содержит класс PageFactory, который делает использование Page Objects более простым и легким. При использовании Page Factory в Selenium тестеры автоматизации могут использовать аннотацию FindBy для определения местоположения веб-элементов. Эти веб-элементы определены в классах веб-страниц (или Page Objects).
Основное преимущество аннотации @FindBy заключается в том, что она позволяет инициализировать элементы страницы без использования FindElement (или FindElements) в Selenium.
Класс PageFactory в Selenium также предоставляет метод initElements для инициализации веб-элементов. В последующих разделах этого руководства по Selenium Page Factory мы подробно рассмотрим наиболее часто используемые методы класса. Это будет полезно, когда мы продемонстрируем паттерн проектирования Page Factory в Selenium на примере автоматизации.
Как инициализировать Page Factory в Selenium
Для использования POM с Page Factory, объекты Page Objects (или классы страниц), содержащие веб-элементы (или локаторы элементов) для страницы, должны быть инициализированы с помощью соответствующих методов класса Page Factory.
Это делается для того, чтобы веб-элементы были инициализированы до выполнения соответствующих действий.
Одна из лучших практик Selenium при использовании Page Factory заключается в создании всех переменных веб-элементов в начале класса и инициализации этих переменных при загрузке страницы.
Инициализация веб-элементов может быть выполнена с помощью методов initElements класса PageFactory. Вот некоторые из распространенных аннотаций и методов, которые широко используются в Page Factory в Selenium.
Аннотация FindBy в Page Factory
Аннотация FindBy используется для объявления и инициализации переменных веб-элементов с помощью нужных веб-локаторов в Selenium. Таким образом, вы можете находить веб-элементы с помощью популярных локаторов, таких как ID, Name, Link Text, Class Name и т.д.
Первый шаг — передача атрибута и его значения (или локатора элемента) для поиска веб-элемента в аннотацию @FindBy. Второй шаг — объявление переменной, чтобы ее можно было использовать в дальнейшем в реализации теста.
Существует два способа использования аннотации @FindBy:
Вариант 1
@FindBy(how = How.ID, using=" element-id")
private WebElement element-name;
- ‘How’ — Класс org.openqa.selenium.support.How в Selenium предоставляет значения (или содержимое) Enum, которые обозначают желаемый локатор (например, CLASS_NAME, ID, CSS, ID_OR_NAME, NAME, LINK_TEXT, PARTIAL_LINK_TEXT, XPATH, TAG_NAME и т.д.).
— ‘using’ используется для присвоения значения статической переменной
Вариант 2 [более краткая форма]
@FindBy(id="element-id")
private WebElement element-name;
В приведенном выше синтаксисе мы использовали свойство ID для определения местоположения элемента ‘element-id’. Помимо ID, вы можете использовать такие популярные локаторы, как CSS Selectors в Selenium, Name locator, Class Name locator, XPath locators и другие.
Если существует несколько элементов, соответствующих заданным локаторам, можно использовать аннотацию FindAll с несколькими аннотациями FindBy.
@FindAll
(
{
@FindBy(how = How.ID, using = "element"),
@FindBy(className = "element-field")
}
)
private WebElement element_name;
Пример
Мы обнаружили кнопку с текстом ссылки ‘Start Free Testing’ на домашней странице LambdaTest с помощью инструмента ‘Inspect tool’ в Google Chrome.
Ниже приведены два способа, с помощью которых аннотация @FindBy используется для объявления веб-элемента, который был найден с помощью свойства XPath.
Пример: Вариант 1
Below are the two ways through which @FindBy annotation is used to declare the web element that was located using the XPath property.
Example: Option 1
Пример: Вариант 2
@FindBy(xpath = "//a[.='Start Free Testing']")
private WebElement SignUpButton;
Метод initElements в фабрике страниц
После того как необходимые веб-элементы на странице найдены с помощью соответствующих веб-локаторов, метод initElements используется для объявления и инициализации необходимых переменных веб-элементов.
initElements — это перегруженная функция (или метод), которая может использоваться различными способами в зависимости от своих аргументов.
Вот некоторые из способов инициализации переменных веб-элементов с помощью метода initElements фабрики страниц в Selenium:
Вариант 1: initElements
Он создает экземпляр данного класса и устанавливает ленивый прокси для каждого из полей WebElements и List, которые были объявлены ранее с помощью аннотации @FindBy. Если класс не может быть инстанцирован, возникает исключение.
Синтаксис
public static <T> T initElements(WebDriver driver,
java.lang.Class<T> pageClassToProxy)
Параметры типа
- T — Класс объекта PageObject
Входные параметры
- драйвер — Selenium WebDriver, используемый для размещения веб-элементов
- pageClassToProxy — Класс, который будет инициализирован Возвращается
Метод возвращает инстанцированный экземпляр класса с проксируемыми полями WebElement и List.
Пример
SamplePage sample_page = PageFactory.initElements(web_driver, SamplePage.class);
Вариант 2: initElements
Во многом похож на метод initElements(WebDriver, Class), за исключением того, что он будет заменять поля уже инстанцированного объекта.
Синтаксис
static void initElements(WebDriver driver, java.lang.Object page)
Входные параметры
- драйвер — Selenium WebDriver, используемый для определения местоположения веб-элементов
- page — Объект с полями WebElement и List, которые должны быть проксированы.
Пример
SamplePage sample_page = new SamplePage(web_driver);
PageFactory.initElements(web_driver, sample_page);
Здесь мы создаем экземпляр класса SamplePage, а созданный объект — sample_page. Метод initElements класса PageFactory в Selenium инициализирует все веб-элементы на странице SamplePage с помощью аннотации @FindBy.
Инициализация веб-элементов также может быть выполнена внутри конструктора класса веб-страницы:
public CreateAccountPage(WebDriver web_driver) {
this.driver = web_driver;
/* Initialize Elements */
PageFactory.initElements(web_driver, this);
}
Помимо двух вышеперечисленных популярных способов инициализации переменных веб-элементов при использовании Page Factory в Selenium, вы также можете использовать следующие два подхода:
Вариант 3: initElements
static void initElements(ElementLocatorFactory factory, java.lang.Object page)
Этот метод очень похож на другие методы initElements, основное отличие заключается в том, что он принимает ElementLocatorFactory, который обеспечивает механизм для поиска соответствующих элементов.
Вариант 4: initElements
static void initElements(FieldDecorator decorator, java.lang.Object page)
Этот метод очень похож на другие методы initElements, основное отличие в том, что он принимает FieldDecorator, используемый для декорирования полей.
Альтернатива aerokube для запуска тестов на 70% быстрее, чем любая облачная сетка, начните бесплатный тест сегодня!!!
Примечание — SHA256 Hash calculator — этот бесплатный онлайн-инструмент поможет вам определить целостность данных и проверить подлинность хэша.
Как инициализировать веб-элементы в фабрике страниц в Selenium
Как было показано в предыдущем разделе этого руководства по Selenium Page Factory, переменные веб-элементов должны быть инициализированы до того, как с ними будет выполнено какое-либо взаимодействие. Метод initElements используется для инициализации веб-элементов в классах веб-страниц или объектах Page Objects.
Рассмотрим простой пример, в котором мы находим нужный веб-элемент с помощью соответствующих веб-локаторов и инициализируем его с помощью метода initElements. В этом примере мы находим ссылку ‘Start Free Testing’ с помощью XPath в Selenium.
@FindBy(how = How.XPATH, using = "//a[.='Start Free Testing']")
@CacheLookup
private WebElement StartTestingButton;
или
@FindBy(xpath = "//a[.='Start Free Testing']")
@CacheLookup
private WebElement StartTestingButton;
Здесь веб-элемент StartTestingButton кэшируется с помощью аннотации @CacheLookup. Эта аннотация предписывает Selenium кэшировать веб-элемент вместо того, чтобы находить его каждый раз при загрузке веб-страницы.
Хотя @CacheLookup обеспечивает значительный прирост производительности, его следует использовать только для статических веб-элементов (т.е. элементов, которые не изменяются после каждой перезагрузки страницы).
Метод initElements используется для инициализации веб-элементов на странице.
public HomePage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
Мы используем кнопку click в Selenium для выполнения операции щелчка на кнопке ‘Start Free Testing’ с помощью локатора XPath.
public void clickOnStartTestingButton()
{
StartTestingButton.click();
}
Если вы планируете использовать другие веб-локаторы с Page Factory в Selenium, обязательно ознакомьтесь с нашим подробным блогом об использовании веб-локаторов с Page Factory.
Что такое ленивая инициализация в Page Factory
До сих пор в этом руководстве по Selenium Page factory мы видели, что метод initElements используется для инициализации объектов класса Page Object. Однако означает ли это, что все необходимые Web-элементы на странице (или AUT) находятся и сохраняются за один раз?
Элементы не находятся и не сохраняются заранее. Selenium WebDriver найдет соответствующий Web-элемент только тогда, когда этот конкретный элемент (или объект страницы) будет использоваться или когда будет выполнена соответствующая операция над этим элементом.
В случае если требуемый веб-элемент отсутствует на странице, возникает исключение Selenium NoSuchElementException, указывающее на то, что нужный элемент отсутствует в DOM.
Если вам интересно узнать об исключениях Selenium, ознакомьтесь с нашим подробным блогом об исключениях в Selenium WebDriver.
Чтобы продемонстрировать, как Page Factory в Selenium WebDriver выполняет ленивую инициализацию, мы переходим на страницу регистрации LambdaTest SignUp Page и пробуем ввести ‘First Name’ в поле Name. Однако проблема в том, что мы использовали неправильный веб-локатор для нахождения этого элемента.
Вместо правильного XPath — //input[@name=’name’], мы использовали неправильное значение XPath (т.е. //input[@name=’names’]).
@FindBy(xpath = "//input[@name='names']")
WebElement full_name;
Следовательно, нужный элемент не находится на странице, что приводит к исключению WebDriver.
Теперь, когда мы рассмотрели основные принципы работы Page Factory в Selenium, давайте замажем руки рабочим сценарием тестирования. В этом примере Selenium Page Factory веб-страницы представлены в виде классов Java.
Комбинация @FindBy/@FindAll (или других аннотаций) и соответствующих методов Selenium в классе PageFactory используется для поиска веб-элементов и их инициализации для автоматизированного тестирования Selenium.
Получив сертификат TestNG, вы сможете проверить свои навыки в проведении автоматизированного тестирования с помощью TestNG и поднять свою карьеру на новый уровень.
Вот краткий обзор сертификации TestNG от LambdaTest:
Демонстрация: Фабрика страниц в Selenium For Java
В этом учебном пособии по Selenium Page Factory мы автоматизируем процесс регистрации в LambdaTet, перейдя на домашнюю страницу LambdaTest, а затем введя соответствующие данные на странице регистрации.
Демонстрация будет выполнена с использованием фреймворка TestNG в Selenium. Выполнение осуществляется на облаке — Selenium Grid, предоставляемом LambdaTest. Облачное тестирование с помощью Selenium дает множество преимуществ — улучшенное тестовое покрытие (в плане комбинаций браузеров и ОС), ускоренное время выхода на рынок и исключительное качество продукта. Для упрощения демонстрация Page Factory в Selenium выполнена на комбинации Chrome (последняя версия) + Windows 10.
Желаемые возможности генерируются с помощью генератора желаемых возможностей на LambdaTest. Для доступа к облачной сети LambdaTest требуется правильная комбинация имени пользователя и ключа доступа, подробности о которой можно найти в разделе профиля LambdaTest.
Сценарий тестирования
- Найдите кнопку «Начать бесплатное тестирование» на странице LambdaTest.
- Нажмите на кнопку
- Введите данные, необходимые для новой регистрации
- Сработайте, если ссылка ‘Verify Your Email’ не открывается.
Настройка проекта
Мы создадим Maven-проект в IntelliJ IDEA для демонстрации Page Factory в Selenium. Хотя мы используем IntelliJ IDEA, вы можете использовать любую другую IDE по вашему выбору (например, Eclipse). Если вы только начинаете работать с IntelliJ или Eclipse для разработки на Java, обязательно ознакомьтесь с нашими блогами, которые помогут вам в следующем:
- Настройка Selenium в IntelliJ
- Настройка Selenium в Eclipse
Ниже показана структура каталогов:
Для начала работы мы создали новый пакет — com.pagefact в папке src/test/java. Под вновь созданным пакетом мы создали еще два пакета:
-
com.pagefact.pages — включает в себя объекты Page (или классы Page), где комбинация аннотации @FindBy и метода initElements используется для подготовки основы для тестов.
-
com.pagefact.tests — Включает реализацию тестов, которые будут использовать соответствующие классы страниц для выполнения соответствующих операций над Web-элементами в DOM.
Таким образом, мы готовы к созданию необходимых классов Page Object и тестов, которые будут использовать эти классы страниц.
Реализация
Прежде чем приступить к реализации, давайте добавим необходимые зависимости проекта в POM-файл проекта.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>SeleniumTEST</groupId>
<artifactId>PageObjectFactoryDemo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.9.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.0.0-rc-2</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-chrome-driver</artifactId>
<version>4.0.0-rc-2</version>
</dependency>
<dependency>
<groupId>io.github.bonigarcia</groupId>
<artifactId>webdrivermanager</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.7.28</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<defaultGoal>install</defaultGoal>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<configuration>
<suiteXmlFiles>
<!-- TestNG suite XML files -->
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
<version>3.0.0-M5</version>
</plugin>
</plugins>
</build>
</project>
Для тестирования мы используем версию Selenium 4 RC (т.е. 4.0.0-rc-2). Если вы еще не опробовали Selenium 4, обязательно ознакомьтесь с нашим подробным руководством по Selenium 4, которое охватывает все основные аспекты, такие как относительные локаторы в Selenium 4, имитация геолокации в Selenium 4, Selenium Grid 4 и т.д., которые считаются изменениями в Selenium 4.
TestNG (v 7.4.0) используется для реализации, группировки и тестирования соответствующих сценариев. Если вы новичок в использовании фреймворка TestNG (или более хорошо знакомы с фреймворком JUnit), вы можете обратиться к сравнению JUnit и TestNG, чтобы понять основные различия между этими двумя фреймворками автоматизации тестирования.
Примечание: SHA1 Hash calculator — этот бесплатный онлайн-инструмент поможет вам определить контрольную сумму файла или группы символов.
Объекты страниц (или классы страниц)
Как уже упоминалось ранее в этом руководстве по Selenium Page Factory, все классы страниц создаются в пакете com.pagefact.pages
Объект страницы HomePage
Самая первая страница, которую нам нужно создать — это домашняя страница LambdaTest. Для этого мы создаем класс HomePage в пакете com.pagefact.pages.
package com.pagefact.pages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
import org.openqa.selenium.support.PageFactory;
public class HomePage {
/* Local Selenium Grid */
/* private WebDriver driver; */
/* Remote Selenium Grid */
private RemoteWebDriver driver;
private static String PAGE_URL="https://www.lambdatest.com";
@FindBy(how = How.XPATH, using = "//a[.='Start Free Testing']")
private WebElement StartTestingButton;
public HomePage(RemoteWebDriver driver)
{
this.driver = driver;
driver.get(PAGE_URL);
PageFactory.initElements(driver, this);
}
public void clickOnStartTestingButton()
{
StartTestingButton.click();
}
}
Ознакомление с кодом
Поскольку мы запускаем тесты на облачной сетке LambdaTest, необходимые пакеты импортируются в начале реализации.
import org.openqa.selenium.remote.RemoteWebDriver;
Необходимые пакеты для использования класса Page Factory Selenium и методов аннотации @FindBy также импортируются в самом начале.
import org.openqa.selenium.support.How;
import org.openqa.selenium.support.PageFactory;
Поскольку мы запускаем тесты на облачной сетке LambdaTest, мы создаем экземпляр RemoteWebDriver вместо локального WebDriver. Вы можете ознакомиться с учебником Selenium RemoteWebDriver, чтобы получить больше информации о разнице между локальным и удаленным веб-драйверами.
public class HomePage {
private RemoteWebDriver driver;
Поскольку нам нужно выполнить операцию нажатия на кнопку ‘Start Free Testing’, мы находим веб-элемент с помощью аннотации @FindBy с XPath-локатором элемента. Вы можете использовать ‘Inspect Tool’ в Chrome или плагин, такой как POM Builder или SelectorsHub в Chrome, чтобы получить XPath нужного веб-элемента.
Создается новая переменная веб-элемента (например, StartTestingButton), чтобы можно было выполнить соответствующие операции (например, click, sendKeys и т.д.) для этого элемента.
1
2
@FindBy(how = How.XPATH, using = "//a[.='Start Free Testing']")
private WebElement StartTestingButton;
Как уже говорилось в предыдущем разделе этого руководства по Selenium Page Factory, мы инициализируем переменные веб-элемента в конструкторе. Затем URL устанавливается на домашнюю страницу LambdaTest, чтобы дальнейшие тесты могли выполняться на переменных веб-элемента этой страницы.
public HomePage(RemoteWebDriver driver)
{
this.driver = driver;
driver.get(PAGE_URL);
PageFactory.initElements(driver, this);
}
Поскольку переменная веб-элемента является кнопкой, мы создаем метод для обеспечения механизма нажатия на переменную веб-элемента (т.е. StartTestingButton).
public void clickOnStartTestingButton()
{
StartTestingButton.click();
}
Объект страницы SignUpPage
Цель этого класса страницы — проверить, является ли нажатие на кнопку «Начать бесплатное тестирование» успешным, и перешла ли страница на «Страницу создания аккаунта». Для этого мы создаем класс SignUpPage в разделе com.pagefact.pages.
package com.pagefact.pages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class SignUpPage
{
/* Local Selenium Grid */
/* private WebDriver driver; */
/* Remote Selenium Grid */
private RemoteWebDriver driver;
@FindBy(xpath = "//h1[@class='form_title']")
private WebElement form_title;
@FindBy(css = ".btn")
private WebElement SignUpButton;
public SignUpPage (RemoteWebDriver driver)
{
this.driver = driver;
PageFactory.initElements(driver, this);
}
public boolean isLTPageOpen()
{
return form_title.getText().toString().contains("Signup for Free");
}
}
Ознакомление с кодом
В этом классе страниц есть только один метод, цель которого — проверить заголовок веб-страницы. Поэтому сначала мы создадим переменную веб-элемента, которая находится с помощью аннотации @FindBy и локатора XPath в Selenium.
Создается новая переменная веб-элемента ‘form_title’, которая будет использоваться для перекрестной проверки заголовка веб-страницы.
@FindBy(xpath = "//h1[@class='form_title']")
private WebElement form_title;
Создается метод с именем ‘isLTPageOpen’, который возвращает true, если заголовок страницы содержит строку ‘Signup for Free’.
public boolean isLTPageOpen()
{
return form_title.getText().toString().contains("Signup for Free");
}
Объект страницы CreateAccountPage
Цель этого класса страницы — ввести необходимые данные на странице «Создание аккаунта» (куда мы попадаем после нажатия на кнопку «Начать бесплатное тестирование» на главной странице). Для этого мы создаем класс CreateAccountPage в разделе com.pagefact.pages.
package com.pagefact.pages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.CacheLookup;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.Select;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
public class CreateAccountPage
{
/* Local Selenium Grid */
/* private WebDriver driver; */
/* Remote Selenium Grid */
private RemoteWebDriver driver;
@FindBy(xpath = "//input[@name='name']")
WebElement full_name;
@FindBy(css = "[name='email']")
WebElement org_email;
@FindBy(xpath = "//input[@id='userpassword']")
WebElement acc_password;
@FindBy(xpath = "//input[@name='phone']")
WebElement phone_number;
@FindBy(css = "[name='designation']")
WebElement designation;
@FindBy(css = "[name='org_size']")
WebElement org_size;
@FindBy(xpath = "//samp[@class='customcheckbox']")
WebElement check_box;
@FindBy(css = ".btn")
WebElement create_account_button;
@FindBy(css = "#recaptcha-verify-button")
@CacheLookup
WebElement recaptcha_button;
public CreateAccountPage(RemoteWebDriver driver)
{
this.driver = driver;
PageFactory.initElements(driver, this);
}
public void setName(String fullname)
{
full_name.clear();
full_name.sendKeys(fullname);
}
public void setEmail(String email)
{
org_email.clear();
org_email.sendKeys(email);
}
public void setAccount_password(String pwd)
{
acc_password.clear();
acc_password.sendKeys(pwd);
}
public void setDesignation(String desig_name) {
Select dropdown;
dropdown = new Select(designation);
dropdown.selectByValue(desig_name);
}
public void setCompanySize(String comp_size) {
Select dropdown;
dropdown = new Select(org_size);
dropdown.selectByValue(comp_size);
}
public void setPhone_number (String phonenum)
{
phone_number.clear();
phone_number.sendKeys(phonenum);
}
public void clickAcceptTCButton()
{
check_box.click();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
create_account_button.click();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
}
public boolean isVerifyPageOpen()
{
String expected_title = "Verify Your Email Address";
String win_title = driver.getTitle();
boolean isWinFound = win_title.indexOf(expected_title) != -1? true: false;
return isWinFound;
}
}
Описание кода
Если операция нажатия на кнопку «Начать бесплатное тестирование» на главной странице прошла успешно, мы переходим на страницу создания аккаунта LambdaTest. Большинство шагов остаются теми же, что и в разделе о создании объекта HomePage.
Поскольку на странице ‘Account Creation’ имеется шесть полей, необходимые переменные веб-элементов создаются путем нахождения веб-элементов с помощью соответствующего веб-локатора и аннотации @FindBy.
Вот как находится элемент ‘Name’ с помощью локатора XPath в Selenium.
@FindBy(xpath = "//input[@name='name']")
WebElement full_name;
Поскольку все остальные веб-элементы являются текстовыми полями, мы используем либо CSS/XPath, либо любой другой соответствующий локатор, связанный с аннотацией @FindBy. Как только элемент найден, создаются соответствующие переменные веб-элемента (например, full_name, phone_number, acc_password и т.д.), чтобы можно было выполнить соответствующие действия над ними.
@FindBy(xpath = "//input[@id='userpassword']")
WebElement acc_password;
@FindBy(xpath = "//input[@name='phone']")
WebElement phone_number;
После того как необходимые веб-элементы найдены, а переменные веб-элементов созданы, для инициализации элементов используется метод initElements. Как упоминалось ранее в этом руководстве Selenium Page Factory, элемент(ы) инициализируется(ются) только тогда, когда над ним(и) выполняется соответствующее действие (например, клик, sendKeys, clear и т.д.).
public CreateAccountPage(RemoteWebDriver driver)
{
this.driver = driver;
PageFactory.initElements(driver, this);
}
Поскольку элементы — Имя, Бизнес Email, Пароль и Номер телефона — являются текстовыми полями, sendKeys в Selenium используется для ввода соответствующей информации в эти элементы.
public void setName(String fullname)
{
full_name.clear();
full_name.sendKeys(fullname);
}
public void setEmail(String email)
{
org_email.clear();
org_email.sendKeys(email);
}
Элементы Designation и Company Size являются выпадающими полями. Следовательно, мы используем соответствующие методы для работы с выпадающими элементами в Selenium. Например, мы можем выбрать нужное значение из выпадающих элементов, используя selectByIndex(int), selectByValue(String) или другие доступные методы.
public void setDesignation(String desig_name)
{
Select dropdown;
dropdown = new Select(designation);
dropdown.selectByValue(desig_name);
}
public void setCompanySize(String comp_size)
{
Select dropdown;
dropdown = new Select(org_size);
dropdown.selectByValue(comp_size);
}
Создается метод для выбора (или проверки) ‘T&C Checkbox’. Затем элемент находится с помощью селектора XPath.
Добавляется блокирующее ожидание в 5 секунд, чтобы убедиться, что требуемая операция завершена. Хотя этот метод не считается одним из лучших методов Selenium, мы использовали его только для демонстрации использования Page Factory в Selenium. Вы также можете использовать явные ожидания и плавные ожидания для добавления задержек при обработке динамических веб-страниц.
Вы можете обратиться к нашему блогу о задержках в Selenium, где подробно рассматриваются все аспекты обработки содержимого динамических веб-страниц (с соответствующими задержками).
public void clickAcceptTCButton()
{
check_box.click();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
create_account_button.click();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
}
Простой Selenium-тест, использующий классы Page
Теперь, когда мы создали необходимые объекты Page Objects (или классы страниц), давайте соберем все части для создания простого Selenium-теста. Файл теста (т.е. SignUpOnLTTest.java) создается на странице com.pagefact.tests.
Вот реализация Selenium-теста:
package com.pagefact.tests;
import com.pagefact.pages.*;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
/* TestNG framework is used instead of JUnit */
/* Tests triggered via testng.xml */
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class SignUpOnLTTest
{
/* Local Selenium Grid */
/* WebDriver driver; */
/* Fetch details from https://accounts.lambdatest.com/detail/profile */
public String username = "himanshu.sheth";
public String accesskey = "IreQpTjhvTdZ9aFfouyQePZbOs4EPT3KpkqvUxxAWf4qGK9rvI";
public String gridURL = "@hub.lambdatest.com/wd/hub";
RemoteWebDriver driver = null;
@BeforeClass
public void testSetUp() throws MalformedURLException
{
/* Instantiate the Chrome instance */
/* local Selenium Grid */
/* driver = new ChromeDriver(); */
/* Selenium 4 capabilities generated using https://www.lambdatest.com/capabilities-generator/ */
ChromeOptions capabilities = new ChromeOptions();
capabilities.setCapability("browserName", "chrome");
capabilities.setCapability("version", "latest");
capabilities.setCapability("platform", "Windows 10");
capabilities.setCapability("build", "[Java] Page Factory Demo on LambdaTest");
capabilities.setCapability("name", "[Java] Page Factory Demo on LambdaTest");
capabilities.setCapability("geoLocation","IN");
try
{
driver = new RemoteWebDriver(new URL("https://" + username + ":" + accesskey + gridURL), capabilities);
}
catch (MalformedURLException e)
{
System.out.println("Invalid grid URL");
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
}
@Test
public void test_signupOnLambdaTest() throws InterruptedException
{
HomePage home = new HomePage(driver);
home.clickOnStartTestingButton();
SignUpPage signup = new SignUpPage(driver);
/* Check if page is opened */
Assert.assertTrue(signup.isLTPageOpen());
/* Create object of CreateAccountPage */
CreateAccountPage accountPage =new CreateAccountPage(driver);
/* Fill up data */
accountPage.setName("Page Factory Testing");
accountPage.setEmail("pagefactorytesting123@gmail.com");
accountPage.setAccount_password("password123");
accountPage.setPhone_number("911234567891");
accountPage.setDesignation("Manager");
accountPage.setCompanySize("10000+");
/* Click on Accept T&C and Create Account button */
accountPage.clickAcceptTCButton();
/* Wait for a few seconds */
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
/* Check if page is opened */
if (accountPage.isVerifyPageOpen())
{
System.out.println("Email address verification page is openn");
}
/* Wait for a few seconds */
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
System.out.println("Page Factory demo completen");
}
@AfterClass
public void tearDown()
{
System.out.println("Close method of WebDriver Called");
driver.close();
}
}
Краткое описание кода
Чтобы начать работу с Selenium-тестом, мы импортируем все Page Objects (или Page Classes), которые доступны в пакете com.pagefact.pages.
import com.pagefact.pages.*;
Желаемые возможности [т.е. Chrome (последняя версия) на Windows 10] генерируются с помощью генератора желаемых возможностей на LambdaTest. Геолокация установлена на «IN» (т.е. сайт будет тестироваться с желаемым местоположением в Индии). Тестирование геолокации в Selenium является обязательным для веб-сайтов (или веб-приложений), ориентированных на глобальную аудиторию.
Поскольку кросс-браузерное тестирование проводится на Selenium 4 Grid, вместо Desired Capabilities (которые используются в Selenium 3) используются соответствующие опции браузера (т.е. ChromeOptions).
ChromeOptions capabilities = new ChromeOptions();
capabilities.setCapability("browserName", "chrome");
capabilities.setCapability("version", "latest");
capabilities.setCapability("platform", "Windows 10");
capabilities.setCapability("build", "[Java] Page Factory Demo on LambdaTest");
capabilities.setCapability("name", "[Java] Page Factory Demo on LambdaTest");
capabilities.setCapability("geoLocation","IN");
Создается новый экземпляр Remote WebDriver с возможностями браузера & OS, установленными в предыдущем шаге. Затем комбинация имени пользователя и ключа доступа используется для доступа к LambdaTest Selenium Grid (т.е. @hub.lambdatest.com/wd/hub).
driver = new RemoteWebDriver(new URL("https://" + username + ":" + accesskey + gridURL), capabilities);
Созданный экземпляр Remote ChromeDriver используется через объекты классов Page (которые были созданы в пакете com.pagefact.pages). Инициализация Remote ChromeDriver является частью метода testSetUp(), реализованного под аннотацией @BeforeClass TestNG. Аннотации TestNG в Selenium помогают построить более надежный фреймворк и предоставляют дополнительную информацию о соответствующем классе или методе.
@BeforeClass
public void testSetUp() throws MalformedURLException
{
В этой демонстрации Page Factory в Selenium мы создали единственный метод тестирования (т.е. test_signupOnLambdaTest), реализованный под аннотацией @test. Вы также можете использовать параметризованный тест TestNG для запуска одного и того же теста (или отдельных тестов) в различных комбинациях входных данных (например, в различных браузерах и платформах).
@Test
public void test_signupOnLambdaTest() throws InterruptedException
{
Сначала мы создаем объект класса страницы HomePage. Затем хэндл удаленного WebDriver передает аргумент экземпляру каждого объекта страницы, поскольку один и тот же экземпляр WebDriver должен использоваться во всех методах тестирования.
Метод clickOnStartTestingButton() класса HomePage вызывается для выполнения щелчка на кнопке «Начать бесплатное тестирование».
HomePage home = new HomePage(driver);
home.clickOnStartTestingButton();
Если предыдущий шаг выполнен успешно, мы переходим на страницу ‘Account SignUp’. Здесь мы создаем экземпляр класса страницы SignUpPage, после чего проверяем, содержит ли заголовок страницы ‘Signup for Free’.
SignUpPage signup = new SignUpPage(driver);
Assert.assertTrue(signup.isLTPageOpen());
Последний шаг к созданию аккаунта на LambdaTest включает создание экземпляра объекта страницы CreateAccountPage. Здесь мы передаем соответствующие данные (например, полное имя, электронную почту, номер телефона и т.д.) на страницу создания аккаунта.
Соответствующие методы [например, setName(), setEmail(), setAccount_password() и т.д.) вызываются для заполнения данными соответствующих Web-элементов на странице.
CreateAccountPage accountPage = new CreateAccountPage(driver);
accountPage.setName("Page Factory Testing");
accountPage.setEmail("pagefactorytesting123@gmail.com");
accountPage.setAccount_password("password123");
accountPage.setPhone_number("911234567891");
accountPage.setDesignation("Manager");
accountPage.setCompanySize("10000+");
accountPage.clickAcceptTCButton();
Тест считается пройденным, если на экране появляется страница ‘Verify your email’.
if (accountPage.isVerifyPageOpen())
{
System.out.println("Email address verification page is openn");
}
Запуск фабрики страниц в демонстрационном тесте Selenium
Поскольку мы не реализовали параметризованный тест TestNG, testng.xml содержит минимум информации для вызова тестов из пакета com.pagefact.tests.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="All Test Suite">
<test verbose="2" preserve-order="true" name="Page Factory Demo">
<classes>
<class name="com.pagefact.tests.SignUpOnLTTest">
<methods>
<include name="test_signupOnLambdaTest"/>
</methods>
</class>
</classes>
</test>
</suite>
Поскольку тесты выполняются на облачной Selenium Grid на LambdaTest, перейдите на LambdaTest Automation Dashboard, чтобы проверить статус выполнения теста. Как показано ниже, тест выполнен успешно.
Примечание — SHA512 Hash calculator — эта программа помогает определить целостность данных и аутентификацию хэша.
Завершение
Источник
Page Factory и Page Object Model (POM) — это шаблоны проектирования, которые облегчают инженерам QA сопровождение и повторное использование кода более эффективным способом. Page Factory в Selenium предоставляет больше возможностей для POM благодаря поддержке важных аннотаций и методов, которые упрощают нахождение и инициализацию переменных веб-элементов.
В этом руководстве по Selenium Page Factory мы рассмотрели, как Page Factory в Selenium может эффективно использоваться в agile-проектах, поскольку классы Page Object можно повторно использовать в соответствующих наборах тестов, сокращая усилия по обслуживанию и внедрению. Кроме того, подобно POM, пользовательское взаимодействие абстрагируется от основной реализации теста, что позволяет легко адаптироваться к изменяющимся требованиям проекта.
Сообщите нам, как вы использовали Page Factory в тестовых наборах Selenium для ускорения доставки тестовых наборов.
Счастливого тестирования!