Работа с confirm диалогами

Confirm диалоги — это встроенные модальные окна браузера, которые запрашивают у пользователя подтверждение действия с помощью кнопок «OK» и «Отмена». В веб-приложениях они часто используются для подтверждения удаления данных, выхода из аккаунта или других критических операций. Protractor предоставляет средства для управления такими диалогами через объект browser.switchTo().alert().


Перехват и управление confirm диалогом

Confirm диалог создаётся методом window.confirm() на стороне клиента. При появлении такого окна стандартный DOM больше не доступен до тех пор, пока пользователь не примет или не отклонит диалог. В Protractor для работы с confirm диалогами применяется Alert API, который включает методы:

  • accept() — подтверждение действия (эквивалент кнопки «OK»)
  • dismiss() — отклонение действия (эквивалент кнопки «Отмена»)
  • getText() — получение текста диалога

Пример базового сценария:

it('должен подтвердить действие через confirm', async () => {
    await element(by.id('deleteButton')).click(); // вызов confirm
    const alertDialog = await browser.switchTo().alert();
    const alertText = await alertDialog.getText();
    expect(alertText).toContain('Вы действительно хотите удалить элемент?');
    await alertDialog.accept(); // нажимаем OK
});

В этом примере:

  1. Выполняется клик по кнопке, которая вызывает confirm.
  2. С помощью browser.switchTo().alert() создаётся объект диалога.
  3. Проверяется текст сообщения для уверенности, что диалог правильный.
  4. Подтверждается действие через accept().

Для отрицательного сценария:

it('должен отменить действие через confirm', async () => {
    await element(by.id('deleteButton')).click();
    const alertDialog = await browser.switchTo().alert();
    await alertDialog.dismiss(); // нажимаем Отмена
});

Асинхронная природа работы с confirm

Все методы Alert API возвращают промисы, поэтому в Protractor 5.x и выше рекомендуется использовать async/await. Это предотвращает неожиданные ошибки, когда действия выполняются до того, как диалог появился.

const alertDialog = await browser.switchTo().alert();
const text = await alertDialog.getText();
await alertDialog.accept();

Без await существует риск того, что тест завершится до обработки confirm, особенно на медленных сетях или при работе с динамическими элементами.


Проверка наличия confirm

Иногда требуется определить, появился ли confirm, прежде чем его принимать или отклонять. Для этого можно использовать конструкцию с try/catch:

try {
    const alertDialog = await browser.switchTo().alert();
    await alertDialog.accept();
} catch (e) {
    if (e.name === 'NoSuchAlertError') {
        console.log('Диалог не появился');
    } else {
        throw e;
    }
}

Это особенно полезно для условных сценариев, где confirm может появляться не всегда.


Мокирование confirm через браузер

Для более контролируемого тестирования иногда удобнее переопределять поведение window.confirm в браузере. Это позволяет симулировать нажатие «OK» или «Отмена» без появления настоящего диалога:

await browser.executeScript("window.confirm = function(){ return true; }"); // всегда OK
await element(by.id('deleteButton')).click();

Для имитации отказа:

await browser.executeScript("window.confirm = function(){ return false; }"); // всегда Отмена
await element(by.id('deleteButton')).click();

Такой подход позволяет полностью исключить зависимость от модальных окон при массовом тестировании.


Отладка и логирование

Confirm диалоги могут влиять на стабильность тестов, если их текст меняется динамически. Важно всегда логировать текст диалога для диагностики:

const alertDialog = await browser.switchTo().alert();
const alertText = await alertDialog.getText();
console.log(`Текст confirm: ${alertText}`);
await alertDialog.accept();

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


Рекомендации по использованию

  1. Всегда проверять текст confirm перед accept() или dismiss().
  2. Использовать async/await для предотвращения гонки промисов.
  3. Для массовых автоматизированных тестов предпочтительно мокировать window.confirm.
  4. Логировать действия с диалогами для облегчения отладки.
  5. Обрабатывать исключения NoSuchAlertError, чтобы тест не падал, если диалог не появился.

Работа с confirm диалогами в Protractor требует внимательности к асинхронности и стабильности тестов. Использование методов Alert API вместе с мокированием диалогов позволяет создавать надежные и воспроизводимые сценарии.