Первые шаги с Selenium RC. Руководство для новичков.

Установка Selenium RC

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

 Тут подробнее про инструменты семейства Selenium. Скачать последнею версию Selenium RC можно с официального сайта проекта. После скачивания Selenium RC нужно просто разархивировать файлы в нужную директорию. Также для запуска Selenium Server нужно установить Java Runtime Environment (JRE) версии 1.5 и выше. Обратите внимание, что версия JRE должна быть не ниже 1.5. Чтобы проверить, установлен ли у вас JRE и какая у него версия, нужно выполнить в консоли команду: java –version

После скачки Selenium RC и установки JRE можно запускать Selenium Server. Для этого открываем директорию в которой установлен Selenium Server, запускаем консоль (“Пуск/Выполнить/cmd”). В консоли нужно выполнить следующую команду: java -jar selenium-server.jar

java -jar selenium-server.jar [options] – формат запуска Selenium Server.

[options] в формате запуска сервера- это дополнительные опции запуска Selenium Server. Более подробную информацию о параметрах запуска Selenium Server можно узнать на сайте проекта. Для запуска Selenium Server рекомендую сразу же сделать .bat файл, так будет удобнее запускать сервер. Также Selenium Server можно запускать из кода тестов. После запуска сервера у вас на экране должно появится примерно такое окно:

Запуск Selenium RC с использованием прокси

При запуске Selenium-а происходит перезапись текущей конфигурации прокси-сервера (proxy). Это делается для того, чтобы Selenium Server использовался в качестве прокси, через который отправляются команды браузеру.  Если вам нужно использовать ваш прокси-сервер одновременно с Selenium Server (например, если доступ к тестируемому веб-приложению есть только через прокси-сервер), то для этого нужно указать дополнительные параметры запуска Selenium Server:

  • Dhttp.proxyHost – адрес (или IP), на котором находится прокси;
  • Dhttp.proxyPort – порт, через который происходит соединение;
  • Dhttp.proxyUser – имя пользователя, если требуется HTTP-прокси аутентификация;
  • Dhttp.proxyPassword – пароль пользователя, если требуется HTTP-прокси аутентификация.

Пример запуска Selenium Server с указанием прокси-сервера:

java -Dhttp.proxyHost=HOSTNAME -Dhttp.proxyPort=PORT -Dhttp.proxyUser=USER -Dhttp.proxyPassword=PASSWORD -jar selenium-server.jar

Установка профиля FireFox для запуска тестов на Selenium RC

По умолчанию, при запуске теста на Selenium RC, генерируется новой профиль браузера (это означает, что профиль браузера, на котором будут выполнять тесты имеет стандартные настройки). Иногда возникает необходимость запускать различные наборы тестов на различных профилях браузера, либо нужно просто настроить браузер под специфическое окружение. В таких случаях возникает вопрос – как управлять настройками профиля браузера при запуске тестов?

 Для начала нужно настроить профиль. Удобнее всего это делать в Profile Manager. Для запуска Profile Manager нужно в командной строке выполнить команду firefox.exe -ProfileManager. После этого откроется Profile Manager для браузера FireFox. Далее требуется выбрать существующий профиль или создать новый, и провести необходимые настройки.

После того как необходимый(ые) профили браузера будут готовы, нужно научить Selenium Server запускать требуемый нам профайл браузера. Делается это очень просто: в строке запуска Selenium Server укажем параметр firefoxProfileTemplate < dir >. Данным флагом мы помечаем, какой профиль необходимо использовать в тестах. Пример использования:

java -jar selenium-server.jar -firefoxProfileTemplate C:\SeleniumProfile

В данном примере происходит запуск Selenium Server, профиль браузера будет использоваться из директории C:\SeleniumProfile.

Для упорядочения работы, рекомендую хранить профиля браузера в специально отведенном каталоге. Также, при создании профиля браузера для запуска тестов, старайтесь не сильно “захламлять профиль”, т.е. не должно быть лишних дополнений, история должна быть почищена и т.д.

