Управление алёртами и диалогами

Protractor — это инструмент для автоматизированного тестирования веб-приложений на основе Angular и других фреймворков. Одной из ключевых задач при тестировании является работа с модальными окнами браузера: alert, confirm и prompt. Эти диалоги блокируют выполнение скриптов, поэтому их необходимо корректно обрабатывать, чтобы тесты выполнялись стабильно.


Типы браузерных диалогов

  1. Alert — простое модальное окно с сообщением и кнопкой «OK».
  2. Confirm — диалог с вариантами «OK» и «Cancel», возвращает булево значение в зависимости от выбора пользователя.
  3. Prompt — диалог, в котором можно ввести текст, также содержит кнопки «OK» и «Cancel».

Все эти диалоги управляются через объект browser.switchTo().alert().


Переключение на диалог

Для работы с любым модальным окном необходимо сначала переключиться на него:

let alertDialog = browser.switchTo().alert();

После этого можно выполнять действия над диалогом: считывать текст, принимать или отклонять, вводить данные.


Получение текста из алёрта

Метод getText() позволяет получить сообщение, отображаемое в модальном окне:

alertDialog.getText().then(function(text) {
    console.log("Текст диалога: " + text);
});

В современном синтаксисе async/await:

let text = await alertDialog.getText();
console.log(`Текст диалога: ${text}`);

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

  • Принятие диалога (кнопка «OK»):
await alertDialog.accept();
  • Отклонение диалога (кнопка «Cancel», применимо для confirm и prompt):
await alertDialog.dismiss();

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


Ввод текста в prompt

Для диалогов с вводом текста используется метод sendKeys():

await alertDialog.sendKeys("Пример текста");
await alertDialog.accept();

sendKeys() позволяет автоматизировать сценарии, где необходимо вводить данные в модальные окна, например при подтверждении действий пользователя.


Обработка диалогов в ожиданиях

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

const EC = protractor.ExpectedConditions;

await browser.wait(EC.alertIsPresent(), 5000, "Диалог не появился за 5 секунд");
let alertDialog = browser.switchTo().alert();
await alertDialog.accept();

Использование ExpectedConditions.alertIsPresent() предотвращает ошибки, если диалог появляется с задержкой после действия на странице.


Примеры использования в тестах

  1. Alert с подтверждением действия:
it('должен принять алерт после нажатия кнопки', async () => {
    await element(by.id('deleteButton')).click();
    await browser.wait(protractor.ExpectedConditions.alertIsPresent(), 3000);
    let alertDialog = browser.switchTo().alert();
    expect(await alertDialog.getText()).toEqual('Вы уверены, что хотите удалить элемент?');
    await alertDialog.accept();
});
  1. Prompt с вводом текста:
it('должен ввести текст в prompt', async () => {
    await element(by.id('nameButton')).click();
    await browser.wait(protractor.ExpectedConditions.alertIsPresent(), 3000);
    let promptDialog = browser.switchTo().alert();
    await promptDialog.sendKeys('Тестовый пользователь');
    await promptDialog.accept();
});
  1. Confirm с отменой действия:
it('должен отклонить confirm', async () => {
    await element(by.id('logoutButton')).click();
    await browser.wait(protractor.ExpectedConditions.alertIsPresent(), 3000);
    let confirmDialog = browser.switchTo().alert();
    await confirmDialog.dismiss();
});

Обработка ошибок при работе с алертами

Частая ошибка — попытка взаимодействия с диалогом, которого нет на момент вызова. Чтобы избежать NoAlertPresentError, следует:

  • Использовать ExpectedConditions.alertIsPresent().
  • Ловить исключения через try/catch:
try {
    let alertDialog = await browser.switchTo().alert();
    await alertDialog.accept();
} catch (e) {
    console.log("Алерт не появился: " + e.message);
}

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

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

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