Ответ
Page Factory — это встроенный в Selenium WebDriver паттерн проектирования (реализация Page Object), который использует аннотации @FindBy для декларативного описания веб-элементов и метод PageFactory.initElements() для их "ленивой" инициализации.
Основная цель: Уменьшение boilerplate-кода и повышение читаемости Page Object-классов.
Пример реализации на Java:
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class LoginPage {
// Элементы объявляются с аннотацией @FindBy
@FindBy(id = "username")
private WebElement usernameField;
@FindBy(name = "password")
private WebElement passwordField;
@FindBy(css = "button[type='submit']")
private WebElement loginButton;
@FindBy(className = "error-message")
private WebElement errorMessage;
// Конструктор инициализирует все элементы
public LoginPage(WebDriver driver) {
PageFactory.initElements(driver, this);
}
// Методы страницы
public void login(String user, String pass) {
usernameField.sendKeys(user);
passwordField.sendKeys(pass);
loginButton.click();
}
public String getErrorMessage() {
return errorMessage.getText();
}
}
Преимущества с точки зрения тестирования:
- Ленивая загрузка (Lazy Load): Элементы ищутся в DOM только при первом обращении к ним (например, при вызове
sendKeys()), а не в момент вызоваinitElements. Это ускоряет инициализацию страницы. - Читаемость и поддержка: Локаторы собраны в одном месте вверху класса.
- Сокращение кода: Не нужно писать
driver.findElement(By.id(...))для каждого элемента.
Недостатки и подводные камни:
- StaleElementReferenceException: Поскольку элементы кэшируются после первой находки, при обновлении DOM (AJAX, SPA) ссылка может устареть. Решение — использовать
PageFactory.initElementsповторно или обновлять элементы в методах. - Меньшая гибкость: Сложнее работать с динамическими локаторами, которые вычисляются во время выполнения.