Есть отличная удаленная работа для php+codeception+jenkins+allure+docker спецов. 100% remote! Присоединиться к проекту

Какие ограничения WebDriver можно лечить через JavaScript?

php
webdriver
javascript
Теги: #<Tag:0x00007f7b64a15658> #<Tag:0x00007f7b64a154f0> #<Tag:0x00007f7b64a15338>

(Michael Bodnarchuk) #1

WebDriver API достаточно обширно, но и оно имеет некоторые ограничения. Хочу поинтересоваться у сообщества. Подскажите исходя из вашего опыта, где возможностей WebDriver обычно не хватает и нужно использовать хуки на JavaScript, чтобы обойти ограничения? Или допустим, где вебдрайвер может глючить и хуки на JavaScript работают более эффективно?


Ранее я работал с PHP + Mink драйверами на Selenium2. Там практически все действия пользователя реализованы не через апи вебдрайвера, а через javascript и библиотеку Syn.js. Сейчас я перевожу всё на чистый вебдрайвер, и в связи с этим у меня и появился этот вопрос.


(Mykhailo Poliarush) #2
  1. доступ к невидимым элементам
  2. ресайзинг окон и работа с окнами
  3. считывание количество оставшихся ajax запросов
  4. ввод текста в различные кастомные редакторы с textarea
  5. скролинг

это пока все что пришло сходу в голову, может быть потом еще допишу


(Michael Bodnarchuk) #3

Доступ к ним можно получать и проверять через isDisplayed. А вот взаимодействовать с ними нельзя :frowning: Как и с disabled элементами.

А это как раз нативно делается. Или есть какие-то подводные камни?

Кстати, возможно есть какие-то ограничения в зависимости от браузеров? Где ещё JavaScript бывает необходим?


(Дмитрий Жарий) #4

Ээээ не-не, не пойду по дороге негатива и феэлов ВебдРайвера, и начну с киллер фичи, которой нет и быть не может (пока что) в JavaScript

Это: nativeEvents

Эта фича работает немного медленнее, чем JavaScript аналог, но зато позволяет эмулировать реальный клики и наборы текста в браузере.
В некоторых веб-приложениях есть обычай блокировать пользовательский интерфейс в момент выполнения некоторого Ajax запроса. Это может быть сделано путем добавления div элемента по верх всей страницы. Так вот, используя nativeEvents, веб драйвер не сможет кликать или набирать текст в заблокированые таким образом поля и не сможет набирать текст, как это бы не мог сделать реальный пользователь. А кликать будет не по элементу найденному в DOM-дереве страницы, а по вычисленным координатам, и клик этот пройдет через весь веб браузер , что создает более реалистичную симуляцию работы пользователя, чем через JavaScript.
Недостаток в том, что работает медленнее, но, в любой момент можно переключится на JavaScript-симуляцию. Я в основном работаю через JavaScript-симуляцию, (nativeEvents = false), но пару раз в неделю прогоняю тесты с nativeEvents = true

Скорость работы

Сам протокол REST, через который работает WebDriver, довольно тормознутый.
Ну, например, мы хотим вывести в лог все теги input и их value в лог.
В этом случае, первый запрос получит список внутренних ID найденных элементов.
Потом в цикле , для каждого элемента, запрос 1 получит тэг, запрос 2 – value.
В таком случае, может быть лучше запустить JavaScript для того чтобы собрать всю информацию за один раз. А JavaScript можно запустить посредством самого вебдрайвера.

AJAX

Вебдрайвере есть конечно WebDriverWait для ожидания появления некоторого элемента при Ajax запросе, но если используется jQuery – то лучше у нее и спросить, закончился запрос или нет:

    public void WaitForAjax()
    {
        while (true) // Handle timeout somewhere
        {
            var ajaxIsComplete = (bool)(driver as IJavaScriptExecutor).ExecuteScript("return jQuery.active == 0");
            if (ajaxIsComplete)
                break;
            Thread.Sleep(100);
        }
    }

Кривые руки программистов некоторых фреймворков

В приложении написаном на knockout + bootstrap (вот не знаю кого конкретно ругать) у текстового поля, которое я проверял на свойство disabled, как раз этого свойства и не было, хотя для пользователя оно было недоступно. Оказалось, что в недрах knockout’а (или bootstrap) у этого поля было нестандартное свойство isEnabled, которое никак не обновляло стандартное HTML’ное disabled.
Приходилось лезть в недра JavaScript’а и получать это свойство.

