Методы Page Objects

Page Object — это паттерн проектирования, позволяющий создавать абстракцию пользовательских интерфейсов для автоматизированного тестирования. В Protractor Page Objects упрощают поддержку тестов, делают их более читаемыми и структурированными, минимизируя дублирование кода и повышая стабильность тестовой автоматизации.


Структура Page Object

Стандартная структура Page Object включает:

  1. Селекторы элементов — локаторы для поиска элементов на странице.
  2. Методы взаимодействия — функции, которые инкапсулируют действия с элементами.
  3. Методы получения данных — функции, возвращающие значения из элементов страницы.
  4. Навигационные методы — переходы между страницами или состояниями приложения.

Пример базового шаблона Page Object:

class LoginPage {
    constructor() {
        this.usernameInput = element(by.id('username'));
        this.passwordInput = element(by.id('password'));
        this.loginButton = element(by.buttonText('Login'));
        this.errorMessage = element(by.css('.error-message'));
    }

    async enterUsername(username) {
        await this.usernameInput.clear();
        await this.usernameInput.sendKeys(username);
    }

    async enterPassword(password) {
        await this.passwordInput.clear();
        await this.passwordInput.sendKeys(password);
    }

    async clickLogin() {
        await this.loginButton.click();
    }

    async getErrorMessageText() {
        return await this.errorMessage.getText();
    }
}

module.exports = new LoginPage();

Основные методы взаимодействия

1. Ввод текста

Используется метод sendKeys() для заполнения полей формы. Для удобства ввод часто оборачивают в отдельные методы Page Object:

async enterText(element, text) {
    await element.clear();
    await element.sendKeys(text);
}

2. Клик по элементу

Для кнопок и ссылок применяются методы click():

async clickElement(element) {
    await element.click();
}

3. Получение текста и атрибутов

Часто требуется проверять видимый текст или значения атрибутов элементов:

async getText(element) {
    return await element.getText();
}

async getAttribute(element, attribute) {
    return await element.getAttribute(attribute);
}

4. Работа с чекбоксами и радиокнопками

Применяется проверка состояния isSelected() и управление состоянием через click():

async setCheckbox(element, shouldCheck) {
    const isChecked = await element.isSelected();
    if (isChecked !== shouldCheck) {
        await element.click();
    }
}

Методы ожидания

Protractor тесно интегрирован с ExpectedConditions, что позволяет создавать надёжные методы ожидания:

const EC = protractor.ExpectedConditions;

async waitForElementVisible(element, timeout = 5000) {
    await browser.wait(EC.visibilityOf(element), timeout, 'Элемент не появился вовремя');
}

async waitForElementClickable(element, timeout = 5000) {
    await browser.wait(EC.elementToBeClickable(element), timeout, 'Элемент не кликабелен вовремя');
}

В Page Object методы ожидания инкапсулируются для каждого элемента или действия, что делает тесты более устойчивыми.


Методы навигации

Для перехода между страницами можно создавать специальные методы:

async navigateToLogin() {
    await browser.get('/login');
}

Методы навигации обеспечивают изолированность логики тестов от URL приложения, что упрощает поддержку при изменении маршрутов.


Использование вспомогательных функций

Для больших проектов полезно создавать универсальные методы, которые можно переиспользовать:

  • clickElement(element) — универсальный клик.
  • enterText(element, text) — ввод текста в любое поле.
  • getElementText(element) — получение текста любого элемента.
  • waitForElement(element) — ожидание видимости элемента.

Это снижает дублирование кода и делает Page Objects более компактными.


Стратегии организации методов

  1. По действиям пользователя — методы отражают реальные пользовательские сценарии (например, loginAsUser()).
  2. По элементам страницы — методы сгруппированы вокруг конкретных элементов (clickLoginButton(), getErrorMessageText()).
  3. Смешанный подход — сочетание действий и элементов, применяемое для крупных интерфейсов.

Асинхронность и использование async/await

Все методы Page Object, взаимодействующие с элементами, должны быть асинхронными, так как Protractor выполняет операции с браузером через промисы:

async performLogin(username, password) {
    await this.enterUsername(username);
    await this.enterPassword(password);
    await this.clickLogin();
}

Это позволяет тесту оставаться читаемым и последовательным, избегая цепочек then() и колбэков.


Пример комплексного метода Page Object

async loginWithInvalidCredentials(username, password) {
    await this.enterUsername(username);
    await this.enterPassword(password);
    await this.clickLogin();
    await this.waitForElementVisible(this.errorMessage);
    return await this.getErrorMessageText();
}

Такой метод объединяет несколько действий и проверку результата, что делает тест коротким и понятным.


Рекомендации по поддержке Page Objects

  • Все методы должны инкапсулировать логику взаимодействия, не допуская прямых вызовов element() вне Page Object.
  • Не смешивать Page Object с логикой теста: проверка результатов должна оставаться в тестовом файле.
  • Использовать ожидания для всех динамических элементов, чтобы исключить нестабильность тестов.
  • Разбивать Page Objects на подстраницы или виджеты, если интерфейс большой.

Page Objects с правильно организованными методами повышают масштабируемость и надёжность автоматизированных тестов в Protractor, позволяя поддерживать сотни тестов без хаоса и дублирования кода.