Дождаться завершения всех Javascript (Angular JS)

Подскажите пожалуйста.Можно ли каким либо образом узнать завершилось ли выполнение всех скриптов на странице.?? Получить как то от браузера или еще как то.???

Приложение написано на #angularjs .
Для тестирования использую #webdriver + #python .

Проблема в том, что в тесте я нажимаю кнопку и выполняется #javascript . С сервера получаю информацию.Она запихивается в таблицу.

Есть метод в котором использую find_elements_by_tag_name (ищу там всякие th tr td в таблице).Метод отрабатывает быстрее чем данные попадут в дом.Аналогию метода find_elements_by_tag_name в классе ExpectedCondition не нашел.
Метод примерно следующий:

def get_all_rows_in_table(self, locator):
    try:
        element = WebDriverWait(self.driver, 10).until(
            EC.presence_of_element_located(locator)
        )
        rows = element.find_elements_by_tag_name("tr")
        return rows
    except TimeoutException:
        print u"Таблица не найдена"

def get_cells_text_on_table(self, row):
    list_of_text = []
    list_of_elements = row.find_elements_by_tag_name("td")
    if list_of_elements == []:
        list_of_elements = row.find_elements_by_tag_name("th")
    for cell in list_of_elements:
        if not ("ng-hide" in cell.get_attribute('class')):
            list_of_text.append(cell.text)
    return list_of_text

Когда я вызываю get_cells_text_on_table с параметром rows[1] в таблице еще нету строки с данным текстом. Я получаю, что то вида IndexOutOfRange или что искомый элмент не в доме
Ставить time.sleep(1) не хочется.

Вот и появилась идея ждать пока завершатся скрипты и тогда уже проверять, что отображается на странице.
Можно ли это сделать без всяких Protraktor-ов))) Потому, что я еще в Python новечек можно сказать,а еще и javascript пока времени нет(((

Ну я бы подождал пока загрузятся все нужные элементы на странице. Для того чтобы дождаться - нужно чётко знать какое количество их должно быть. И только после загрузки всех элемнетов проверить на нужное условие

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

Можно попробовать, но вопрос именно про завершение javascript

А можете кусочек кода, что то сразу не могу сообразить.
Я знаю например, что при нажатии на элемент должна загрузиться таблица и в ней 59 строк.

Просто если я добавлю строку в таблицу мне, что нужно метод переписывать???

Извини, но не могу сказать как в python
Пока писал на чистом java селениуме, писал while(elements.size() < 58){
sleep(200);
}
Потом уже использовал waitUntil() длинный

Ну sleep Зло…
Хочется узнать неужели никто не задавался таким вопросом…

Не зло, если тебе надо по простому решить проблему не городя логики. И плюс если у тебя хорошо устроена инкапсуляция потоков тестов.
У тебя тесты мног опоточно бегают?

Нет… Все пока запускается в консоле или из среды.Никаких потоков нету.Есть всякие PageObject + Allure + Pytest+Jenkins. В общем вопрос остается открытым

Эти все варианты я читал мне они чем то не понравилось…
Хочется именно завершения Javascript

Выполни тогда jsExecutor c командой $(document).ready()

Или уже ищи как задать ожидание определённого скрипта с помощью jQuery или чистого js

В JQuery есть (я находил на форуме), какая-то переменная, которая отвечает за количество завершенных скриптов. У меня Angular ,как я понимаю там такого нет…
В общем буду искать

1 Like

Спасибо большое буду смотреть

напишите потом что сработало для вас

мне подсказал начальник)) я в Javascript не селен. Но вроде пока работает.
Я создал файлик tools.py.В него написал страшный вот такой код:

class angular_not_active(object):
    def __call__(self, driver):
        hasAngularFinishedScript = "var callback = arguments[arguments.length - 1];\n" + \
                                " angular.element(document.body).injector().get('$browser').notifyWhenNoOutstandingRequests(callback);\n"
        driver.execute_async_script(hasAngularFinishedScript)

Во всех методах, где ждет пока отработает Javascript(angelar) я написал такое:

    def get_all_rows_in_table(self, locator):
        angular_not_active()(self.driver) ---->>>>ДОБАВИЛ ВОТ ТАКОЕ
        try:
            element = WebDriverWait(self.driver, 10).until(
                EC.element_to_be_clickable(locator)
            )
            rows = element.find_elements_by_tag_name("tr")
            return rows
        except TimeoutException:
            print u"Таблица не найдена"
1 Like

Какой ужас :slight_smile:

для Python пока похоже нету - для Java

и C#

есть порт Protractor
(для первых двух я же и последние PR сделал, можете посмотреть их upstream:

).

он делает

вот что:

var waitForAngular = function(rootSelector, callback) {
    var el = document.querySelector(rootSelector);
    try {
        if (window.getAngularTestability) {
            window.getAngularTestability(el).whenStable(callback);
            return;
        }
        if (!window.angular) {
            throw new Error("window.angular is undefined");
        }
        if (angular.getTestability) {
            angular.getTestability(el).whenStable(callback);
        } else {
            if (!angular.element(el).injector()) {
                throw new Error("root element (" + rootSelector + ") has no injector.");
            }
            angular.element(el).injector().get('$browser').
            notifyWhenNoOutstandingRequests(callback);
        }
    } catch (err) {
      callback('exception: ' + err.message);
    }
};
// var arguments = []
var log = function(message){ console.log("callback: " + message); return(message); }

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


то есть в точности то же что и “настоящий” GitHub - angular/protractor: E2E test framework for Angular apps

все работает и проблема с ожиданием окончания работы фреймворка решена.

Кстати - если нужен Python порт - могу написать - займет примерно месяц -

1 Like