Selenium RC (Java): Основные операции в действии (Часть 3)

Часть 2

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

Отдельно стоит рассмотреть такой момент как работа Selenium-а с различными модальными окнами. В данном случае подразумеваются диалоги, которые инициируются вызовом функций вроде openDialog в JScript. В результате работы таких функций открывается новая веб-старница в отдельном модальном окне. Также, как правило подобные окна характеризуются наличием идентификатора.

Так вот, основная трудность заключается в том, что при работе Selenium-a все действия выполняются изначально над основным окном. Соответственно, при появлении нового окна все операции по-прежнему будут выполняться в старом окне. В результате, нам нужно как-то переключить Selenium на нужное окно, а после всех операций вернуться на главное.

Также, учитывая тот факт, что подобные модальные окна - это те же веб-страницы, то желательно дожидаться, когда они загрузятся прежде чем делать какие-то операции с элементами внутри страницы.

Теперь посмотрим, что у нас есть для того, чтобы нормально обрабатывать подобные ситуации.

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

Далее, перед тем как начать работать с элементами внутри появившегося диалога, мы должны перенести фокус на это окно, чтобы Selenium посылал команды конкретному окну. Для этого используется метод selectWindow. В качестве параметра ему надо указать имя данного модального диалога. Обычно оно указывается при вызове openDialog.

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

Но есть случаи, когда мы не можем получить имя данного окна. Либо его тяжело искать, либо оно динамическое. В-общем, нюансов может быть много, но это не повод считать подобные задачи невыполнимыми. В ряде случаев удобно пользоваться различными приемами.

Когда открывается новое модальное окно, то в списке окон, которые видит Selenium оно находится на последнем месте. Соответственно, нам надо получить список всех доступных окон, а потом выбрать последнее. Для этих целей нам помогут методы getAllWindows или getAllWindowNames. Они возвращают список имен или идентификаторов окон, которые видит Selenium. В результате, прежде чем работать с модальным окном, мы должны выполнить инструкции вида:

{syntaxhighlighter brush: java;fontsize: 100; first-line: 1; }String[] winIDs = selenium.getAllWindows(); selenium.selectWindow( winIDs[ winIDs.length - 1 ] );{/syntaxhighlighter}

Аналогично делается выбор окна по имени с использованием getAllWindowNames.

Более надежно будет еще дождаться появления нового окна. В этом случае, мы в течение некоторого времени сканируем список открытых окон и ждем, пока их количество не увеличится на единицу. Это нужно для того, чтобы синхронизировать работу приложения и Selenium-а. Файтически это аналог waitForPopup, только более универсальный, хотя и более громоздкий. Выглядит это примерно так:

{syntaxhighlighter brush: java;fontsize: 100; first-line: 1; }String[] winIDs = selenium.getAllWindows(); int origCount = winIDs.length; // Scan original number of available windows


// Here we make operation activating new window

int maxTries = 60; // Specify the number of iterations while waiting for new window

for( int i = 0 ; i < maxTries ; i++ ){
winIDs = selenium.getAllWindows();
if( winIDs.length > origCount ){
break; // If the number of open windows becomes greater than before we exit the loop
}
}
selenium.selectWindow( winIDs[ winIDs.length - 1 ] );{/syntaxhighlighter}

Местами, этот код можно упростить или вынести в отдельный метод/функцию.

Это были основные подходы к работе с модальными HTML окнами. Аналогичный подход применим, если мы имитируем действие, открывающее страницу в новом окне.

Помимо этого, есть случаи, когда обычным способом открыть новое окно не получается. В частности, IE в этом плане новые окна (особенно модальные) отлавливает плохо или же ни id, ни имени у появляющегося окна нет. Как вариант, можно воспользоваться методом openWindow. Но для этого нужно уметь вычислить точный URL открываемой страницы.

Основным преимуществом данного подхода является то, что мы сами можем задать ID данного окна и контролировать его внутри кода тестов. Тем не менее, подобный прием является скорее обходным.

Часть 2