Обработка новых вкладок и окон

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


Получение идентификаторов окон

Каждое окно браузера имеет уникальный window handle — строковый идентификатор. Для работы с несколькими окнами используется метод:

const handles = await browser.getWindowHandles();
  • getWindowHandles() возвращает массив всех открытых окон браузера в текущей сессии.
  • Порядок окон в массиве соответствует последовательности их открытия.
  • Текущий активный контекст можно получить через:
const currentHandle = await browser.getWindowHandle();

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


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

Для взаимодействия с конкретной вкладкой используется метод switchToWindow:

await browser.switchToWindow(handle);
  • handle — это идентификатор окна из массива, полученного через getWindowHandles().
  • После переключения все команды WebdriverIO (клики, ввод текста, проверка элементов) будут выполняться в контексте выбранного окна.

Пример переключения на новую вкладку:

const originalWindow = await browser.getWindowHandle();

// Выполняем действие, открывающее новую вкладку
await $('a[target="_blank"]').click();

const allWindows = await browser.getWindowHandles();
const newWindow = allWindows.find(handle => handle !== originalWindow);

await browser.switchToWindow(newWindow);
await browser.pause(1000); // ожидание загрузки нового окна

Закрытие окон и возвращение в исходное

После завершения работы с новым окном его можно закрыть с помощью:

await browser.closeWindow();

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

await browser.switchToWindow(originalWindow);

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

const originalWindow = await browser.getWindowHandle();
await $('a[target="_blank"]').click();

const allWindows = await browser.getWindowHandles();
const newWindow = allWindows.find(handle => handle !== originalWindow);

await browser.switchToWindow(newWindow);
// действия в новой вкладке
await browser.closeWindow();

await browser.switchToWindow(originalWindow);
// действия в исходной вкладке

Работа с модальными окнами (alert, confirm, prompt)

Новые вкладки и окна часто сопровождаются браузерными модальными окнами. WebdriverIO поддерживает работу с ними через объект browser:

  • Принятие окна:
await browser.acceptAlert();
  • Отклонение окна:
await browser.dismissAlert();
  • Получение текста окна:
const alertText = await browser.getAlertText();
  • Ввод текста в prompt:
await browser.sendAlertText('Текст для prompt');
await browser.acceptAlert();

Советы по надежному управлению окнами

  1. Всегда сохранять исходное окно перед открытием новых вкладок.
  2. Использовать явное ожидание появления нового окна:
await browser.waitUntil(
    async () => (await browser.getWindowHandles()).length > 1,
    {
        timeout: 5000,
        timeoutMsg: 'Новое окно не открылось за 5 секунд'
    }
);
  1. Закрывать временные окна после завершения взаимодействия, чтобы не захламлять сессию.
  2. Использовать метод find() для выбора нужного окна, если открыто несколько вкладок одновременно.

Практические примеры

Открытие документации в новой вкладке и проверка заголовка:

const mainWindow = await browser.getWindowHandle();
await $('a[href="https://webdriver.io/docs"]').click();

await browser.waitUntil(
    async () => (await browser.getWindowHandles()).length > 1,
    { timeout: 5000 }
);

const allWindows = await browser.getWindowHandles();
const docWindow = allWindows.find(handle => handle !== mainWindow);

await browser.switchToWindow(docWindow);
const title = await browser.getTitle();
console.log(title); // выводим заголовок страницы

await browser.closeWindow();
await browser.switchToWindow(mainWindow);

Обработка множественных вкладок:

const mainWindow = await browser.getWindowHandle();

// открываем несколько вкладок
await $('a#link1').click();
await $('a#link2').click();

const handles = await browser.getWindowHandles();

// проходим по всем вкладкам, кроме основной
for (const handle of handles) {
    if (handle !== mainWindow) {
        await browser.switchToWindow(handle);
        console.log(await browser.getTitle());
        await browser.closeWindow();
    }
}

await browser.switchToWindow(mainWindow);

Итог

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