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

Как дождаться ответа на POST запрос при нажатии на кнопку

python
webdriver
Теги: #<Tag:0x00007f7b63128348> #<Tag:0x00007f7b63128190>

#1

Добрый день. Проблема следующая: при нажатии на кнопку происходит POST-запрос, но т.к. нажатие - это последнее действие в сценарии, то ответ может быть не получен и фактически действие в приложении не завершится, соответственно остальные шаги в тесте провалятся.

Если использовать после нажатия ожидание в 1 сек, то всё работает. Есть ли альтернативные методы ожидания получения ответа на запрос?
ожидание “return jQuery.active == 0” не помогает


(Stan) #2

А что, после нажатия на странице ничего не меняется?


(Sergey Korol) #3

А как вы его используете в коде?


#4

На самой странице нет, кнопка также доступна для повторного нажатия. Совершенное действие после нажатия увидит только пользователь с другой ролью.


#5

использую сразу после нажатия на кнопку

button.click()
while True
    if self._driver.execute_script("return jQuery.active==0")
        break

(Stan) #6
  • в примере опечатка? ("return jQuery.activ==0")
  • почему не wait.until ? как-то вроде
WebDriverWait(driver, 15).until(
   lambda driver: driver.execute_script('return jQuery.active;') == 0
)
  • пытались вывести что возвращает jQuery.active ? Точно там никаких проблем?
  • у вас точно используется jquery? (на всякий случай :smiley: )

#7
  • Да, опечатка)
  • через WebDriverWait не пробовал, не знал, что его можно еще так применить.
  • выводил - 0. Если ставить ipdb, то к тому времени как он сработает “return jQuery.active;” уже вернет 0
  • недавно на проекте, но думаю да, frontend написан на javaScript :smile:

(rmerkushin) #8

То что он написан на JS еще не факт что jQuery :slight_smile: Ну и как писали выше, у вас после получения ответа что то изменяется на странице? Если да, то ожидание нужно привязывать уже на два события, и проверять что оба условия - true.


#9

Внешне на странице ничего не меняется.
Про jQuery согласен :slight_smile: Лучше уточню у программистов, что они используют.


(Сергей Блохин) #10

Как вы, когда тестируете вручную, узнаёте, что Ajax запрос прошёл спешно?


#11
  • На странице пользователя одной ролью, при нажатии, в консоли появляется сообщение вида:
    RqCheck: for order: 421
    и ответ:

    mq.js:1181 request: call for service 2 for order: 421
    mq.js:1203 ** requestService: returned: {“id”:1293,“status”:0}

  • На странице пользователя с другой ролью, приходит сообщение, что совершено действие

  • В проекте используется jQuery и не помогло

WebDriverWait(driver, 15).until( lambda driver: driver.execute_script('return jQuery.active;') == 0 )


(Ray Romanov) #12

“return $.active;” попробуй.


#13

тоже нет


#14

добрался до кода приложения:

function requestService(id, serviceRq) 
{	
console.log('request: call for service ' + serviceRq + ' for order: ' + id);
console.log(jQuery.active);
if (!id)
{
	var activePos = getActivePos(null);
	id = gDat.orders.oData[activeOPos].id;
}
console.log(jQuery.active);
var denId  = getDenId(id);

var oRequest = { type : serviceRq, o_id : id, den_id : denId };
console.log(jQuery.active);
call_method('setEvents', oRequest, function(msg) {
	console.log("** requestService: returned: " + JSON.stringify(msg));
	console.log(jQuery.active);
});
};

вывод jQuery.active следующий: 0, 0, 0, 1
Получается, что выход из WebDriverWait срабатывает уже на первом 0


(Ray Romanov) #15

ИМХО Тогда, принудительное ожидание 1 сек. после клика, а потом проверка jQuery.


(Михайленко Владимир) #16

Возможно вас направит реализация в Protractor . Это надстройка над Webdriver-ом. В ней, например, клик происходит только когда все запросы дождались ответов.
https://github.com/bbaia/protractor-net/blob/master/src/Protractor/NgWebElement.cs (C#) строка 50, например, ждем все ответы.


(Stan) #17

Пробовали ждать document.readyState === 'complete' ? Или даже вместе jQuery.active + document.readyState (хотя чисто теоретически если readyState != 'complete', active не может быть == 0).

Судя по https://github.com/jquery/jquery/blob/239169bb2ede6ea6287d82d1d13b0c354f451749/src/ajax.js active этого не проверяет, только смотрит есть ли ajax запросы и сколько их.


#18

document.readyState === 'complete'
на всем протяжении возвращает true


#19

Так проверьте, ловит ли Селениум лог в консоли (по крайней мере, с FF должно работать, а вот с Хромом были проблемы).

  1. При создании браузера добавляем капабилити для логирования:

    driver = webdriver.Firefox(capabilities = {“webdriver.log.driver”: “ALL”})

  2. Получаем логи:

    driver.get_log(‘browser’)

Возвращает список из словарей с полями “timestamp”, “message”, “type”, “level”. Причем только последние, которые еще не отдавались по запросу get_log(). Поэтому перед вызовом POST-а можно 1 раз этот метод вызвать, чтобы буфер был почище :smile:


#20

Для моей задачи, пока это единственное альтернативное решение принудительному ожиданию. Всем спасибо за помощь :smiley: