Попытка поймать перекрытие элемента перед кликом

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

Я пытался проверять антилом через element_to_be_clickable, visibility_of_element_located, is_displayed - ничего не помогает, антил все равно пропускает проверку дальше и клик уже рейсит эксепшен

Exception text: Message: element click intercepted: Element <button type="button" class="Butt....
1 лайк

Сделай try/catch:

try {
  element.click()
} catch (error) {
  if (error.message.includes('element click intercepted')) {
      // oops, cannot click, handling somehow
  } else {
     throw error
  }
}

это костыль

Нет, это правильная обработка ошибок. Ты не можешь знать кликабельный элемент или нет на 100% пока не жмакнешь его.

Если бы такой метод и был бы, то вполне могла бы быть следующая ситуация:

expect(element.isClickable()) // all good, can click element
element.click() // oops, something covered our element between checking and actually clicking!

Команды отрабатывают не моментально, и даже между вызовами команд может изменится все что угодно, и провека ничего не даст.

Это обычная проблема во многих областях программирования. Взгляни например на документацию nodejs про аналогичную проблему то как проверить существует ли файл:

https://nodejs.org/api/fs.html#fs_fs_exists_path_callback

Метод не рекомендуется использовать, поскольку между проверкой и началом работы с файлом, файл может изменится.

почему это костыль? код не умеет сам смотреть на странице и понимать типо:

  • АГА, НАД КНОПКОЙ ПОЯВИЛАСЬ ВСПЛЫВАШКА, НАДО ЕЕ ЗАКРЫТЬ И ТОЛЬКО ПОТОМ ЖАТЬ КНОПКУ
    потому что эту логику надо описать тебе:
  • с помощью try catch проверять, кликабельный ли элемент
  • если нет, то искать локатор того, что закрывает кнопку

глазами ты делаешь тоже самое: кнопка закрыта? уберу то, что её закрывает

Не хотите try-catch, ищите перед кликом элемент который может перекрывать и пытайтесь закрыть его, но опять же, а вдруг вы ищите и его нет, а перед кликом за долю секунды он появится.
Без трай кетч придется городить огород, вот это и будет костыль.

Посмотрите, как решается аналогичная проблема со спиннером. Примеров - масса.
Общая идея проста:
try {
element.click();
}
catch (Exception e) {
popUpWindow.close()
}

Да это трэш, если сам метод клика способен зарейсить ошибку о перекрытии элемента, значит у селениума есть эта проверка внутри, ее нужно только достать и проверить до того, как попытаешься кликнуть, в смысле это не правильно? Кто же методом тыка определяет состояние? Какое то решение ради решения, есть отличные либы вроде ДрайверВейта и Сапорта, которые как раз дают доступ к подобным проверками, нужно просто человека который в этом разбирается, а не тыкает как макака в пульт управления

ещё раз
селениум не хранит в себе DOM дерево с положениями элементов друг относительно друга и z-index - ами

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

Ты не можешь знать кликабельный элемент или нет на 100% пока не жмакнешь его.

Вот самая крамольная ошибка тестировщика.
В любой момент времени вы должны точно понимать, в каком состоянии у вас сейчас DOM.
Есть всплывающее окно или нет в данный момент — надо знать. Если его появление — случайность, то перед кликом нужно проверять наличие всплывашки, а не пытаться кликнуть на кнопку и ловить исключения.

  1. “есть отличные либы вроде ДрайверВейта и Сапорта” - можно по конкретнее? Если я вас правильно понял вы имеете ввиду “ExpectedConditions.elementToBeClickable” - это проверка Enablad и Displayed и если она возвращает true, это не значит что элемент не перекрыт
  2. ElementClickInterceptedException - Эта ошибка прилетает непосредственно из драйвера(сервера) на клиент(тесты)
    https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/src/webdriver/Remote/WebDriverError.cs
    https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/src/webdriver/Remote/Response.cs
    а взаимодействие с драйвером идет только через эти команды
    selenium/W3CWireProtocolCommandInfoRepository.cs at trunk · SeleniumHQ/selenium · GitHub
    и тут нет проверки на кликабельность, это стандарт

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

В части не согласен, в современных приложениях это актуально для StaleElementReferenceException, потому что часто DOM меняется из за добавления различных компонентов, ссылка на элемент устаревает, а по бизнес логике все ок. Поэтому сейчас ищут и выполняют действие, обрабатывая все это на ошибку StaleElementReferenceException как единое целое. Очень часто бывает что между поиском и например кликом, за миллисекунды, элемент успевает устареть

Проверил, ее нет.
Пока запрос на клик дошел до браузера, она появилась, и толку что я ее проверил перед кликом?

Если появление - случайность - то проверять видимость - это значит делать ожидание. Что может быть довольно расточительным по времени запускать пуллинг на видимость элемента перед каждым кликом.

Быстрей именно пробовать кликнуть и ловить исключение и обрабатывать его. В конструкции try/catch нет ничего плохого, не зря же ее в язык добавили.

А какая причина появления рандомной всплывашки или она не рандомная? Нужно стараться сделать тест максимально линейным, например отключить всплывашку, если она не входит в сценарий теста. Если это не возможно, тогда конечно приходится изворачиваться

Есть, можно ее взять.

только между, тем как тебе driver вернет что кнопка кликабельна и ты выполниш click пройдет время и модалка может перекрыть елемент)

1 лайк

Согласен с

Все зависит от контекста, можно ее отключить/удалить/подождать, а можно кликнуть и обработать исключение, главное решить свою проблему)

У селениума нет такой проверки, там идет клик по координатам, в определенную точку элемента.

1 лайк