Пример авто-теста на Selenium RC (С#)

Перед написанием примера на Selenium RC c использованием C# выполним следующие действия:

Дополнительно рекомендую скачать и установить для Visual Studio NUnit . NUnit удобно использовать для организации тестов.

Далее открываем Visual Studio и создаем новый проект типа Class Library, создаем тестовый класс. Не забываем добавить в проект требуемые тестовые библиотеки – nmock.dll, nunit.core.dll, nunit. framework.dll, ThoughtWorks.Selenium.Core.dll, ThoughtWorks.Selenium.IntegrationTests.dll и ThoughtWorks.Selenium.UnitTests.dll. Подробный пример тут.

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

Шаги теста:

  • Открыть страницу https://bugscatcher.net/;
  • Проверить страницу на наличие текста “Bugs Catcher”;
  • Нажать по ссылке “Bugs Catcher”;
  • Проверить наличие элемента на странице для ввода текста поиска;
  • Произвести поиск по тексту “Пишем тесты на Selenium IDE”;
  • Проверить наличие ссылки на станице “Пишем тесты на Selenium IDE”.

С помощью Selenium IDE запишем требуемые шаги теста. Затем с помощью “Options/Format” попросим Selenium IDE отобразить тесты в формате C#. Сохраняем тест в студии, получаем примерно такой тест:

{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; }using System; using System.Text; using System.Text.RegularExpressions; using System.Threading; using NUnit.Framework; using Selenium;

namespace SeleniumTests
{
[TestFixture]
public class Untitled
{
private ISelenium selenium;
private StringBuilder verificationErrors;

    [SetUp]
    public void SetupTest()
    {
        selenium = new DefaultSelenium("localhost", 4444, "*chrome", "http://blogs.logicsoftware.net/");
        selenium.Start();
        verificationErrors = new StringBuilder();
    }

    [TearDown]
    public void TeardownTest()
    {
        try
        {
            selenium.Stop();
        }
        catch (Exception)
        {
            // Ignore errors if unable to close the browser
        }
        Assert.AreEqual("", verificationErrors.ToString());
    }

    [Test]
    public void TheUntitledTest()
    {
       selenium.Open("http://blogs.logicsoftware.net/");   //открытие страницы
       selenium.WaitForPageToLoad("60000"); //ждем загрузки страницы
       Assert.IsTrue(selenium.IsTextPresent("Bugs Catcher"));  //проверяем наличие текстового элемента "Bugs Catcher" на странице
       selenium.Click("link=Bugs Catcher"); //нажимаем на ссылку "Bugs Catcher"
       selenium.WaitForPageToLoad("60000"); //ждем загрузки страницы
       Assert.IsTrue(selenium.IsElementPresent("s")); //проверяем, присутствует ли на станице элемент ввода текста для  поиска
       selenium.Type("s", "Пишем тесты на Selenium IDE"); //вводим в текстовое поле значение "Пишем тесты на Selenium IDE"
       selenium.Click("searchsubmit");   //нажимаем на кнопку поиска (лупа)
       selenium.WaitForPageToLoad("60000");  //ждем загрузки страницы
       Assert.IsTrue(selenium.IsElementPresent("link=Пишем тесты на Selenium IDE"));  //проверяем, есть ли на странице результатов ссылка "Пишем тесты на  IDE"
    }
}

}{/syntaxhighlighter}

В коде теста не должно возникнуть особых проблем, но все же немного поясню. Код теста делится на явные блоки – в [SetUp]
создаем объект selenuim (он отвечает за работу с браузером), указываем
тестовые параметры – сервер, порт, тестовый браузер и урл приложения.

{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; } [SetUp]
public void SetupTest()
{
selenium = new DefaultSelenium(“localhost”, 4444, “*chrome”, “http://blogs.logicsoftware.net/”);
selenium.Start();
verificationErrors = new StringBuilder();
}{/syntaxhighlighter}

Teardown:

{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; }[TearDown]
public void TeardownTest()
{
try
{
selenium.Stop();
}
catch (Exception)
{
// Ignore errors if unable to close the browser
}
Assert.AreEqual(“”, verificationErrors.ToString());
}{/syntaxhighlighter}

Ну и непосредственно сам тест (производимые действия в тесте):

{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; }[Test]
public void TheUntitledTest()
{
selenium.Open(“https://bugscatcher.net/”); //открытие страницы
selenium.WaitForPageToLoad(“60000”); //ждем загрузки страницы
Assert.IsTrue(selenium.IsTextPresent(“Bugs Catcher”)); //проверяем наличие текстового элемента “Bugs Catcher” на странице
selenium.Click(“link=Bugs Catcher”); //нажимаем на ссылку “Bugs Catcher”
selenium.WaitForPageToLoad(“60000”); //ждем загрузки страницы
AssertTrue(selenium.IsElementPresent(“s”)); //проверяем, присутствует ли на станице элемент ввода текста для поиска
selenium.Type(“s”, “Пишем тесты на Selenium IDE”); //вводим в текстовое поле значение “Пишем тесты на Selenium IDE”
selenium.Click(“searchsubmit”); //нажимаем на кнопку поиска (лупа)
selenium.WaitForPageToLoad(“60000”); //ждем загрузки страницы
Assert.IsTrue(selenium.IsElementPresent(“link=Пишем тесты на Selenium IDE”)); //проверяем, есть ли на странице результатов ссылка “Пишем тесты на IDE”
}{/syntaxhighlighter}

Вот и написали простейший тест на Selenium RC (C#) :-)

Теперь попробуем запустить разработанный тест. Перед этим сбилдите проект в Visual Studio и проверьте, что нет ошибок. Если все хорошо идем дальше, если нет пишите в комменты или на email.

Для запуска тестов, нам понадобиться установить NUnit. NUnit – это вспомогательный framework для создания тестов. Рекомендую вам изучить возможности NUnit. Скачать NUnit можно по этой ссылке. После установки:

  • Запускаем Selenium Server;
  • Запускаем NUnit;
  • В NUnit выбираем “File -> Open Project…”;
  • И в диалоговом окне указываем путь к .dll нашего теста (…binDebugSeleniumTest.dll);
  • Загружаем проект и нажимает кнопку “Run” (ее будет трудно не заметить).

В результате данных, не хитрых, действий должен запуститься написанный нами ранее авто-тест на Selenium. Примерно так должно выглядеть окно NUnit-а с загруженным тестом:

Локаторы в Selenium

После изучения основных команд Selenium-а, для успешного создания тестов вам предстоит научиться работать с локаторами. Локатор (locator) – это строка, уникально идентифицирующая элемент веб-страницы. То есть, это тот механизм, с помощью которого ищутся элементы на странице. Для того, чтобы выполнить действие на странице Selenium-у необходимо знать, с каким элементом на странице ему нужно выполнить требуемое действие. Для этого и служат локаторы. Практически для всех команд первым параметром идет именно локатор, поэтому стоит сразу учиться правильно подбирать локаторы.

 Типы локаторов в Selenium:

  • id – в качестве локатора используется атрибут id (уникальный идентификатор) элемента страницы. Пример:

{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; }input ID="ctl00_cp1_form_tbxTaskNameFieldControl"{/syntaxhighlighter}

  • name – в качестве локатора используется атрибут name элемента страницы. Пример:

{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; }input type="text" class="text_box" id="ctl00_cp1_form_tbxDurationFieldControl" maxlength="5" value="35" NAME="ctl00cp1formtbxDurationFieldControl"{/syntaxhighlighter}

  • link – поиск ссылок с указанным текстом. Для локаторов данного типа не забываем использовать в командах формат объявления локатора: “link=SOME_LINK”. Пример:

{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; }<a target="_blank" href="http://www.easyprojects.net">Logic Software Inc.</a>{/syntaxhighlighter}

  • css – данный тип локаторов основан на описаниях таблиц стилей (CSS). Для локаторов данного типа не забываем использовать в командах формат объявления локатора: “css =SOME_CSS”. Пример вызова css локатора: "css=form iframe".
  • xpath – используется для поиска элемента по XPath выражению. Для локаторов данного типа не забываем использовать в командах формат объявления локатора: “XPath =SOME_XPath”. Пример XPath запроса: "XPath=//TR[5]/TD[@class='calendar-day-header' and position()=1]"
  • dom – поиск элемента происходит по DOM выражению, обращение к элементу происходит так же, как и в DHTML, используя DOM-структуру. Т.е. все конструкции – объявление, элемент, атрибут, значение и текстовое содержимое – могут быть представлены классами. А если у таких классов будут свойства коллекций, позволяющие хранить содержимое узла-потомка, мы сможем построить дерево объектов и полностью описать документ. Это и называется объектной моделью документа, или DOM. Данный тип локатора используется нечасто, так как обычно есть возможность использования более удобных локаторов.

Естественно, наиболее удобные для работы локаторы это: “id”, “name”, “link”, так как данные типы локаторов быстро подбираются – достаточно посмотреть html структуру документа. Также данные типы локаторов являются наиболее быстрыми в нахождении – скорость выполнения теста значительно возрастает по сравнению с “xpath” или “dom”. К сожалению, далеко не всегда данные локаторы используются активно разработчиками, в таких случаях нужно использовать поиск по локатором – “css”, “xpath”, “dom”.

Локаторы типа “css”, “xpath”, “dom” менее желательны – их иногда бывает достаточно трудно подобрать и оптимизировать. Скорость поиска данных типов локаторов на странице значительнее медленнее, чем для других локаторов.

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

  • Изучаем html страницы;
  • Высматриваем атрибуты “id” и “name” для элемента (если элемент является ссылкой используем “link”);
  • Изучаем дополнительные атрибуты элемента, например – “class”, “type” или текст и др. Дополнительные атрибуты можно использовать для построения “xpath”.
  • Смотрим на соседние (дочерние, родительские) элементы по иерархии. С помощью соседних элементов можно получить требуемый элемент.

В случаях, когда подобрать требуемый локатор очень сложно (у меня такие случаи были, например, если на странице много динамических JS элементов за которые сложно “зацепится” xpath-ом или “css”) бывает проще попросить разработчиков добавить в код страницы специальный атрибут, уникально идентифицирующий требуемый элемент страницы.

Вспомогательные инструменты при написании тестов на Selenium RC

Selenium RC обеспечивает работу только на уровне кода, ведь это только сервер, который выполняет команды, а также клиентская библиотека команд. Selenium RC взаимодействует со средой разработки, языком программирования, фрэймворком и библиотеками. При этом, Selenium RC не имеет никаких встроенных визуальных инструментов, помогающих проектировать тесты. Тут и возникает самая главная проблема – с помощью какого инструмента подбирать локаторы? Подбор локаторов является фактически самой распространенной задачей (а при автоматизации некоторых приложений – наиболее сложной и трудозатратной). Так что без вспомогательных инструментов, обойтись будет довольно сложно.

 Конечно, Selenium IDE будет служить нам самым главным и верным помощником. Не буду описывать всех прелестей данного инструмента, читайте тут. Связка инструментов Selenium RC + Selenium IDE является достаточно мощной (среди бесплатных инструментов данная связка является лидером).

Firebug – это расширение для браузеров Firefox, являющееся консолью, отладчиком, и DOM-инспектором JavaScript, DHTML, CSS, XMLHttpRequest. Firebug показывает в консоли вызвавшую ошибку функцию, стек вызовов функций, вызвавших эту ошибку. Он предупреждает, что CSS-правило или JavaScript-метод/свойство, которое вы пытаетесь использовать, не существует. Тут подробнее про Firebug. Главное, что дает нам данный инструмент при автоматизации на Selenium – это удобный просмотр HTML-кода страницы, что значительно упрощает подбор локаторов. Также отмечу, что данный инструмент очень полезен и при “ручном” тестировании веб-приложения.

Для подбора локаторов будут полезными еще два расширения для браузера Firefox XPather и XPath Checker. Исходя из названия понятно, что оба инструмента позволяют подбирать XPath-локаторы. С помощью данных программ получить XPath любого элемента страницы можно в два клика. Затем полученный (полный XPath элемента) можно (нужно) оптимизировать, что позволяют делать оба инструмента.

Web Developer Tools – еще один славный инструмент (опять же расширения для браузера Firefox). Web Developer умеет делать очень много полезных “штук”, но в первую очередь, будет полезным при исследовании свойств страниц приложения.

Браузер Firefox также предоставляет много других интересных и полезных расширений, которые могут помочь при разработке тестов. Я же перечислили только те, с которыми работаю. Отмечу, что именно Firefox на данный момент является самым удобным браузером для разработки веб-приложений.

Наиболее известные расширения для браузера Internet Explorer, которые способные помочь при написании тестов на Selenium: Firebug Lite , HttpWatch, Internet Explorer Developer Toolbar.

Управление сессией

Команды, позволяющие управлять сессией в Selenium RC:

  • void Start(); – запуск сессии;
  • void Stop(); – остановка сессии;
  • void SetSpeed(string value); – установить скорость, с которой Selenium RC будет посылать команды браузеру;
  • void SetTimeout(string timeout); – установить таймаут для ожидания ответа от браузера.

Рекомендую, создать отдельный класс, который будет содержать методы-обертки с данными командами.

Работа с полем загрузки файлов

Довольно распространенной проблемой для начинающих работать с Selenium является организация обработки загрузки файла на сервер. Вся сложность данной задачи заключается в том, что нужно обойти ограничение безопасности браузера. В основе Selenium (тут подробнее) лежит среда Selenium Core, манипуляции над браузером Selenium Core выполняет с помощью JS команд. У элемента управления “File upload” нельзя менять значение у атрибута “value” (он закрыт для записи). Это стандартное ограничение для большинства браузеров, которое блокирует возможность автоматической загрузки на сервер произвольных файлов (теоретически вредоносных).

 Элемент “File upload”, как правило, представляет собой текстовое поле, не доступное для редактирования, и кнопку, вызывающую диалог выбора файла. Пример классического элемента управления “File upload”:

Мы уже выяснили, что ввести в текстовое поле требуемый путь к файлу не получится. Как найти выход из данной ситуации? Есть несколько вариантов решения данной проблемы:

  • Использовать стандартную команду Selenium AttachFile, синтаксис – void AttachFile(string fieldLocator, string fileLocator). Однако, AttachFile не всегда помогает, так в ИЕ данная команда вообще не работает. Пример использования:

{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; }File file = new File (filePath); selenium.attachFile(fieldLocator, file.toURL().toString());{/syntaxhighlighter}

  • Самый удобный и надежный вариант (если AttachFile не помог) – воспользоваться специальным (небезопасным) режимом запуска браузера. В данном режиме поле загрузки файлов доступно для записи обычным вызовом команды selenium.type. Для браузера FireFox нужно использовать "*chrome", для Internet Explorer – "*iehta". Тут пример запуска браузера в специальном режиме. Пример использования команды selenium.type для ввода пути к файлу в “File upload” поле:

{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; }selenium.type("file_upload", "C:\file.xls");{/syntaxhighlighter}

  • Использование специализированных библиотек, которые имитируют ввод текста с клавиатуры. Тут нужно ориентироваться на платформу разработки тестируемого приложения.
  • Еще как вариант можно дать Selenium привилегии на загрузку файла для определенного браузера, или подготовить специальный профиль браузера, в котором поле загрузки доступно для редактирования. Решение нужно искать для каждого браузера отдельно. Вышеописанный – один из вариантов решения для браузера FireFox.

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

Работа с фреймами

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

 В Selenium для организации работы с фреймами (frame, iframe) предназначена команда void SelectFrame(string locator). Данная команда осуществляет переход на указанный фрейм. В качестве аргумента служит идентификатор фрейма. Для того чтобы получить фрейм-родитель в качестве локатора нужно указать – "relative=parent". Если нужно получить фрейм верхнего уровня используем "relative=top", также можно использовать "relative=up", но в IE "relative=up" у меня отказывался работать, поэтому использую "relative=top".

Пример фрейма:

Примеры использования команды SelectFrame:

{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; }public void GetFrameTop() { Trace.WriteLine("Select top frame:", "Component"); Selenium.SelectFrame("relative=top"); //выбрать фрейм верхнего уровня }

public void GetParentFrame()
{
Trace.WriteLine(“Select parent frame:”, “Component”);
Selenium.SelectFrame(“relative=parent”); //выбрать фрейм нижнего уровня
}

public void SelectIframe()
{
Trace.WriteLine(“Select iframe:”, “Component”);
Selenium.SelectFrame(“css=form iframe”); //выбрать фрейм с идентификатором “css=form iframe”
}{/syntaxhighlighter}

Не забываем дожидаться загрузки фреймов. Для ожидания загрузки фрейма в Selenium реализована команда void WaitForFrameToLoad(string frameAddress, string timeout). Где frameAddress
это атрибут ‘Name’ фрейма. В случае, когда имя фрейма генерируется
автоматически, или что-то в таком духе, то можно использовать следующий
код, который возвращает имя активного фрейма:

{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; } Trace.WriteLine(“Get iframe name:”, “Document”);
string innerValue = StateS.GetTestState().selenium.GetEval(“selenium.browserbot.getCurrentWindow().$(‘iframe’)[0].name;”);
Trace.WriteLine("Iframe name is: " +innerValue, “Document”);
return innerValue;{/syntaxhighlighter}


Часто еще бывает необходимым при обращении к элементам фрейма наводить
фокус на требуемый элемент. Для этого нужно использовать команду void Focus(string locator). Пример использования команды Focus можно посмотреть тут.

После обновления фрейма, фокус с активного фрейма часто переходит к родительскому фрейму (окну). Поэтому, после операций, которые приводят к обновлению фрейма, необходимо повторно активировать требуемый фрейм.

Установка фокуса на элемент

В ряде случаев, для того, чтобы выполнить некоторые действия над элементом страницы, необходимо навести фокус на данный элемент. То есть, перед тем как выполнить действие над элементом, сперва необходимо навести фокус на данный элемент. Для работы с фокусом в Selenium есть команда Focus(string locator). Далее по тексту пример использования команды Focus.

Синтаксис команды – void Focus(string locator), в качестве атрибута необходимо использовать идентификатор элемента. Пример использования команды Focus:

{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; }Selenium.Focus("text box locator");{/syntaxhighlighter}

Так как, при реальной работе с приложением пользователь активирует фокус элемента с помощью клавиатуры (клавиша “Tab”) или с помощью компьютерной мыши, то логично использовать команды имитирующее максимально точно данные действия пользователя. В Selenium есть команды, которые эмулируют работу с мышью, и с клавиатурой. Команды, предназначенные для работы с клавиатурой, начинаются на “Key”, в качестве аргумента нужно указывать код клавиши. Пример команды – void KeyUpNative(String keycode). Команды, предназначенные для эмуляции работы мыши, начинаются на “Mouse”, в качестве аргумента нужно использовать идентификатор и, в некоторых случаях, позицию (координаты – 10,20) для нажатия мыши. Пример команды – void MouseMoveAt(String locator,String coordString).

Для установки фокуса на требуемый элемент также можно использовать библиотеку jQuery. Для обработки JS нужно воспользоваться командой Selenium - string GetEval(string script). Команда GetEval возвращает результат вычисления указанного JS кода. В результате получаем конструкцию следующего вида:

{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; } public override void SetFocus(string locator) { Trace.WriteLine("Set focus for an element", "Document"); Selenium.GetEval("selenium.browserbot.getUserWindow().$get('"+locator+"').focus()"); //навести фокус на элемент }

    public override void UnsetFocus(string locator)
    {
       Trace.WriteLine("Unset focus for an element", "Document");
       Selenium.GetEval("selenium.browserbot.getUserWindow().$get('" + locator + "').blur()");     //снять фокус с элемента
    }{/syntaxhighlighter}</p><h2>Работаем с модальными окнами</h2><p>При работе с веб-сайтами 

довольно часто можно столкнуться с ситуацией, в которой при переходе
по ссылке на странице, с помощью JS функций открывается новая
веб-страница в отдельном окне. В данном случае новое окно будет являться
разновидностью модальных окон.
При написании авто-теста на Selenium все действия выполняются над
основным (активным) окном браузера. Поэтому, если после появления
модального окна требуется продолжить выполнение теста в новом
(появившемся) окне, то необходимо с помощью специальных команд
Selenium-а перевести фокус на новое окно. В данной заметке я попытаюсь
рассказать, как осуществить данный переход с помощью стандартных средств
Selenium.

 Для решения данной задачи нам понадобятся команды SelectWindow(), WaitForPopUp(), GetAllWindowNames(), GetAllWindowTitles(). Синтаксис данных команд:

  • void SelectWindow(string windowID) – переключить фокус на заданное окно браузера. Для того,что бы выбрать основное окно нужно в качестве параметра передать значение “null”;
  • void WaitForPopUp(string windowID, string timeout) – ожидание загрузки нового окна, заданное количество времени;
  • string[] GetAllWindowTitles() – возвращает массив заголовков окон, которые видит Selenium;
  • string[] GetAllWindowNames() – возвращает массив имен окон, которые видит Selenium.

Пример использования:

{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; }selenium.сlick("link=Customer"); //перейти по ссылке "Customer" selenium().waitForPopUp("enquiryPopup", Config.Wait); // ожидание загрузки нового окна, заданное количество времени selenium().selectWindow("Activity list | Easy Projects .NET"); //переход на модальное окно с title = "Activity list | Easy Projects .NET"{/syntaxhighlighter}

Бывают случаи, когда получить имя требуемого окна довольно сложно, – например, когда имя генерируется динамически. В данных случаях нужно использовать команды Selenium RC, которые позволяют получить список всех окон. Это команды – GetAllWindowIds, GetAllWindowNames, GetAllWindowTitles, GetAttributeFromAllWindows. Так как, когда открывается новое модальное окно, то в списке всех окон оно будет иметь самый больший индекс (порядковый номер в массиве). То есть, после того, как мы получили массив всех открытых окон браузера, нам остается указать индекс требуемого окна. Получилась следующая конструкция:

{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; }selenium.waitForPopUp(selenium.getAllWindowNames()[1], Config.Wait); //дожидаемся загрузки окна с индексом 1 из всего массива окон selenium.selectWindow(selenium.getAllWindowNames()[1]); //получить из массива окон, окно с индексом 1{/syntaxhighlighter}

В данном примере мы с помощью команды getAllWindowNames()[1] сперва дожидаемся загрузки окна с индексом 1, затем переходим на окно с индексом 1.

Данный механизм поиска требуемого модального окна можно улучшить. Можно не использовать конкретный индекс окна, а взять индекс последнего элемента в массиве. Пример реализации:

{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; }String[] AllWindow = selenium.GetAllWindowTitles(); selenium.selectWindow( AllWindow [ AllWindow.length - 1 ] );{/syntaxhighlighter}

Список и описание команд Selenium RC, обеспечивающих работу с модальными окнами можно посмотреть тут.

Обработка сообщений браузера (Confirmation, Alert, Prompt)

Существует три типа окон пользовательских сообщений в браузере: Confirmation, Alert, Promt. Форма Confirmation используется для подтверждения пользователем выполнения определенного действия на странице. Окно Alert используется для вывода предупреждений пользователю. Форма Promt представляет собой вывод диалога с возможностью вода текста в текстовое поле. Подробнее про JavaScript команды тут, примеры данных окон можно посмотреть здесь.

Selenium имеет встроенные методы для обработки перечисленных пользовательских сообщений браузера. Список команд Selenium RC, предназначенных для работы с пользовательскими сообщениями браузера:

  • bool IsAlertPresent() – метод проверят, появилось ли окно сообщения с типом Alert на странице;
  • bool IsConfirmationPresent() – метод проверят, появилось ли окно сообщения с типом Confirmation на странице;
  • bool IsPromptPresent() – метод проверят, появилось ли окно сообщения с типом Prompt на странице;
  • string GetAlert() – метод возвращает текст сообщения с типом Alert и закрывает окно;
  • string GetConfirmation() – метод возвращает текст сообщения с типом Confirmation и закрывает окно;
  • string GetPrompt() – – метод возвращает текст сообщения с типом Prompt и закрывает окно;
  • void ChooseOkOnNextConfirmation() – нажать кнопку “Ok” в следующем окне диалога. Вызывать данный метод нужно перед GetConfirmation();
  • void ChooseCancelOnNextConfirmation() – нажать кнопку “Cancel” в следующем окне диалога. Вызывать данный метод нужно перед GetConfirmation();
  • void AnswerOnNextPrompt(string answer); – ввести текст в поле окна Prompt при следующем его появлении .

Общий алгоритм обработки данных типов сообщений будет таков:

  • Перехватить событие появления пользовательского окна (используя IsAlertPresent, IsConfirmationPresent, IsPromptPresent в зависимости от типа окна). Если такого перехвата нет, то следующие действия приведут к ошибке: "There was unexpected alert".
  • Указать какую кнопку нужно нажать “Ok” или “Cancel”, актуально только для Confirmation и Prompt. Реализуют данный шаг команды: ChooseOkOnNextConfirmation, ChooseCancelOnNextConfirmation.
  • Для Prompt диалога ввести текст в поля ввода используя метод AnswerOnNextPrompt.
  • Считать текст пользовательского сообщения и закрыть диалог. В зависимости от типа сообщения использовать методы: GetAlert, GetConfirmation, GetPrompt.

Примеры обработки Confirmation: сообщения:

{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; }Trace.WriteLine("Choose 'Cancel' button on next confirmation:"); Selenium.ChooseCancelOnNextConfirmation(); Selenium.Click("user_delete_button"); Trace.WriteLine("Is confirmation present:"); Assert.IsTrue(Selenium.IsConfirmationPresent(), "Confirmation message is not present."); Trace.WriteLine("Get confirmation:"); string confirmationText = Selenium.GetConfirmation(); Assert.AreEqual(confirmationText, ConfMessage, "Confirmation message has incorrect text.");{/syntaxhighlighter}

Примеры обработки Alert: сообщения:

{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; }Selenium.Click("alert_button_name"); Trace.WriteLine("Is alert present:"); Assert.IsTrue(Selenium.IsAlertPresent(), "Alert message is not present."); Trace.WriteLine("Get alert message:"); string alertText = Selenium.GetAlert(); Assert.AreEqual(alertText , AlertMessage, "Alert message has incorrect text.");{/syntaxhighlighter}

Примеры обработки Prompt: сообщения:

{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; }Selenium.Click("prompt_button_name"); Trace.WriteLine("Choose 'Ok' button on next confirmation:"); Selenium.ChooseOkOnNextConfirmation(); Trace.WriteLine("Set answer text:"); Selenium.AnswerOnNextPrompt("some text"); Trace.WriteLine("Is prompt present:"); Assert.IsTrue(Selenium.IsPromtPresent(), "Prompt message is not present."); Trace.WriteLine("Get prompt message:"); string promptText = Selenium.GetPrompt(); Assert.AreEqual(promptText , PromptMessage, "Prompt message has incorrect text.");{/syntaxhighlighter}

WaitForCondition

В Selenium есть замечательный метод WaitForCondition. С помощью данного метода можно задавать ожидание наступления определенного события на странице. WaitForCondition может быть особенно полезен для ожидания отработки JS и AJAX запросов.

 Синтаксис команды: void WaitForCondition(string script, string timeout). В качестве параметра script указываем JavaScript код для выполнения, timeout – время ожидания в миллисекундах (в течении какого времени будет выполняться проверка).

Примеры использования:

{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; }//ожидание появления элемента "ctl00_Content_buttonRefresh" в течении 6 секунд selenium.WaitForCondition("selenium.isElementPresent("ctl00_Content_buttonRefresh")", "60000"");{/syntaxhighlighter}

А можно писать и так:

{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; }//ожидание появления элемента "ctl00_Content_buttonRefresh" в течении 6 секунд selenium.WaitForCondition("selenium.browserbot.getCurrentWindow().document.getElementById("ctl00_Content_buttonRefresh")", "60000"");{/syntaxhighlighter}{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; }//ждем в течении 6 секунд, пока элемент "ctl00_Content_buttonRefresh" не станет видимым selenium.WaitForCondition("selenium.IsVisible("ctl00_Content_buttonRefresh")", "60000"");{/syntaxhighlighter}

С помощью данной команды можно организовать ожидание всех JS и AJAX запросов на странице (ждем полной загрузки страницы) :

{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; }selenium.WaitForCondition("try {var doc = selenium.browserbot.getCurrentWindow().document;doc.readyState == 'complete' && doc.selenium_dummy == undefined}catch(err){false}", timeout);{/syntaxhighlighter}

Пример использования метода GetXpathCount()

Одной из распространенных задач, встречающихся при написании автотестов, является получение из списка элементов количества объектов удовлетворяющих определенным условиям. Один из вариантов решения – воспользоваться командой Selenium RC GetXpathCount. Ниже пример решения.

 Синтаксис команды – decimal GetXpathCount(string xpath);

В качестве примера возьму последнею свою практическую задачу, где пришлось использовать команду GetXpathCount. Итак, задача: из всего списка задач нужно получить количество задач с заданным именем (имя задачи уникально только в рамках одного проекта). Выглядит это примерно так:

Сперва требуется подобрать xpath локатор, который будет искать все элементы, содержащие заданное имя задачи. Остановился на таком локаторе:

 

xpath="//span[contains(@id, 'ctl00_Content_tg_ct')]/a[text()='Task1']";{/syntaxhighlighter}

А вот так будет выглядеть вызов функции GetXpathCount:

 

{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; }decimal xpathcount = selenium.GetXpathCount("//span[contains(@id, 'ctl00_Content_tg_ct')]/a[text()='" + ActivityName + "']");

Если нужно выполнить определенное действие над полученными элементами (click, check и т.д.), то код может выглядеть примерно так:

 

{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; }xpathcount = selenium.getXpathCount("//span[contains(@id, 'ctl00_Content_tg_ct')]/"); //получить кол-во элементов for (i = 1;i<xpathcount;i++){ selenium.click("//span[contains(@id, 'ctl00_Content_tg_ct')]["+i+"]"); //["+i+"] индекс элемента }{/syntaxhighlighter}

Удачи в освоении Selenium RC!

 

проблема с запуском селениума

nunit выдает ошибки 


testpro.Untitled.TheUntitledTest:
SetUp : System.Net.WebException : Невозможно соединиться с удаленным сервером
  ----> System.Net.Sockets.SocketException : Подключение не установлено, т.к. конечный компьютер отверг запрос на подключение 127.0.0.1:4444
TearDown : System.NullReferenceException : Ссылка на объект не указывает на экземпляр объекта.
-----------------------------------------------------------------------------------------------------------------------------------------------
насколько я понял Seleniunm IDE при переводе  на С# отображает тесты в формате selenium 1.0
нужно использовать команды selenium 2.0
или что -то не то???