Page Object Model паттерн

Page Object Model (POM) — это шаблон проектирования в автоматизации тестирования, который разделяет тесты и логику взаимодействия с элементами страницы. Главная цель POM — сделать тесты более читаемыми, поддерживаемыми и менее зависимыми от изменений интерфейса.

Принципы Page Object Model

  1. Разделение логики теста и интерфейса страницы Страница представляется отдельным объектом с методами, которые инкапсулируют взаимодействие с элементами. Тесты при этом используют только методы объекта, не обращаясь напрямую к локаторам.

  2. Инкапсуляция локаторов Все селекторы элементов хранятся в классе страницы. При изменении интерфейса необходимо править только Page Object, а тесты остаются неизменными.

  3. Переиспользование кода Методы страницы могут быть использованы в нескольких тестах, что снижает дублирование кода и облегчает поддержку.

  4. Повышение читаемости тестов Тест становится более «читаемым», поскольку описывает действия на уровне бизнес-логики, а не низкоуровневого взаимодействия с элементами.

Структура Page Object

Класс Page Object обычно содержит:

  • Локаторы элементовelement(by.css(...)), element(by.id(...)) и другие стратегии поиска.
  • Методы взаимодействия — клики, ввод текста, получение текста элементов.
  • Методы проверки состояния страницы — например, проверка отображения элемента или текущего URL.

Пример структуры Page Object на Protractor:

class LoginPage {
    constructor() {
        this.usernameInput = element(by.id('username'));
        this.passwordInput = element(by.id('password'));
        this.loginButton = element(by.css('button[type="submit"]'));
        this.errorMessage = element(by.css('.error'));
    }

    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 getErrorMessage() {
        return await this.errorMessage.getText();
    }
}

module.exports = new LoginPage();

Использование Page Object в тестах

Тест, использующий Page Object, становится компактным и понятным:

const loginPage = require('../pages/login.page');

describe('Login functionality', () => {
    it('should display error for invalid credentials', async () => {
        await loginPage.enterUsername('wrongUser');
        await loginPage.enterPassword('wrongPass');
        await loginPage.clickLogin();
        const error = await loginPage.getErrorMessage();
        expect(error).toBe('Invalid username or password');
    });
});

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

Организация проекта с Page Object

Для больших проектов рекомендуется создавать отдельную папку pages для всех Page Object. Внутри можно разделять страницы по функциональным областям, например:

/pages
    login.page.js
    dashboard.page.js
    settings.page.js

Тесты при этом располагаются в папке specs или tests и импортируют только нужные Page Object.

Рекомендации по написанию методов

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

Асинхронность и ожидания

Protractor работает с промисами, поэтому методы Page Object должны корректно использовать async/await. Это обеспечивает последовательное выполнение действий и предотвращает ошибки из-за того, что элемент еще не появился на странице.

Пример с ожиданием видимости элемента:

async clickLogin() {
    await browser.wait(protractor.ExpectedConditions.elementToBeClickable(this.loginButton), 5000);
    await this.loginButton.click();
}

Использование ожиданий делает тесты более стабильными, особенно на динамически загружаемых страницах.

Преимущества использования POM в Protractor

  • Снижение дублирования кода и упрощение поддержки.
  • Легкость внесения изменений при изменении интерфейса.
  • Улучшение читаемости и понимания тестов.
  • Возможность масштабирования тестового проекта за счет модульной структуры.

Page Object Model является стандартом в современном автоматизированном тестировании веб-приложений на Protractor и JavaScript, позволяя строить надежные и поддерживаемые тестовые фреймворки.