Фреймы недоступны в JavaScript

Через JavaScript и без помощи WebDriver – нельзя обращаться из одного фрейма в другой (который ведет на другой сайт). В Вебдрайвере – можно.

Вебдрайвер сам использует очень много JavaScript

Сам вебдрайвер инжектит очень много JavaScript. Везде есть баги, но я всегда более уверен в том, что в реализации Вебдрайвера их меньше, чем в моей реализации. Почему? Потому что этот код уже от тестирован тысячами пользователей на разных платформах.
Кроме того, очень удобным образом можно инжектить и пользовательский JavaScript, так что, в случае чего, всегда можно заменить стандартную реализацию на свою.

Итог

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

Хотим ли мы получить более быстрый, но, менее надежный код в итоге?

Ура! научился форматировать текст в маркдауне!


(Mykhailo Poliarush) #5

конечно для некоторых случаев есть нативная поддержка через определенные методы

я тебе просто рассказываю частые случае, в которых люди пытаюсь выполнить что-то javascript, чтобы решить их задачу (просто я думал, ты об этом спрашивал)


(vmaximv) #6

[quote=“davert, post:1, topic:3310”]
Подскажите исходя из вашего опыта, где возможностей WebDriver обычно не хватает и нужно использовать хуки на JavaScript, чтобы обойти ограничения?
[/quote]Везде хватает.

[quote=“davert, post:1, topic:3310”]
Или допустим, где вебдрайвер может глючить и хуки на JavaScript работают более эффективно?
[/quote]Везде может глючить: тайпы, клики, isDisplayed и т.д. Но, имхо, нужно придерживаться следующей стратегии:

  1. Пишем workaround на js
  2. Помечаем его //TODO: remove when fixed
  3. Выписываем/находим соответствующий баг в багтрекере селениума
  4. Ждем фикса или просто проверяем с новым релизом WD
  5. Удаляем workaround

Единственным случаем, когда при относительно (iedriverserver падал иногда) правильной работе WD, пришлось использовать js, было пару листбоксов/ддл с парой сотней айтемов. Вот тут WD нещадно тупил (счет не на секунды, а на минуты) на findElements.

[quote=“dzhariy, post:4, topic:3310”]
Я в основном работаю через JavaScript-симуляцию, (nativeEvents = false),
[/quote]Хочу добавить, что с этой опцией лучше отказаться от запуска скриптов в IE.

[quote=“dzhariy, post:4, topic:3310”]
но если используется jQuery – то лучше у нее и спросить, закончился запрос или нет:
[/quote]Код может и подкупает своей простотой и видимой надежностью, но на практике заставить его работать не получилось. jQuery.active == 0 не говорит о том, что все запросы выполнились.


(Дмитрий Жарий) #7

Использовать или не использовать – тут все зависит от конкретного приложения. То, с которым я работаю – по сути синхронное, т.е. выполняет один запрос за другим и все это делается через только через jQuery. В таком случае jQuery.active == 0 всегда возвращает «истину». Но, опять же, вполне возможно, что когда-то это будет не так.

Ну, и иногда приходится комбинировать и запрос к jQuery и использовать свой аналог WebDriverWait для того чтобы дождаться элемента.


(vmaximv) #8

Я не имел ввиду параллельное/последовательное выполнение запросов. Между “действием” и инкрементом каунтера active может пройти достаточно времени, за которое WaitForAjax()
успешно пройдет, при том, что запрос не выполнился.

Либо WaitForAjax()
может попасть в промежуток, когда предыдущий запрос выполнился, а следующий еще не сформировался. В лучшем случае WaitForAjax() будет работать “вхолостую”, а ожидать окончания запросов/сетевого трафика будет драйвер (FF). В худшем (IE) тесты будут крайне нестабильны.


(Дмитрий Жарий) #9

Да, 100% гарантии нет, и это хороший пример. Такое бывает. В этих случаях можно сделать более явное ожидание


(Ninfea) #10

Как раз столкнулась с проблемой заполнения textarea, есть какие то пути решения?


(Mykhailo Poliarush) #11

Случаи разные и решения тоже разные.

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

(Вот прямо возле этого топика, справа, есть кнопка “Ответить в новой теме”)

И кстати вот подобные топики