как найти на странице javascript-скрипт и вызвать его в тесте ?

Привет. Перерыл в поиске все темы связанные с #javascript , но не нашёл ответа. В общем, никогда не сталкивался со скриптами, всегда хватало простых действий через #webdriver , на этот раз на проекте оказалось что привязаться ( в плане #locators ) вообще почти не к чему, всё динамическое.

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

<button class="uri-button component_ok_set" ng-click="ctrl.confirmemailproperty()" main="" use-template="true" tabindex="1">

Я так понимаю confirmemailproperty() - это #javascript -метод, который можно вызвать.

Как это сделать в #python ? Можно ли обращаться к нему прямо по имени ?

Можно пример кода страницы? Привязаться всегда есть к чему, возможно просто не замечаете.
Что касается обращения к JS непосредственно в тесте - это можно сделать при помощи метода execute_script
Вот тут хороший пример: Python selenium - execute javascript code - InfoHeap

from selenium import webdriver

driver = webdriver.PhantomJS("/usr/local/bin/phantomjs")
driver.get("http://dev.infoheap.com/")
jscode='''
var global_total_links=0;
jQuery("a").each(function() {
  global_total_links++;
});
return global_total_links;
'''
retval = driver.execute_script(jscode);
print retval
driver.close()
2 лайка

Я извиняюсь, не совсем точно сформулировал вопрос. То, что скрипты вызываются с помощью execute_script я нашёл.

Меня больше интересует то как вызвать конкретный скрипт на странице. Т.е. у меня есть элемент (за элемент не ругайте, пишу дома на память, но общая суть - та же) <div class="popup_confirmation_property_btn hide" ng_click="ctrl.confirmemailproperty();" css_блаблабла--span-OK></span></div>. Я пробовал вставлять в execute script и отдельно "confirmemailproperty();", и "ctrl.confirmemailproperty();" и "return confirmemailproperty()", но ничего из этого не работает.

Итого,
1-ый вопрос: “ctrl.confirmemailproperty();” - это же скрипт ?
2-ой вопрос: как его вызвать ?

п.с. к сожаленію пример страницы предоставить не могу, всё приватное. На счёт того, что привязаться можно всегда - это понятно, просто настало время подтянуть знания по джс :slight_smile:

Похоже у вас Angular. Вот так попробуйте:

А ещё, возможно стоит поглядеть в сторону Protractor/CodeceptJS, тестировать Angular ими гораздо проще.

4 лайка

для тех то пишет на Python есть GitHub - kpodl/pytractor: Python selenium extensions for testing angular.js apps
для тех то пишет на Java есть GitHub - caarlos0-graveyard/jProtractor: An angular/protractor implementation for Java Selenium API / GitHub - henrrich/jpagefactory: JPageFactory is a set of Selenium Java FindBy annotations that eases the usage of Selenium page factory pattern for automating Angular based web application. It is based on JProtractor project which is a Java wrapper of Protractor framework.
для тех то пишет на .net есть GitHub - bbaia/protractor-net: The .NET port of Protractor, an E2E test framework for Angular apps

2 лайка

Вы end to end тесты пишете ведь? Делайте всё именно так, как делал бы пользователь - дождитесь пока будет виден элемент, а далее взаимодействуйте с ним, иначе толку от ваших тестов не будет никакого. Если нужна помощь с построением локаторов - вам тут помогут, подскажут где почитать, но не изобретайте велосипедов - не нужно вам взаимодействовать с скриптами на странице. Определить уникальный локатор можно всегда - практически без исключений.

4 лайка

Не всегда можно дождаться элемента.

Пример приведите пожалуйста.

Если ваш сайт не из 90-х, то наверняка js скрипт будет лежать не в #dom , а если это #nodejs , то вы и не увидите ссылок на скрипты в принципе.

У вас 2 варианта:

  1. Подливать напрямую js в репозиторий вашего проекта и выполнять его на сервере.
    Как по мне, вариант плохой ( конечно если вам не хочется написать еще и сервер)
  2. Вызывает событие, которое и триггерит выполнение скрипта. Наиболее подходящий вариант

При разработке не нужно усложнять то, что можно сделать более просто, это один из главных императивов. Сложная зависимая логика приведет вас к тому, что вы не разберетесь как оно вообще работает.

@pavelp дал вам самый действенный совет

Пример простой.

У меня на проекте на сайте есть табличная часть, которая обновляется по клику (некий фильтр). Между кликом и запросом к серверу (ajax запрос) есть таймаут в 0.5 секунд (требование бизнеса). После запроса табличная часть обновляется, в зависимости от того, что человек выбрал. Тест должен проверять, что табличная часть соответствует выбранным фильтрам. Как будете ждать нужный вам элемент?

1 лайк

@Mes , большинство сайтов сейчас представляют собой one-page solution, т.е. элементы динамические. Обратите внимание на WebDriverWait для ожидания элементов, которые появляются на странице со временем, а не при загрузке html.

Проверяйте контекст таблицы, а не локаторы, если они не уникальные.
Cоставте mapping context - expected table

Обратитесь к разработчикам, спросите их о возможности добавления уникальных идентификаторов.
Качество дело не только тестировщиков, если вам скажут разбираться самим ( только QA) , значит ваше начальство не особо и интересует качество проекта

1 лайк

именнно для этих ситуаций и существуют ExpectedConditions. Вы можете с их помощью реализовать ожидания любых условий. Проще, конечно использовать существующие обёртки вроде #selenide , чтобы не изобретать велосипеды самому.

Как это вы видите? Как будет выглядеть ваш expected condition?

А мне проще скриптом дождаться окончания всех запросов и потом проверять таблицу.
В том же протракторе (на который ссылаются выше) есть функция waitForAngular, который по сути через execute_script запускает скрипт ожидания всех запросов, то есть “взаимодействует со скриптом на странице”.

а если на странице есть запросы, которые выполняются переодически? Сейчас у вас их может не быть на странице, но отбрасывать такую возможность я бы не стал. Как вы будете ждать завершения всех запросов? Такой подход концептуально не верен. Ждите элемент с помощью WebDriverWait + ExpectedConditions. Как это сделать вам расскажет гугл.

В любом случае вам выбирать, но еще раз: тело скрипта вам не получить со страницы, скрипты хранятся на веб-сервере. Хотите выполнять скрипт - храните его у себя в проекте.

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

1 лайк

Во-первых я бы не полагался на protractor для e2e тестов. Ваши девелоперы завтра решат переписать приложение на React и гудбай 100500+ тестов. Будете переписывать по новой. Вот человек пишет про боль перевода протракторовских тестов на react http://www.joelotter.com/2015/04/18/protractor-reactjs.html Можно конечно обойти вокруг всего - но зачем делать ставку на то, что может в один момент сломать все ваши тесты ? Упомяну лишь, что сам я тесты для protractorа не писал, но его использовали наши фронтэнд разработчики… до тех пор пока приложение было на angular :wink:

Буду благодарен, если расскажете как выполнить js скрипт ( имеется ввиду хранящийся в файле, например, scriptTest.js) не сохраняя его у себя.

Непонятен вопрос.
Есть свой скрипт, который лежит у меня и надо его исполнить в браузере?
Тот же execute_script c телом вышеуказанном скрипта.

Я не юзаю протрактор, из него только взял скрипт для ожидания ангуляра и только.

вы сказали, что чтобы выполнить js script, который находится на сервере ( это понятно из того, что кода скрипта нет в html, только ссылка на него, либо отсуствие ссылки как таковой из-за особенностней реализации js frameworkа) вам не нужно хранить файл со скриптом у себя. Мне интересно, как вы выполняете такой скрипт?