Несколько вопросов от начинающего (WebDriver)

Добрый день, вдохновился здешним форумом и вебинарами (очень понравился вот этот: http://automated-testing.info/forum/problema-pri-zapisi-lokatora , отсмотрел уже половину), взял C#-версию (2.24) и появились вот такие вопросы:

0) не является ли C#-версия "отстающей"? (как это обычно происходит, например, с FitSharp в сравнении с джавовским оригиналом).

1) как получить хэндл окна драйвера? То, что возвращается, является какой-то шуткой:

Chrome -> CurrentWindowHandle
Started ChromeDriver
port=9155
version=22.0.1203.0b
log=C:\Windows\system32\chromedriver.log
f1-2


Chrome ->WindowHandles
Started ChromeDriver
port=9209
version=22.0.1203.0b
log=C:\Windows\system32\chromedriver.log
f1-2


InternetExplorer x64 ->CurrentWindowHandle
Started InternetExplorerDriver server (64-bit)
2.24.2.0
Listening on port 9263
6cc32c42-d3b8-4a89-a11a-e32098b9b4f6

InternetExplorer x64 ->WindowHandles

Started InternetExplorerDriver server (64-bit)
2.24.2.0
Listening on port 9293
b5f4b7c4-f41e-492d-ad6e-d42f3b0c2858

кто-нибудь знает, как получить хэндл в int или в IntPrt, или процесс окна? Тайтл, понятное дело, не уникален. Без хэндла окна невозможно получить экранные координаты элемента, к примеру, потому что координаты элемента отмеряются даже не от окна, а от контейнера страницы.

2) как получить элемент, родительский только что полученному (в принципе, код на любом языке мне подойдёт для прочтения)?

3) драйверы отчего-то выдают кучу мусора в коммандлайн - есть _штатные_ средства для избавления от этого? (скрыть я могу, но вдруг есть штатные средства).

4) PageObjectPattern - это термин из селениума или из более широкой области (что-нибудь с вэб-программированием)? Хотелось бы почитать что-то теоретическое по этой теме.

5) А можете, коллеги-тестировшики, выложить куски кода из произвольных проектов? Интересует сама организация кода.

6) В классическом примере из доки http://seleniumhq.org/docs/03_webdriver.html : запустить браузер, навигировать на гугль, взять окошко ввода, записать туда Cheese и засабмитить (или не засабмитить, без разницы) - я не могу получить Text из этого IWebElement. Почему?

<input class="gbqfif" disabled="" autocomplete="off" style="border: medium none; padding: 0px; margin: 0px; height: auto; width: 100%; position: absolute; z-index: 1; background-color: transparent; color: silver; left: 0px; visibility: hidden;" id="gs_htif0" dir="ltr">

Насколько я понимаю, Text никак не относится к коду элемента, а формируется драйвером на основе данных в контроле? Так отчего же он этот Text не возвращает?

7) Кстати, о координатах: пробовал не только ((IWebElement)element).Location.X, но и через RemoteWebElement -> Coordinates.LocationOnScreen.X - и это возвращает в координатах от окошка, а не от десктопа. Именно, не ошибка в отсутствии преобразования логических координат в физические или обратно, я линейкой мерял :), а возвращает от левого верхнего угла десктопа.

8) Как делаются продолжительные истории на веб-драйвере? Вот пример из вчера: сайт omena.com (omenahotels.com, omenahotelli.fi и т.д.). Сам по себе сайт неплохой, более-менее удобно выбирать дни (нууу, ну удобно), чувствуется, что или сайт немного протестили руками, или юнит-тестами. Потому что когда начинается что-то продолжительное, начинается сущий ад.

Когда начинаешь заносить свои данные (требуется внести данные за всех жильцов!!), эта форма проверяет ввод, не допускает неуникальных номеров тлф (ребёнку 5 лет всегда даю номер второй симки :):) бред). Если я не залогинился, то не даёт ввести мой имейл (я уже под ним зареган). Чтобы войти, в русской версии это называется Регистрация (а не Логин), пришлось сверяться со шведской и англ версиями.

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

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

Вопрос: интересует, как тестируются такие длинные истории. За одну длинную сьюту? Как это принято делать? В данном случае оказалось, что первый цикл вбития данных и оплаты гораздо легче последующих. Т.е., делает ли кто-нибудь такие сценарийные тесты и как это вообще (получается, работает, подводные камни)?

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

Заранее спасибо!

0) не является ли C#-версия "отстающей"? (как это обычно происходит, например, с FitSharp в сравнении с джавовским оригиналом).

