Переключение контекста выполнения

WebdriverIO предоставляет гибкие возможности для управления контекстом выполнения тестов. Контекст определяет, с каким элементом или областью страницы происходит взаимодействие: основное окно браузера, iframe или мобильное приложение через WebDriver/ Appium. Корректное переключение контекста критически важно для надежного тестирования сложных веб-страниц и гибридных приложений.


Работа с окнами браузера

Каждое окно или вкладка браузера имеет свой уникальный идентификатор (windowHandle). WebdriverIO позволяет получить текущий идентификатор окна, переключиться на другое окно и управлять их количеством.

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

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

// Переключение на другое окно
await browser.switchToWindow(allWindows[1]);

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

  • getWindowHandle() возвращает строку с текущим идентификатором.
  • getWindowHandles() возвращает массив идентификаторов всех окон.
  • Переключение на закрытое или несуществующее окно вызывает исключение.

Переключение на iframe

Iframe создают отдельный контекст внутри страницы. Все действия внутри iframe требуют явного переключения контекста.

// Поиск iframe по селектору
const iframe = await $('#my-iframe');

// Переключение контекста на iframe
await browser.switchToFrame(iframe);

// Выполнение действий внутри iframe
await $('#button').click();

// Возврат в основной контекст страницы
await browser.switchToParentFrame();

Особенности работы с iframe:

  • switchToFrame() принимает элемент iframe или его индекс.
  • switchToParentFrame() возвращает контекст на уровень выше.
  • Можно использовать вложенные iframe, последовательно переключаясь на каждый уровень.

Контекст мобильных приложений (Appium)

В тестировании мобильных приложений через WebdriverIO используется концепция NATIVE_APP и WEBVIEW. Переключение между ними позволяет управлять нативными элементами и веб-контентом внутри приложения.

// Получение всех доступных контекстов
const contexts = await driver.getContexts();

// Переключение на WEBVIEW
await driver.switchContext('WEBVIEW_com.example.app');

// Действия в веб-контексте
await $('#login').setValue('user');

// Возврат в нативный контекст
await driver.switchContext('NATIVE_APP');

Особенности:

  • getContexts() возвращает массив доступных контекстов: NATIVE_APP и WEBVIEW_<package_name>.
  • Переключение на несуществующий контекст приведет к ошибке.
  • Для гибридных приложений необходимо корректно ожидать загрузку WEBVIEW перед взаимодействием.

Переключение между вкладками и окнами с разными доменами

WebdriverIO соблюдает политику одного источника (Same-Origin Policy) при работе с окнами разных доменов. Для успешного взаимодействия:

  • Переключение на окно с другим доменом допустимо.
  • Взаимодействие с элементами может быть ограничено кросс-доменными политиками браузера.
await browser.switchToWindow(allWindows[2]);
await browser.url('https://example.com');

Советы:

  • Всегда сохранять идентификатор исходного окна.
  • Использовать await browser.closeWindow() для закрытия лишних окон и возврата к основному.

Совмещение переключений

Часто тестовые сценарии требуют комбинации переключений между окнами, iframe и контекстами мобильного приложения. Для этого важно:

  1. Сохранять исходный контекст.
  2. Последовательно переключаться на нужный уровень.
  3. Возвращаться в исходный контекст после завершения действий.
const mainWindow = await browser.getWindowHandle();
const iframe = await $('#frame1');

await browser.switchToFrame(iframe);
await $('#submit').click();
await browser.switchToParentFrame();

await browser.switchToWindow(mainWindow);

Эта стратегия гарантирует стабильность тестов и предотвращает ошибки no such element из-за нахождения в неверном контексте.


Обработка ошибок при переключении контекста

Наиболее частые причины ошибок:

  • Некорректный идентификатор окна или контекста.
  • Попытка взаимодействия с элементом вне текущего контекста.
  • Задержки загрузки iframe или WEBVIEW.

Для их предотвращения рекомендуется:

  • Использовать ожидания (waitForExist, waitUntil) перед переключением.
  • Проверять наличие элемента после перехода в новый контекст.
  • Логировать контексты и идентификаторы окон для отладки.

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

  • Минимизировать количество переключений. Частые переходы замедляют тесты и увеличивают вероятность ошибок.
  • Явно сохранять исходный контекст. Это позволяет быстро восстановить состояние теста.
  • Использовать асинхронные ожидания. Особенно важно при работе с динамически загружаемыми iframe и WEBVIEW.
  • Разделять тесты по типу контекста. Веб-элементы и нативные элементы лучше тестировать отдельными сценариями для стабильности.

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