Зачем FindElement, если есть FindElements?


(apetrovskiy) #1

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

 

К примеру, мы делаем dir или Get-ChildItem и получаем в ответ массивчик, т.е. вообще всё. Если нам надо фильтровать результат, мы фильтруем (параметры на входе или фильтр на выходе. Я специально не даю кода фильтрации, потому что это можно сделать и на языках с точечной нотацией, в этих, неприятно глазу выглядящих строк кода с кучей скобок :) недавно был примерчик : "улица Октября".equals(element.FindElement(by.Name="улица Октября")).getText() - тут тоже можно задать фильтр в виде параметров).

Т.е. правильная выборка (FindElements) плюс фильтрация дают верный результат.

Выборка наугад (FindElement) даёт непредсказуемый результат.

 

А вот пример кода (я всё ещё мусолю пример из доки селениума про сыр). Пример, конечно, не фонтан, просто пример с TagName чётче покажет то, что есть и в семи остальных вариантах FindElement:

создаём драйвер и навигируем на сыр:

 

Start-SeChrome | Enter-SeURL -u "http://google.com" | Get-SeWebElement -Name q | Set-SeWebElementKeys -Text cheese | Submit-SeWebElement

 

Теперь посмотрим результаты.

Результат не определён (выдало что-то одно, по выбору драйвера):

Get-SeWebElement -TagName input

полная коллекция результатов, которую затем можно фильтровать:

Get-SeWebElementCollection -TagName input

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

Кусок исходника страницы из хрома:

<input type=hidden name="hl" value="ru"><input type=hidden name="newwindow" value="1"><input type=hidden name="output" value="search"><input type=hidden name="sclient" value="psy-ab"></div></fieldset><fieldset class=gbqff id=gbqff><legend class=gbxx></legend><div id=gbfwa class="gbqfwa "><div id=gbqfqw class=gbqfqw>

 

Возвращаемся к вопросу - зачем тогда нужен FindElement? Ведь логичнее использовать только вывод в виде коллекции или перечислителя. Оптимизация памяти или времени? Ну и зачем такая оптимизация, если могут выйти разные результаты?

 


(barancev) #2

Никакой оптимизации. Метод findElement возвращает первый элемент той самой коллекции, которую возвращает метод findElements. Чисто для удобства, чтобы не возиться каждый раз с коллекциями, driver.findElement(locator) полностью эквивалентно driver.findElements(locator)[0].

И о какой "выборке наугад" Вы говорите? Если метод findElement возвращает разные результаты в разных браузерах, значит и метод findElements тоже будет возвращать разные результаты.


(Denis Veselovskiy) #3

"Выборка наугад (FindElement) даёт непредсказуемый результат."

афтар, жги исчо   Ж))


(apetrovskiy) #4

Именно это я и хотел узнать. Если гарантированно возвращается элемент нуммер ноль, тогда я просто выкину котлету , которая выдает один элемент и сделаю так:

Get-SeWebElement -First (тут будет работать FindElement);

Get-SeWebElement (тут будет работать FindElements)

Спасибо за инфу


(apetrovskiy) #5

Спокойно, я такой же спам/бот, как и ты. :)


(barancev) #6

Имхо, те же яйца, только в профиль :)


(apetrovskiy) #7

И о какой "выборке наугад" Вы говорите? Если метод findElement возвращает разные результаты в разных браузерах, значит и метод findElements тоже будет возвращать разные результаты.

Допустим, один драйвер возвращает x1, x2, x3, x4, x5

другой драйвер возвращает x2, x3, x4

нам нужен x2

что вернёт findElement?

x1 от первого драйвера и x2 от второго драйвера.

А через findElements x2 можно получить гарантированно. Вот это меня и насторожило (а также спорадические ошибки на хроме, и ряд топиков здесь - когда драйверы различаются результатами).

 

Это, конечно, перестраховка (просто меня интересуют самые общие случаи. Дальше уже дело юзера - подобрать XPath, CSS, и т.д.). И уж точно не моё дело тестирвоать сам селениум. :)

 

В настоящее вермя у меня совсем другие проблемы: если что-то не работает, так это чаще всего не работает драйвер совсем.

На замечательной семёрке не работает Firefox (???) - что-то там про отсутствие пермиссий в какой-то внутренней dll'ке (и где это искать?? :))

на XP IEDriverServer работает, но не находит элементов вообще

ну и на паре машинок IE не работает.

Изредка, хром выдают ошибку.

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


(apetrovskiy) #8

да, по сути выборка одного элемента не нужна.

Мне на днях один мвп задал вопрос по другому моему фреймворку: а чего это код 

Get-UIAButton -Name '* '

возвращает только одну кнопку на калькуляторе? Вот я и задумался. А ведь он прав, надо отдавать всю последовательность контролов, элементов и т.д.