Нет, по крайней мере явно. Обычно идет вровень

1) как получить хэндл окна драйвера? То, что возвращается, является какой-то шуткой:

Это внутренний selenium хенд окна. Исползуется для переключения на это окно и т.п.

Системный хэндл получить нельзя, о крайне меря, в iedriver.

2) как получить элемент, родительский только что полученному (в принципе, код на любом языке мне подойдёт для прочтения)?

через поиск родительского элемента, типа webelement.find_element_by_xpath("./..")

3) драйверы отчего-то выдают кучу мусора в коммандлайн - есть _штатные_ средства для избавления от этого? (скрыть я могу, но вдруг есть штатные средства).

http://code.google.com/p/selenium/issues/detail?id=4287

Часть сообщений типа:

Started InternetExplorerDriver server (64-bit)
2.24.2.0
Listening on port 9293

не отключаема на данный момент. Остальные можно отключить - посмотрите комментарий в issue.

4) PageObjectPattern - это термин из селениума или из более широкой области (что-нибудь с вэб-программированием)? Хотелось бы почитать что-то теоретическое по этой теме.

Для начала, https://code.google.com/p/selenium/wiki/DesignPatterns https://code.google.com/p/selenium/wiki/PageFactory https://code.google.com/p/selenium/wiki/PageObjects

Ну а дальше - интернет большой, что-нибудь найдется. Или еще кто-нибудь что-то здесь посоветует.

По идее, PageObject это не только селениум.

6) В классическом примере из доки http://seleniumhq.org/docs/03_webdriver.html : запустить браузер, навигировать на гугль, взять окошко ввода, записать туда Cheese и засабмитить (или не засабмитить, без разницы) - я не могу получить Text из этого IWebElement. Почему?

<input class="gbqfif" disabled="" autocomplete="off" style="border: medium none; padding: 0px; margin: 0px; height: auto; width: 100%; position: absolute; z-index: 1; background-color: transparent; color: silver; left: 0px; visibility: hidden;" id="gs_htif0" dir="ltr">

Насколько я понимаю, Text никак не относится к коду элемента, а формируется драйвером на основе данных в контроле? Так отчего же он этот Text не возвращает?

text() - это доступ к текстовой ноде. Для input, если не ошибаюсь, нужно использовать value.

7) Кстати, о координатах: пробовал не только ((IWebElement)element).Location.X, но и через RemoteWebElement -> Coordinates.LocationOnScreen.X - и это возвращает в координатах от окошка, а не от десктопа. Именно, не ошибка в отсутствии преобразования логических координат в физические или обратно, я линейкой мерял :), а возвращает от левого верхнего угла десктопа.

А в чем вопрос-то? Как получить абсолютные координаты? Через селениум никак, т.к. селениум тулза не для тестирования браузера, а сайтов.

Но иногда такое нужно. Обычно используются внешние тулзы, типа autoit и т.п. Для этого как раз нужен хэндл или pid.

Его можно получить взяв все хэндлы до запуска IE и после.

8) Как делаются продолжительные истории на веб-драйвере? ...

Если честно, не очень понял вопрос. Как организуются длинный тест кейс? Ну как Вы его записываете в ручном тестировании?

Можно взглянуть в сторону Behavior-Driven testing, мне кажется.

8) Как делаются продолжительные истории на веб-драйвере? Вот пример из вчера: сайт omena.com (omenahotels.com, omenahotelli.fi и т.д.). Сам по себе сайт неплохой, более-менее удобно выбирать дни (нууу, ну удобно), чувствуется, что или сайт немного протестили руками, или юнит-тестами. Потому что когда начинается что-то продолжительное, начинается сущий ад.

 

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

 
Автоматизация тестирования лишь может вам ответить, что все те кнопочки, которые работали вчера еще до сих пор работают, но, скрипты не сделают вывод об неадекватности самой работы сайта. 
Но, в данном случае, автоматизация может помочь и в исследовательском тестировании, например, создать для вас 30 пользователей (скажем, многодетная семья из детскогодома семейного типа планирует забронировать номера в отеле). 
 
