Что такое PageObject и PageFactory?qa-41

Page Object Pattern

Определение

Паттерн проектирования, который инкапсулирует работу с элементами веб-страницы в отдельный класс.

Основные принципы

  1. Инкапсуляция логики работы со страницей
  2. Повторное использование кода
  3. Упрощение поддержки тестов

Пример реализации

public class LoginPage {
    private WebDriver driver;

    // Локаторы элементов
    By usernameField = By.id("username");
    By passwordField = By.id("password");
    By submitButton = By.id("login-btn");
    By errorMessage = By.cssSelector(".error");

    public LoginPage(WebDriver driver) {
        this.driver = driver;
    }

    // Методы для взаимодействия со страницей
    public void enterUsername(String username) {
        driver.findElement(usernameField).sendKeys(username);
    }

    public void enterPassword(String password) {
        driver.findElement(passwordField).sendKeys(password);
    }

    public void clickSubmit() {
        driver.findElement(submitButton).click();
    }

    public boolean isErrorDisplayed() {
        return driver.findElement(errorMessage).isDisplayed();
    }

    // Комбинированный метод
    public HomePage loginAs(String username, String password) {
        enterUsername(username);
        enterPassword(password);
        clickSubmit();
        return new HomePage(driver);
    }
}

Page Factory

Определение

Расширение Page Object, предоставляемое Selenium WebDriver для упрощения инициализации элементов страницы.

Ключевые особенности

  1. Ленивая инициализация элементов (поиск только при обращении)
  2. Аннотации для удобного описания элементов
  3. Автоматическая инициализация через initElements()

Пример использования

public class LoginPage {
    @FindBy(id = "username")
    private WebElement usernameField;

    @FindBy(id = "password")
    private WebElement passwordField;

    @FindBy(id = "login-btn")
    private WebElement submitButton;

    @FindBy(css = ".error")
    private WebElement errorMessage;

    public LoginPage(WebDriver driver) {
        PageFactory.initElements(driver, this);
    }

    public void login(String username, String password) {
        usernameField.sendKeys(username);
        passwordField.sendKeys(password);
        submitButton.click();
    }
}

Сравнение подходов

Критерий Классический Page Object Page Factory
Инициализация Ручная в конструкторе Автоматическая через аннотации
Синтаксис Явный поиск элементов Аннотации + делегирование
Гибкость Больше контроля Меньше кода
Производительность Быстрее (элементы инициализируются сразу) Медленнее (ленивая загрузка)

Лучшие практики

Для Page Object:

  1. Один класс = одна страница/компонент
  2. Возвращать другие PageObjects при навигации
  3. Не включать ассерты в PageObject

Для Page Factory:

  1. Использовать AjaxElementLocatorFactory для динамических элементов
PageFactory.initElements(new AjaxElementLocatorFactory(driver, 10), this);
  1. Комбинировать аннотации:
@FindBy(id = "username")
@CacheLookup  // Кэшировать найденный элемент
private WebElement usernameField;

Современные альтернативы

1. Лямбда-подход

private Component usernameField = driver -> driver.findElement(By.id("username"));

2. Компонентный подход

public class Button {
    private By locator;

    public Button(By locator) { this.locator = locator; }

    public void click(WebDriver driver) {
        driver.findElement(locator).click();
    }
}

Резюмируем

Page Object - это:

  • Основной паттерн организации автотестов
  • Инкапсуляция логики работы со страницей
  • Улучшение читаемости и поддерживаемости

Page Factory - это:

  • Расширение PageObject в Selenium
  • Упрощение работы с элементами через аннотации
  • Ленивая инициализация элементов

Что выбрать:

  • Для сложных проектов - классический PageObject
  • Для быстрого прототипирования - PageFactory
  • Для современных фреймворков - компонентный подход

Правильно реализованный Page Object/Factory:

  • Уменьшает дублирование кода
  • Делает тесты устойчивее к изменениям
  • Упрощает поддержку тестовой базы