Как проверить что элемент не перекрывает другой?

У меня есть проблемные кнопки на странице, которые иногда не нажимаются с первого раза. Хотя селенид думает что нажал их. Обходным решением для этого я сделал переодическое нажатие на кнопку пока она не исчезнет

while ($(By.xpath(field)).exists()& $(By.xpath(field)).is(Condition.visible)&$(By.xpath(field)).is(Condition.enabled)){
                    $(By.xpath(field)).click();
                    sleep(500);

И для одного случая этого хватает, но появился другой случай, когда после нажатия на кнопку появляется попап и условия для while остаются true, НО далее все падает по ElementClickInterceptedException, оно и логично его перекрывает попап, но селенид все равно считает что элемент visible, enabled! Я пытался словить это исключение и меня бы это устроило, но оно не отлавливается даже когда я ставил самое высокоуровневое Exeption!

            while ($(By.xpath(field)).exists()& $(By.xpath(field)).is(Condition.visible)& $(By.xpath(field)).is(Condition.enabled)){
                try {
                    $(By.xpath(field)).click();
                    slepeeeLong(500);
                }catch (ElementClickInterceptedException e){
                    return;
                }
            }

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

У селенида или селениума такой проверки нет, насколько я знаю. И в целом её сложно реализовать и даже определить (что, если 49% пикселей перекрыто?)

Ваш подход в целом мог бы быть рабочий, только одна ошибка в этой фразе:

самое высокоуровневое Exeption
Подсказка: ловить там надо не ElementClickInterceptedException. См. также Как надругаться над Селенидом

НО
и это делать не нужно, т.к. селенид внутри и сам делает такой же try/catch в цикле.

В вашем описании остаётся неясным вот этот момент:

НО далее все падает по ElementClickInterceptedException

Далее - это в результате какого действия? Чтобы это случилось, вы ведь должны были сделать ещё какой-то следующий клик, верно? Тогда логично, что try/catch вокруг первого клика не поможет.

1 лайк

Я делаю вот такую манипуляцию

            $(By.xpath(field)).shouldBe(Condition.enabled, Duration.ofSeconds(55)).click();
            while ($(By.xpath(field)).exists()& $(By.xpath(field)).is(Condition.visible)& $(By.xpath(field)).is(Condition.enabled)){
                try {
                    $(By.xpath(field)).click();
                    slepeeeLong(500);
                }catch (Throwable e){
                    return;
                }
            }

Сначала обязательно нажимаю кнопку, а затем отталкиваясь от состояния кнопки снова могу нажать если она активна. А если над ней появился попап(что мне и нужно), тогда я ловлю Throwable и заканчиваю цикл нажатий. И меня сейчас этот вариант спас. Спасибо вам за подсказку!

В целом да, такое решение ловит ваш попап, но оно имеет некоторые недостатки.
Например, каждый раз при падении метода click() селенид делает скриншот и тратит лишние 4 секунды (или какой там у вас таймаут) на ненужное ожидание.
Лучше всё-таки избавляться от подобных циклов и условий.

P.S. И ловить catch (Throwable e) в целом плохая практика. Ведь под этим Throwable может скрываться и NullPointerException, и OutOfMemoryError, и ClassNotFoundException. Ловить надо только ту ошибку, которая вас интересует. В крайнем случае AssertionError.