Продолжительные истории, к слову, называются end-to-end scenario, это также не простая штука в автоматизации. 
Во-первых, такой сценарий требует качественного слоя автоматизации. Потому что если весь сценарий будет записан как серия кликов и вводов текста в поле – сам тест-кейс будет огромным, непонятным и плохо поддерживаемым. Именно для решения этой проблемы нужно использовать PageObject – чтобы вынести все действия, специфичные для страницы в сам класс, декларирующий страницу. 
Более крупные действия, вы можете вынести в так называемые хелперы. Это глобальная функция или на C# – это общедоступный статический метод. 
Ну, вот пример такого сценария с буканьем номеров. Тест должен выглядеть примерно так:
[Test]
public virtual void T01_Booking_for_3_users()
{
 
var users = new List<UserParam>() { new UserParam () { Name = "Vasya", Email = "vasya@yandex.ru"},  
                                                     new UserParam () { Name = "Nastya", Email = "nastya@yandex.ru"},  
                                                     new UserParam () { Name = "Annya", Email = "Annya@yandex.ru"},  
         };
 
User.Create(users);
Order.Create("Lux", users);
Order.Checkout();
Mailbox.WaitForNewEmail();
var emailMassage = Mailbox.GetLatestEmail();
StringAssert.Contains("Lux for 3 persons was booked", emailMassage.Body);
}
 
Как видите, это набор очень высокоуровневых действий, которые понятное дело, содержат в себе более низкоуровневые. Но, именно так должен выглядеть сам продолжительный сценарий:
Без вызовов функция драйвера в самом тесткейсе, работать только с родными структурами для языка программирования: строками, числами, классами, но не объектами вебдрайвера. Быть коротким (по количеству строк кода) и понятным.
И в данном примере User.Create(users); – это и есть такой высокоуровневый хелпер. Внутри он дергает страницы, возможно обновляет саму базу данных, это не важно, а важно то, что в случае завала теста – мы четко знаем в каком блоке произошел завал, а какие блоки успешно прошли. 
И тем самым время анализа ошибки тесткейса сокращается. 
Вот, приблизительно так я советую делать end-to-end сценарии. 
 

Я только пару дней назад познакомился с Selenium WebDriver (под Java) для работы, а потому вопросы совсем простые.

1)В инетернете единственный сайт с какой-то документацией по вебдрайверу, который я нашел - это http://selenium.googlecode.com/svn/trunk/docs/api/java/index.html - а есть что-нибудь еще и желательно с примерами использованиями?

2)Как можно узнать адрес, на который ведет ссылка (ссылка представлена как WebElement)?

3)В документации нашел, что есть LinkFinder, но попытки научиться его использовать успехом не увенчалиь. Поборол при помощи driver.findElements(By.partialLinkText("")); а как по-еловечески это можно делать?

4)Есть какой-то аналог LinkFinder'а для кнопочек и формочек?

Заранее спасибо.

1) selenium2.ru - русская документация, постоянно обновляется.

 

2) можно попробовать через WebElement.getAttribute("href"), поскольку вебелемент является <a> элементом.

 

3) про линкфайндер не подскажу ибо не пользовался.

 

4) что имеешь ввиду под линкфайндером для кнопок и форм?

1) Не совсем то, что я имел ввиду, я не видел там полного списка имеющихся классов и методов. Насколько я понял ничего подобного http://www.cplusplus.com/reference/ для WebDriver'а нет (т.е. так, что написан метод, что он из себя представляет, пример использования)?

2)Работает, благодарю.

4)Можно ли как-то, например, получить List всех форм для ввода на странице?

1) http://release.seleniumhq.org/selenium-remote-control/0.9.2/doc/java/com/thoughtworks/selenium/Selenium.html - селениум АПИ.

 

4) ну тут стоит думаю воспользоватся стандартными локаторами для конкретной формы. айдишки, неймы, xpath + всяческие дата провайдеры и циклы будут вам в помощь. Также рекомендую посмотреть что такое PageObject и PageFactory+@FindBy аннотации.

4)Немного поэкспериментировал, более-менее проблема решилась при помощи driver.findElements(By.tagName("form")) Но возник другой вопрос - как можно узнать CSS элемента, можно ли как-то перейти к предку элемента? Причем проблема в том, что заранее сайт неизвестен,  и просто руками посмотреть CSS в firebug'е нельзя, нужно научиться делать это автоматизированно. Попытался поиграться с getCssValue, но ничего полезного не получилось. Кто-нибудь знает как можно решить эту проблему?

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

 

однако в данном вопросе я вам не подскажу поскольку я им не пользовался.

Ответ на мой вопрос #2.

Как только удастся вырваться с дачи, применю в деле.

Точно, я как-то сразу не сообразил что xpath позволяет добиратся до предков и потомков.

 

Посмотрите правила создания xpath локаторов. Также полезным будет поставить плагин типа xpathChecker.