t.me/atinfo_chat Telegram группа по автоматизации тестирования

Ожидание отработки Ajax при проверке одного и того же элемента на странице

Теги: #<Tag:0x00007f748713e9a0> #<Tag:0x00007f748713e838> #<Tag:0x00007f748713e720> #<Tag:0x00007f748713e630> #<Tag:0x00007f748713e568>

На странице есть элемент <div>foo</div>.
По некому событию (клик на ссылку, например) идёт ajax запрос, который меняет текст внутри блока <div>bar</div>. Вот каким образом можно поставить ожидание, что запрос выполнился?
Я вижу пока только вариант, брать значение до события и в цикле проверять, что значение изменилось. Есть более правильные варианты?

  1. неявное ожидание появления/исчезновения/…/ какого-нибудь элемента
  2. JavaScript типа return jQuery.active == 0
 WebDriverWait wait = new WebDriverWait(webDriver,GlobalVariables.GlobalTimeOut);
    wait.until(new ExpectedCondition<Boolean>() {
        @Override
        public Boolean apply(org.openqa.selenium.WebDriver driver) {
            return (Boolean)((JavascriptExecutor)driver).executeScript("return jQuery.active == 0");
        }
  1. если ничего не помогает то Thread.sleep(100000)
1 Симпатия

Рискну предположить, что искомый элемент пересоздается а не просто меняет text.
В таком случае находим элемент, запускаем событие, ждем стейла (StaleElementReferenceException) найденного элемента, ищем его заново.

1 Симпатия

Похоже, так и происходит. Я немного костыльно поступил, но сработало.
Я нахожу нужный элемент (на самом деле — у меня это массив элементов), потом инициализирую событие, потом снова нахожу нужный элемент по такому же пути и внутри wait цикла жду, пока оба элемента не будут разными.

Когда-то была задача - проверять динамическое изменение статуса файла при загрузке. Т.е. если вы знаете, какой текст нужно ждать, то кастомный expected condition решит проблему:

wait.until((WebDriver driver) -> findElement(locator).getText().equals(text));

Используйте библиотеку selenide. Она сама организовывает ожидание, вам остаётся только написать $(“div”).should Have(text(“bar”));