Selenium and AngularJS тестиривание application. Wait until page loads

selenium
angularjs
java
Теги: #<Tag:0x00007fedc4194c68> #<Tag:0x00007fedc4194b28> #<Tag:0x00007fedc41949e8>

(Ilya G) #1

Всем привет. Кто-нибудь тестировал #angularjs and #selenium если до то не подскажете как вы ждали чтоб полностью страница загрузилась?


(brbrr) #2

protractor - Это то что вам нужно.

Я сделаю допущение, что вопрос возник не просто потому что вы не гуглили, а потому что вы не пишите тесты на JS.

У меня подобная ситуация на проекте. 3 приложения написаны на GWT, 1 - на Angular. Долго думал, стоит ли мне браться за JS, или продолжать на ruby. Пришел к выводу что использовать ruby - это городить костыли для того что уже отлично работает изкоробки для JS.

Если ваш проект состоит ТОЛЬКО из angular приложения - я вам рекомендую использовать именно протрактор. Он удобен, и приятен, очень не много действий требуют каких то специфичных ожиданий, есть нюанс с дебагом и не привычной асинхронностью - но к этому быстро привыкаешь.


(Ilya G) #3

Не хотелось бы писать на JavaScript, да и не знаю его. Пытаюсь найти как люди имплементировали это на Selenium. нашел на Git как добрые лиди выташили из протрактора все методы которых нет в selenium и написали на Java все через JavaScriptExecutor Пытаюсь чтоб заработало на моем коде, пока тоже никак. и не только гуглил, у нас в компании уже сть проект на протракторе, но не хочется писать на JavaScript, Java ближе будет
https://github.com/paul-hammant/ngWebDriver


(brbrr) #4

Да, я вас понимаю. Но как по мне язык програмирования - это иструмент. А инструменты можно менять, для разных задач :slight_smile: Что бы писать на нем тесты - в принципе достаточно курса на Codecademy. А также знание других языков и подходов - хороший и полезный опыт.


(Roma Marinsky) #5

Если тебе ближе Java, то попробуй писать тесты с помощью Selenide - это удобная обёртка над селениумом, которая умеет умно ждать изменений на странице

Если что обращайся в скайп: newromik
И присоединяйся в Slack чат к опытным автоматизаторам, поможем всей кучей: https://software-testers.herokuapp.com/


(Дмитрий Мирошник) #6

Принципиально это делается по-другому.
Ты не ждёшь, пока загрузится страница, а ждёшь, пока загрузятся необходимые тебе элементы. Почитай про implicit и explicit waits. Используй Visible в качестве условия для завершения ожидания.
Если необходимо по какой-то причине дождаться, пока отработают все ajax запросы - используй ExecuteScript.
Если лень разбираться - используй Selenide. Он это всё умеет из коробки.


(Taras) #7

нету такого механизма, есть костили... например loadedCriteria написать для каждого пейдж обджекта и в Page Factory initElements засунуть, перед тем подождать пока js page load complete не отпашет и проверить что все собития подгрузились - есть такое вот еще решение http://www.ontestautomation.com/using-the-loadablecomponent-pattern-for-better-page-object-handling-in-selenium/


(Ilya G) #8

Интересно как узнать какой aJax запрос мне надо ждать? Visible не помогает,потому что все элементы видны , а действия над ними призводить нельзя пока не зокончатся все запросы(примерно 1 сек) никогда не работал раньше с AngularJS... пробовал такое:

 public void waitForJQuery(WebDriver driver) {
        (new WebDriverWait(driver, 10)).until(new ExpectedCondition<Boolean>() {
            public Boolean apply(WebDriver d) {
                JavascriptExecutor js = (JavascriptExecutor) d;
                return (Boolean) js.executeScript("return jQuery.active == 0");
            }
        });
    }

но выдает exception
WebDriverException: unknown error: jQuery is not defined и ругается на это return jQuery.active == 0

Есть соображения?


(Ilya G) #9

спасибо @Roma_Marinsky, @Defender, хотелось бы с Selenium сначало разобраться... а следующий проект можно и selenoidy учиться. хотя до этого selenium не подводил не разу)


(Дмитрий Мирошник) #10

Есть. Эксепшен возникает потому, что данная переменная не определена на странице в тот момент времени, когда ты её запрашиваешь.
Вот отсюда можно попробовать эту функцию как дополнительное условие:
userWindow.Ajax.activeRequestCount == 0;
Для того, чтобы избежать эксепшена, посмотри здесь
Есть ещё 1 идея. Посмотри реализацию waitForAngularRequestsToFinish() Вот тут. Или можешь просто подключить данный фреймворк, если лень разбираться :wink:


(Xasatx) #11

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


(Антон) #12

Есть похожая проблема. На проекте идет обновление приложения и новый функционал во многом написан с использованием AngularJS. В итоге на наборе новых страниц при сохранении формы ChromeDriver просто вешается и чего-то бесконечно ждет, в то время как FirefoxDriver спокойно себе проходит дальше.
Кто-то встречался с чем-то подобным?


(Mykhailo Poliarush) #13

https://github.com/emanlove/SeConf2015/blob/master/SeConf2015_EdManlove_Dealertrack.pdf


(Сергей Кузьмин) #14

попробуйте java порт Protractor:


(https://github.com/caarlos0/jProtractor)
и

(https://github.com/henrrich/jpagefactory)

все Angular локаторы по умолчанию
делают

this.driver.waitForAngular();

который делает

/* Wait until Angular has finished rendering and has
 * no outstanding $http calls before continuing.
 * arguments[0] {string} The selector housing an ng-app
 * arguments[1] {function} callback
 */
var waitForAngular = function(rootSelector, callback) {
    var el = document.querySelector(rootSelector);
    try {
        if (window.getAngularTestability) {
            window.getAngularTestability(el).whenStable(callback);
            return;
        }

....
var rootSelector = arguments[0] || 'document';
var callback = arguments[1] || log;

waitForAngular(rootSelector, callback);

работает во всех браузерах


(Andrew Kravchuk) #15

Этот код плох сразу с нескольких сторон:
1) document.querySelector('document') - это null, в случае, если rootSelector неизвестен, нужно брать "html"
2) window.getAngularTestability не определено в Angular 1.x

Проще уж выдрать соответствующий JS из ngWebDriver, который был выше по треду.


(Сергей Кузьмин) #16

и ngWebdriver и jProtractor используют пркатически одинаковый javascript
который изначально взят из Angulat Progractor
он работает хорошо с Angular 1.x (я один из разработчиков jProtractor).