流利等待不忽略异常

Fluent wait not ignoring exceptions

我正在使用流畅的等待,所以我可以在特定时间内忽略某些异常,尤其是 ElementClickInterceptedException 这就是我声明等待的方式:

private Wait<WebDriver> initiateWebDriverWait(int timeoutSeconds) {
        List allExceptions = new ArrayList();
        allExceptions.add(NoSuchElementException.class);
        allExceptions.add(ElementNotVisibleException.class);
        allExceptions.add(StaleElementReferenceException.class);
        allExceptions.add(ElementClickInterceptedException.class);

        return new FluentWait<>(driver)
                .withTimeout(Duration.ofSeconds(timeoutSeconds))
                .pollingEvery(Duration.ofMillis(100))
                .ignoreAll(allExceptions);
    }

用法:

    public void waitForElementThenClick(WebElement webElement, int timeOutSeconds) {
        waitForElementToBeClickable(webElement, timeOutSeconds);
        webElement.click();
    }


    public void waitForElementToBeClickable(WebElement webElement, int timeoutSeconds) {
        Wait<WebDriver> wait = initiateWebDriverWait(timeoutSeconds);
        wait.until(ExpectedConditions.elementToBeClickable(webElement));
    }

所以当我使用 waitForElementThenClick 时,我仍然得到

org.openqa.selenium.ElementClickInterceptedException: element click intercepted: Element ... is not clickable at point (1338, 202). Other element would receive the click:

这是一些随机叠加层,只存在很短的时间,我可以添加 100 毫秒的等待时间等等,但我的主要问题是为什么我什至看到了这个异常,当我特别说到忽略它至少 5 秒?而且它没有等待这 5 秒,所以这不是超时的事情。

有什么想法吗? 是 webElement.click();抛出异常?如果是,为什么 waitForElementToBeClickable 返回 true?

谢谢

如果 webdriver 说该元素是可点击的,并不总是意味着该元素真的是可点击的。可能是目标元素被另一个元素覆盖时。 这是一个例子。打开 https://whosebug.com/jobs?so_medium=Whosebug&so_source=SiteNav 。让我们尝试检查此元素是否可点击并点击它:

但是,我们将这个元素隐藏在下拉列表中,如下所示:

存在xpath:By.xpath("//*[text()='Developer jobs']")

因此,如果我们检查此元素的条件 ExpectedConditions.elementToBeClickable,它将 return 为真(例如元素可点击)。但是当您执行 element.clickm 时,您将发生 ElementClickInterceptedException。

只有在 until 等待条件为真时才会考虑例外列表。 click() 在那之后发生,所以没有什么可以捕获 ElementClickInterceptedException.

elementToBeClickable 检查元素是否可见,如果元素的一部分可见,则为 true,如果元素已启用,则为 true,除非它具有明确的 disabled 属性,但 Selenium 会尝试单击可能被覆盖的元素的中间。要通过这个问题你可以等待覆盖消失然后等待元素可点击

wait.until(ExpectedConditions.invisibilityOfElementLocated(ovferlayLocator));
waitForElementThenClick();