Закрытие окон

В автоматизированном тестировании на JavaScript с использованием Protractor работа с несколькими окнами браузера является одной из часто встречающихся задач. В веб-приложениях часто открываются новые вкладки или всплывающие окна, которые необходимо корректно закрыть, чтобы тесты выполнялись стабильно и не оставляли «зависших» сессий.

Получение дескрипторов окон

Каждое окно или вкладка в браузере имеет уникальный window handle. Для работы с ними используются методы getWindowHandle() и getAllWindowHandles().

// Получение текущего окна
const mainWindowHandle = await browser.getWindowHandle();

// Получение всех открытых окон
const allWindowHandles = await browser.getAllWindowHandles();

Важно: getWindowHandle() возвращает строку с идентификатором текущего окна, а getAllWindowHandles() — массив строк для всех окон, включая текущее.

Переключение между окнами

Чтобы закрыть нужное окно, сначала необходимо переключиться на него. Для этого применяется метод switchTo().window(handle):

await browser.switchTo().window(allWindowHandles[1]); // Переключение на второе окно

После переключения все команды element(), browser.get() и т.д. будут выполняться в контексте выбранного окна.

Закрытие окна

Метод close() закрывает текущее окно браузера.

await browser.close();

Если закрывается не основное окно, важно после закрытия переключиться обратно на основное:

await browser.switchTo().window(mainWindowHandle);

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

Работа с несколькими окнами

Часто в приложениях требуется закрыть все дополнительные окна, оставив основное. Для этого удобно использовать цикл:

const mainWindow = await browser.getWindowHandle();
const handles = await browser.getAllWindowHandles();

for (const handle of handles) {
  if (handle !== mainWindow) {
    await browser.switchTo().window(handle);
    await browser.close();
  }
}

// Возврат в основное окно
await browser.switchTo().window(mainWindow);

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

Закрытие окон с ожиданием

Иногда новые окна загружаются с задержкой. Для корректной работы стоит использовать ожидания (ExpectedConditions):

const EC = protractor.ExpectedConditions;
await browser.wait(async () => (await browser.getAllWindowHandles()).length > 1, 5000);

const allWindows = await browser.getAllWindowHandles();
await browser.switchTo().window(allWindows[1]);
await browser.close();
await browser.switchTo().window(allWindows[0]);

Это позволяет избежать ошибок, связанных с тем, что окно еще не открылось на момент выполнения команды закрытия.

Практические рекомендации

  • Не закрывать основное окно, пока не завершены действия с дополнительными вкладками.
  • Использовать циклы и условия, если количество окон динамическое.
  • Применять ожидания для новых окон, чтобы тесты были стабильными.
  • После закрытия всех дополнительных окон всегда возвращать контекст на основное окно.
  • Для модальных диалогов и alert-окон методы close() не применяются, вместо этого используются browser.switchTo().alert().accept() или dismiss().

Пример комплексного сценария

const mainWindow = await browser.getWindowHandle();

// Открытие нового окна через клик
await element(by.id('openWindowButton')).click();

// Ожидание появления второго окна
await browser.wait(async () => (await browser.getAllWindowHandles()).length > 1, 5000);

const handles = await browser.getAllWindowHandles();
for (const handle of handles) {
  if (handle !== mainWindow) {
    await browser.switchTo().window(handle);
    // Здесь можно выполнить проверки или взаимодействия
    await browser.close();
  }
}

await browser.switchTo().window(mainWindow);

Этот подход обеспечивает безопасное закрытие всех дополнительных окон и поддержание стабильного контекста теста.