← Назад к вопросам

Что такое Page Factory и зачем она нужна?

1.2 Junior🔥 161 комментариев
#Теория тестирования

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Page Factory в Selenium WebDriver

Page Factory — это паттерн (шаблон проектирования) в Selenium WebDriver, который реализует подход Page Object Model (POM) и предоставляет удобный механизм для инициализации элементов веб-страницы с помощью аннотаций @FindBy. Его основная цель — уменьшить boilerplate-код (повторяющийся код) и повысить читаемость тестов, позволяя автоматически находить элементы при их первом использовании.

Основная идея и преимущества

В классическом POM вы создаете класс, представляющий страницу, и в его конструктор явно инициализируете каждый элемент с помощью driver.findElement(By...). Page Factory берет эту ответственность на себя:

// Пример без Page Factory (классический POM)
public class LoginPage {
    private WebDriver driver;
    private WebElement usernameField;
    private WebElement passwordField;

    public LoginPage(WebDriver driver) {
        this.driver = driver;
        this.usernameField = driver.findElement(By.id("username"));
        this.passwordField = driver.findElement(By.name("password"));
    }
}
// Пример с использованием Page Factory
public class LoginPage {
    @FindBy(id = "username")
    private WebElement usernameField;

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

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

Ключевые преимущества:

  1. Упрощение кода: Инициализация всех элементов происходит одной строкой PageFactory.initElements(driver, this);. Не нужно писать множество driver.findElement.
  2. Ленивая загрузка (Lazy Initialization): Элементы не инициализируются сразу в конструкторе. WebDriver начинает поиск элемента только при первом обращении к полю класса. Это может повысить производительность, особенно для страниц с большим количеством элементов.
  3. Читаемость и поддержка: Локаторы элементов (id, name, xpath и т.д.) задаются прямо над полем с помощью аннотации @FindBy. Это делает класс Page Object более компактным и понятным.
  4. Поддержка динамических элементов и Ajax: Page Factory может работать с механизмом AjaxElementLocatorFactory, который периодически пытается найти элемент в течение заданного времени (например, 10 секунд), прежде чем выкинуть исключение NoSuchElementException. Это критически важно для современных динамических веб-приложений.
// Пример с AjaxElementLocatorFactory для ожидания появления элемента
public class DynamicPage {
    @FindBy(css = ".ajax-loaded-content")
    private WebElement dynamicContent;

    public DynamicPage(WebDriver driver) {
        // Элемент будет пытаться найтись каждые 500ms в течение 10 секунд
        PageFactory.initElements(new AjaxElementLocatorFactory(driver, 10), this);
    }
}

Как работает Page Factory внутри

Метод PageFactory.initElements() использует рефлексию (Java Reflection API) для анализа класса:

  • Он просматривает все поля класса, помеченные аннотацией @FindBy.
  • Для каждого такого поля создается "прокси" (proxy) объект, который замещает реальный WebElement.
  • При первом вызове любого метода на этом прокси-объекте (например, usernameField.sendKeys("test")), происходит вызов driver.findElement(...) с локатором из аннотации, и возвращается реальный найденный элемент.

Расширенные возможности аннотации @FindBy

@FindBy очень гибкая и поддерживает различные стратегии поиска:

// Комбинация нескольких стратегий
@FindBy(id = "submit", name = "submitBtn")
private WebElement submitButton;

// Поиск по XPath
@FindBy(xpath = "//div[@class='container']//input")
private WebElement complexElement;

// Поиск по нескольким элементам (список)
@FindBy(css = "table.results tr")
private List<WebElement> resultRows;

// Использование How и Using для явного указания стратегии
@FindBy(how = How.CSS, using = ".btn-primary")
private WebElement primaryButton;

Когда использовать Page Factory и основные ограничения

Использовать рекомендуется: для большинства проектов автоматизации веб-интерфейсов, где применяется Page Object Model. Это стандартный и эффективный подход.

Ограничения и особенности:

  • Неявная привязка к драйверу: После initElements элементы "связываются" с конкретным экземпляром WebDriver. Если вам нужно использовать тот же Page Object класс с другим драйвером, требуется повторная инициализация.
  • Прокси-объекты: Некоторые операции, например, прямое сравнение элементов (element1 == element2), могут работать неожиданно из-за прокси-механизма.
  • Инициализация в конструкторе: Важно вызывать initElements в конструкторе класса-страницы, обычно после получения драйвера.

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

В последних версиях Selenium 4 появилась поддержка относительных локаторов (Relative Locators), которые можно комбинировать с подходом Page Factory. Также многие фреймворки (например, Selenide для Java) предлагают свои более декларативные способы описания элементов, но Page Factory остается фундаментальным и широко распространенным инструментом в экосистеме Selenium.

Таким образом, Page Factory — это не отдельная библиотека, а важная часть Selenium WebDriver, которая реализует и оптимизирует паттерн Page Object Model, делая код тестов более чистым, поддерживаемым и адаптированным к динамическому поведению современных веб-приложений.

Что такое Page Factory и зачем она нужна? | PrepBro