Задать вопрос
@vlatek
Digital Nomad

Как сэмулировать клик по кнопке (Selenium, JS, Python, Chrome)?

Задача сэмулировать клик по кнопке «Проверено» на хитром UX. button “Проверено» имеет свойство срабатывать при клике правой кнопкой мыши, как и левой кнопкой. С button «В брак» такого нет. Все элементы с динамическими атрибутами, поэтому был сделан скрипт поиска элемента по тексту в нем .

В Selenium click() не срабатывает ни по какой кнопке. Пробовал реализовать через driver.find_element_by_partial_link_text;
Цепочки событий ActionChains(driver);
driver.find_elements_by_css_selector;
с дальнейшим click() по элементу, не сработало нигде на этих страницах

Тогда я воткнул JS код через driver.execute_script и это сработало, везде кроме button “Проверено»

setTimeout(function() {
      let link = document.querySelectorAll('label'); 
      link = Array.from( link ).filter( e => (/Элемент1/i).test( e.textContent ) );
      link[0].click(); 
    });


или такой вариант , равнозначный.

const buttonNodes = document.getElementsByTagName('label')
const links = Array.from(buttonNodes).filter(e => (/Элемент1/i).test( e.textContent ))
links[0].click()


Скрипт ищет все элементы по тегу, добавляет в массив, фильтрует и кликает.

Меняем тег и текст, все прекрасно работает на кнопках «В брак» и «ок». Но не работает с проверено, хотя outerHTML одинаковый по структуре

const buttonNodes = document.getElementsByTagName('button')
const links = Array.from(buttonNodes).filter(e => (/В брак/i).test( e.textContent ))
links[0].click()


OuterHTML кнопки проверено

<button class="x-btn-text" type="button" style="position: relative; width: 94px;" tabindex="0" aria-disabled="false">Проверено<img onload="this.__gwtLastUnhandledEvent=&quot;load&quot;;" src="%D0%A1%D0%9F%D0%9E%20%D0%A1%D0%90%D0%A4%D0%90%D0%9F_files/clear_002.gif" style="width: 24px; height: 24px; background: rgba(0, 0, 0, 0) url(&quot;https://192.168.80.2:6780/WebModule/vf2011/01B9092B7306E43EFF062BE4A1F4F390.cache.png&quot;) no-repeat scroll -798px -192px; position: absolute; left: 0px; top: 4px;" role="presentation" class=" x-btn-image" border="0"></button>


OuterHTML кнопки в брак

<button class="x-btn-text" type="button" style="position: relative; width: 94px;" tabindex="0" aria-disabled="false">В Брак<img onload="this.__gwtLastUnhandledEvent=&quot;load&quot;;" src="%D0%A1%D0%9F%D0%9E%20%D0%A1%D0%90%D0%A4%D0%90%D0%9F_files/clear_002.gif" style="width: 24px; height: 24px; background: rgba(0, 0, 0, 0) url(&quot;https://192.168.80.2:6780/WebModule/vf2011/01B9092B7306E43EFF062BE4A1F4F390.cache.png&quot;) no-repeat scroll -798px -168px; position: absolute; left: 0px; top: 4px;" role="presentation" class=" x-btn-image" border="0"></button>


console.log(typeof links[0]) выдает Object

console.log(links[0] instanceof(HTMLElement)) выдает False
Такой же ответ выдается и на кнопке «В брак», хотя она срабатывает.

Передавал в Python return links[0] , запрашивал принт элемента, его координаты и размер, вот что сообщает:

<selenium.webdriver.remote.webelement.WebElement (session="052cc0daa6975bc23282c08ce26fc5fa", element="106630e2-439a-4e47-b03f-d4fb6641ec46")> 1592 650 {'height': 32, 'width': 94}

Пробовал также сделать в Selenium эмуляцию клика со сдвигом по пикселям через move_to_element , move_by_offset, бесполезно

Какие идеи? Сделать клик по пикселям в JS? На крайняк эмулировать клавиши Tab и Enter, что замедлит работу аппы во много раз (более 30 событий нужно + все поедет при правках UI) и тоже не факт что сработает.
  • Вопрос задан
  • 2249 просмотров
Подписаться 1 Простой 2 комментария
Решения вопроса 1
@vlatek Автор вопроса
Digital Nomad
Оказалось что фронт собирали на GWT, да так криво получилось, что событие висит только на mousedown на родителе пятого поколения кнопки button O_O Этот родитель является таблицей в которой вложено еще несколько десятков "пустых" элементов.
Проблему решил таким JS костылем:

var buttonNodes = document.getElementsByTagName('button') //ищем все элементы по тегу
var links = Array.from(buttonNodes).filter(e => (/Проверено/i).test( e.textContent )) //ложим в массив и фильтруем по тексту в кнопке
var link= links[0] //выделяем первый найденный элемент
parent = link.parentNode;  //ищем родителей
parent2 = parent.parentNode;
parent3 = parent2.parentNode;
parent4 = parent3.parentNode;
parent5 = parent4.parentNode;
var clientRect = parent5.getClientRects() //выделяем координаты элемента
clientX = clientRect[0].x
clientY = clientRect[0].y
var o = document.createEvent('MouseEvents'); //создаем событие по координатам
o.initMouseEvent( 'mousedown', true, true, window, 1, 0, 0, clientX, clientY, false, false, true, false, 0, null );
parent5.dispatchEvent(o);
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы