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

Selenium Webdriver. Accordion element issue.

webdriver
Теги: #<Tag:0x00007f7b691958c0>

(Maxim Zaitsev) #1

Коллеги, приветствую.
Столкнулся с такой проблемой: есть веб-элемент предоставляющий собой список с раскрывающемся по клику текстом
Примерно вот такой:
http://jqueryui.com/resources/demos/accordion/default.html
В некоторых случаях мне важно узнать, в какой момент времени прекращается “движение” элемента при раскрытии и страница становится статичной. Куда копать?


(Sergey Korol) #2

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


(Maxim Zaitsev) #3

Тут следует упомянуть, что мой элемент имеет принципиальное отличие от примера, который я давал выше: а именно, есть возможность закрыть уже раскрытый список при повторном клике на него
Я использую следующий алгоритм:

  1. Клик на элемент списка для раскрытия блока с текстом
  2. Забираю текст
  3. Клик на элемент списка для закрытия блока

В п.3 возникает проблема: вместо клика на “стрелочку” идет клик на блок с текстом, связанная, как я полагаю, с тем, что элемент в этот момент еще продолжает двигаться


(Ugin Berets) #4

Может быть поможет что-то вроде этого
http://codeception.com/docs/modules/WebDriver#waitForJS


(Maxim Zaitsev) #5

Пробыл ждать окончания работы скриптов. Ошибка все равно возникает через раз. Видимо, есть микро интервал после выполнения скрипта и полной остановкой элемента


(Sergey Korol) #6

Ну так используйте официальные API аккордеона.
Достаточно передать соответствующую команду через JS executor, и будет вам счастье.

$("#accordion").accordion("option", "active", false);

П.С. Как показывает практика, с подобными JS контролами лучше взаимодействовать при помощи native, а не webdriver api.


(Maxim Zaitsev) #7

Спасибо за совет.


(Nik Sidorenko) #8

Попробуйте использовать кастомный WebDriverWait.
Главное понять какое событие нужно ждать.
Возьмём в качестве примера аккордеона на который Вы дали ссылку.
Нам нужно дождаться момента когда сворачивание одного и разворачивание другого аккордеона завершилось.
Если посмотреть на HTML, во время выполнения дааной операции, то можно увидить, что пока контролы сворачиваются/зазворачиваются, то у двух элементов “div” атрибут “style” содержит значение “display: block;”.
А когда операция заканчивается, то только у одно элемента есть это значение в атрибуте.
Таким образом можно написать такой кастомный WebDriverWait:

WebDriverWait waiter = new WebDriverWait(driver, 60, 500); waiter.until(new Predicate<WebDriver>() { @Override public boolean apply(WebDriver driver) { List<WebElement> elements = driver.findElements(By.xpath("//div[contains(@class,'ui-accordion-content') and contains(@style,'display: block;')]")); return elements.size() == 1; } });

Данный кусок кода на протяжении 60 секунд через каждые пол секунды выполняет поиск элементов по локатору. Если элементов больше или меньше 1, то он засыпает на полсекунды и потом выполняет поиск снова, если элементов 1, то он переходит к следующей операции. Если за 60 секунд на странице количество элементов попрежнему != 1, то бутет TimeoutException

Если есть вопросы или нужна помощь с ниписанием костомного wait, обращайтесь


(Goshko Nazar) #9

Вы пробовали забирать тект дожидаясь когда он будет visible на странице через wait?


(Maxim Zaitsev) #10

спасибо, буду иметь ввиду.


(Maxim Zaitsev) #11

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