Получение списка открытых окон

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

Основы работы с окнами

Каждое окно или вкладка браузера имеет уникальный идентификатор — window handle. Этот идентификатор используется для переключения между окнами и управления их состоянием. В WebdriverIO методы для работы с окнами сосредоточены вокруг объектов browser и window.

Основные методы:

  • browser.getWindowHandle() — возвращает идентификатор текущего окна.
  • browser.getWindowHandles() — возвращает массив всех открытых окон.
  • browser.switchToWindow(handle) — переключает контекст на указанное окно.

Получение списка всех окон

Метод getWindowHandles() является ключевым для получения списка открытых окон:

const handles = await browser.getWindowHandles();
console.log('Открытые окна:', handles);

Результат метода — массив строк, каждая из которых представляет уникальный идентификатор окна. Порядок элементов в массиве соответствует порядку открытия окон в браузере.

Применение списка окон

Список идентификаторов используется для переключения контекста, проверки открытия новых окон и взаимодействия с ними. Например, при тестировании всплывающих окон (pop-ups) можно определить новое окно следующим образом:

const mainWindow = await browser.getWindowHandle(); // текущее окно
await $('button#openPopup').click();                // действие, открывающее новое окно

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

await browser.switchToWindow(popupWindow);
// действия в новом окне
await browser.closeWindow();  // закрытие всплывающего окна

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

Ключевые моменты:

  • Всегда сохраняется идентификатор исходного окна перед открытием нового.
  • После завершения работы с новым окном рекомендуется возвращаться в исходный контекст.

Фильтрация и работа с конкретными окнами

Иногда требуется определить окно по его свойствам, например, по заголовку (title) или URL. Для этого используется комбинация методов getTitle(), getUrl() и перебора списка идентификаторов:

const allWindows = await browser.getWindowHandles();
for (const handle of allWindows) {
    await browser.switchToWindow(handle);
    const title = await browser.getTitle();
    if (title.includes('Целевая страница')) {
        // действия в нужном окне
        break;
    }
}

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

Асинхронность и ожидания

WebdriverIO использует асинхронный API, поэтому все методы работы с окнами возвращают промисы. Для корректной работы с динамическими окнами важно использовать ожидания (waitUntil) перед обращением к новому окну, чтобы избежать ошибок из-за задержки открытия:

await browser.waitUntil(async () => {
    const handles = await browser.getWindowHandles();
    return handles.length > 1;
}, {
    timeout: 5000,
    timeoutMsg: 'Новое окно не открылось в течение 5 секунд'
});

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

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

  • Сохранять идентификатор основного окна перед любыми действиями, создающими новые окна.
  • Закрывать ненужные окна после выполнения теста, чтобы избежать утечек контекста.
  • Использовать фильтрацию по заголовку или URL, если открывается несколько окон с разными задачами.
  • Оборачивать переключение окон в ожидания, чтобы обеспечить стабильность тестов в асинхронной среде.

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