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

Вейт на кликабельность/завершение JSа для селенида

selenide
Теги: #<Tag:0x00007f7b621f9cc8>

#1

У меня есть несколько попап форм в проекте, в которых код кнопку распознает в некоторых ранах(компилах) а в некоторых нет. Причем в произвольном порядке(и раны и формы).

Код: $("[role=‘dialog’]").should(appear).$(“button”).should(appear).click();

Логи:
Element not found {button}
Expected: exist

На скринах видна форма

Версии ОС и софта следующие:
Хром последний, силенид 4.5.1, silenium 3.4.0

P.S. Можете если не сложно подсказать какие аргументы бывают у методов should, shouldBe


(Yuri Kalinin) #2

Привет!
Кажется, что локатор по которому ты ищешь этот элемент не уникальный.
Такое поведение чаще всего указывает на это =)


#3

Спасибо за совет, но дело не в этом.
Попап появляется с анимацией(код видимо нажимает на кнопку, когда она еще не стала кликабельной). Соотвесвенно нужен вейт, который будет ждать пока элемент станет кликабельным(такого функционала в селениде не нашел), но нашел метод для селениума:
WebDriverWait wait = new WebDriverWait(driver, 10);

wait.until(ExpectedConditions.elementToBeClickable())
но для него нужно явно вызывать драйвер(явно вызывать который в селениде я тоже не умею)


(Yuri Kalinin) #4

Предположу, что всё таки ошибка “Element not found” означает что он его честно не нашёл.
Есть цепочка локаторов $("[role=‘dialog’]").$(“button”)
Если искать одним локатором [role=‘dialog’] button, то кнопка найдётся.
Если отдельно, то (я предполагаю, не знаю как точно работает селенид) сначала мы найдём всё, что ищется по _[role=‘dialog’] _, выберем первый элемент и уже в его контексте будем искать button.

Чтобы это проверить открой попап и в js консоли набери


Если найдётся больше одного элемента - то значит проблема тут.


#5

Спасибо, но как оказалось ошибка относилась к коду, который следовал за кнопкой(после того как скрипт кликал на кнопку, которая еще до конца не появилась, он пытался найти элемент за незакрывшейся формой - вот и ошибка). А дело действительно оказалось в анимации. Я поставил слип и все заработало.
Вопрос по прежнему остается открытым - как подождать кликабельность кнопки в селениде.

P.S. И выбило действительно только один - https://www.screencast.com/t/OUeAcLQYW


#6

Попробуй найти какой-то элемент на форме или атрибут кнопки, который появляется/пропадает последним (по окончании анимации) и в тесте жди появления/пропадания этого элемента. Потом кликай свой элемент.
Condition elementToBeClickable лично мне никогда не помогал, но можешь ради эксперимента попробовать подождать - драйвер можно достать в селениде либо в WebDriverRunner, либо WebDriverProvider статический метод есть (точно не помню)


(Nikita) #7

сделай через FluentWait клик на кнопку и затем проверку того, что должно отобразиться после кнопки, если проверка не пройдена, пробуй ещё раз кликнуть, если всё плохо упадёшь по таймауту.

я обычно делаю так:

boolean isSuccess = ActionWait.withTimeout(30, TimeUnit.Second)
.withPoolingEvery(1, TimeUnit.Second).safeCall(o -> {
    $(yourProblemButton).click();
  return $(notification).isVisible();
}).isSuccess();

В течении 30 секунд, с интервалом в одну секунду кликать на кнопку и проверять появилась ли нотификация.


#8

Спасибо всем за советы :slight_smile:
Но я все-таки нашел, как получить драйвер из селенида(WebDriverRunner.getWebDriver()), вставил в код - и все заработало:

WebDriverWait wait = new WebDriverWait(WebDriverRunner.getWebDriver(), 10);
wait.until(ExpectedConditions.elementToBeClickable($("[role=‘dialog’]").$(“button”)));


(vmaximv) #9


по факту вы просто добавили небольшой слип, т.е. сделали тест более flaky.