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

При автоматизации тестирования веб-приложений часто возникает необходимость работы с несколькими окнами или вкладками браузера. В Protractor для этого используется управление window handles — уникальными идентификаторами открытых окон. Понимание и правильное использование этих механизмов позволяет создавать надежные тесты для сложных сценариев.

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

Каждое открытое окно браузера имеет уникальный идентификатор, называемый window handle. Получить список всех доступных окон можно с помощью метода:

browser.getAllWindowHandles().then(function(handles) {
    console.log(handles);
});

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

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

Для переключения на конкретное окно используется метод browser.switchTo().window(handle):

browser.getAllWindowHandles().then(function(handles) {
    let newWindowHandle = handles[1]; // предположим, что это новое окно
    browser.switchTo().window(newWindowHandle);
});

После выполнения этой команды все последующие действия (click, sendKeys, getText и т.д.) будут применяться к новому окну.

Работа с новым окном

После переключения можно выполнять стандартные операции с элементами на странице:

element(by.css('.input-field')).sendKeys('Тестовые данные');
element(by.buttonText('Отправить')).click();

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

browser.getAllWindowHandles().then(function(handles) {
    let originalWindowHandle = handles[0];
    browser.switchTo().window(originalWindowHandle);
});

Закрытие окна и возврат к предыдущему

Если необходимо закрыть текущее окно и вернуться к предыдущему:

browser.close().then(function() {
    browser.getAllWindowHandles().then(function(handles) {
        browser.switchTo().window(handles[0]);
    });
});

Важно понимать, что после закрытия окна его window handle становится недействительным. Поэтому переключение следует делать только на существующее окно.

Ожидание открытия нового окна

При клике на элемент, который открывает новое окно, может потребоваться ожидание появления нового window handle. Для этого используется метод browser.wait:

let originalHandles;
browser.getAllWindowHandles().then(function(handles) {
    originalHandles = handles;
});

element(by.id('open-new-window')).click();

browser.wait(function() {
    return browser.getAllWindowHandles().then(function(handles) {
        return handles.length > originalHandles.length;
    });
}, 5000);

Этот код гарантирует, что новое окно появилось до выполнения дальнейших действий.

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

Если тест требует взаимодействия с несколькими окнами:

  1. Получить список всех window handles.
  2. Сохранять идентификаторы для каждого окна.
  3. При необходимости переключаться между окнами с помощью browser.switchTo().window(handle).

Пример:

browser.getAllWindowHandles().then(function(handles) {
    let mainWindow = handles[0];
    let secondWindow = handles[1];

    browser.switchTo().window(secondWindow);
    element(by.css('.confirm')).click();

    browser.switchTo().window(mainWindow);
    element(by.css('.status')).getText().then(console.log);
});

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

  • В большинстве современных браузеров новое окно часто открывается как вкладка. Механизм работы с window handles одинаков для окон и вкладок.
  • browser.getCurrentUrl() и browser.getTitle() возвращают информацию о текущем окне после переключения.
  • Любые операции без предварительного switchTo().window() будут выполняться в текущем активном окне.

Взаимодействие с alert и confirm

Alert, confirm и prompt не создают новые window handles, но требуют переключения контекста с помощью browser.switchTo().alert():

browser.switchTo().alert().accept();
browser.switchTo().alert().dismiss();
browser.switchTo().alert().getText().then(console.log);

Важно учитывать, что эти операции не связаны с окнами и не влияют на window handles.

Рекомендации при работе с окнами

  • Всегда хранить идентификаторы открытых окон, чтобы избежать ошибок переключения.
  • Проверять наличие нового окна через browser.wait, особенно при асинхронных операциях.
  • После закрытия окна немедленно переключаться на существующее, чтобы не получить исключение.
  • Использовать явное ожидание элементов в новом окне для стабильности тестов.

Переключение между окнами — ключевой навык при тестировании сложных веб-приложений с множественными вкладками, всплывающими окнами и динамическим контентом. Правильное управление window handles обеспечивает надежность и предсказуемость автоматизированных тестов.