Page Object для модальных окон

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

Создание Page Object для модального окна

Модальное окно обычно состоит из нескольких элементов: заголовка, тела с контентом и кнопок управления (например, «Закрыть», «Подтвердить»). Структура Page Object может включать локаторы этих элементов и методы взаимодействия с ними.

Пример структуры на Jav * aScript:

class ModalWindow {
    constructor() {
        this.modalRoot = element(by.css('.modal'));
        this.header = this.modalRoot.element(by.css('.modal-header'));
        this.body = this.modalRoot.element(by.css('.modal-body'));
        this.closeButton = this.modalRoot.element(by.css('.close'));
        this.confirmButton = this.modalRoot.element(by.css('.confirm'));
    }

    async isDisplayed() {
        return await this.modalRoot.isPresent() && await this.modalRoot.isDisplayed();
    }

    async getHeaderText() {
        return await this.header.getText();
    }

    async getBodyText() {
        return await this.body.getText();
    }

    async clickClose() {
        await this.closeButton.click();
        await browser.wait(async () => !(await this.isDisplayed()), 5000);
    }

    async clickConfirm() {
        await this.confirmButton.click();
        await browser.wait(async () => !(await this.isDisplayed()), 5000);
    }
}

module.exports = new ModalWindow();

Особенности работы с модальными окнами

  1. Ожидание появления и исчезновения окна Модальные окна могут появляться с задержкой после определенного действия. Необходимо использовать browser.wait с условием на отображение (isDisplayed) или присутствие (isPresent), чтобы избежать ошибок типа ElementNotVisibleError.

  2. Стабильность локаторов Часто модальные окна генерируются динамически, поэтому стоит использовать устойчивые локаторы, такие как CSS-классы или уникальные атрибуты (data-*). Избегать локаторов по индексу или порядку появления, так как это делает тесты хрупкими.

  3. Методы для взаимодействия Все действия с модальным окном должны инкапсулироваться внутри Page Object. Например, закрытие, подтверждение или ввод текста в поля должны быть методами класса. Это упрощает повторное использование и повышает читаемость тестов.

  4. Проверка состояния Для модальных окон важно проверять не только действия, но и их состояние: отображается ли окно, корректно ли отобразился текст, активны ли кнопки. Методы isDisplayed и getText помогают реализовать эти проверки.

Применение в тестах

Page Object для модального окна используется следующим образом:

const modal = require('./modalWindow');

describe('Тест модального окна', () => {
    it('Должно открываться и закрываться корректно', async () => {
        await element(by.id('openModalButton')).click();
        expect(await modal.isDisplayed()).toBe(true);

        expect(await modal.getHeaderText()).toEqual('Подтверждение действия');
        expect(await modal.getBodyText()).toContain('Вы уверены, что хотите продолжить?');

        await modal.clickConfirm();
        expect(await modal.isDisplayed()).toBe(false);
    });
});

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

  • Если приложение имеет несколько типов модальных окон, рекомендуется создавать отдельные классы для каждого типа, наследуя общие методы из базового класса BaseModal.
  • Для сложных модальных окон с формами и множеством интерактивных элементов стоит добавлять методы для ввода данных и проверки ошибок.
  • Использование async/await позволяет писать тесты линейно, что повышает читаемость и снижает вероятность ошибок синхронизации.

Интеграция с другими Page Object

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

class DashboardPage {
    constructor() {
        this.openModalButton = element(by.id('openModalButton'));
    }

    async openModal() {
        await this.openModalButton.click();
        const modal = require('./modalWindow');
        await browser.wait(async () => await modal.isDisplayed(), 5000);
        return modal;
    }
}

module.exports = new DashboardPage();

Такой подход позволяет вызывать модальное окно в тестах через страницу и работать с ним через отдельный Page Object, обеспечивая строгую разделенность логики.