流利等待不忽略异常
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.click
m 时,您将发生 ElementClickInterceptedException。
只有在 until
等待条件为真时才会考虑例外列表。 click()
在那之后发生,所以没有什么可以捕获 ElementClickInterceptedException
.
elementToBeClickable
检查元素是否可见,如果元素的一部分可见,则为 true
,如果元素已启用,则为 true
,除非它具有明确的 disabled
属性,但 Selenium 会尝试单击可能被覆盖的元素的中间。要通过这个问题你可以等待覆盖消失然后等待元素可点击
wait.until(ExpectedConditions.invisibilityOfElementLocated(ovferlayLocator));
waitForElementThenClick();
我正在使用流畅的等待,所以我可以在特定时间内忽略某些异常,尤其是 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.click
m 时,您将发生 ElementClickInterceptedException。
只有在 until
等待条件为真时才会考虑例外列表。 click()
在那之后发生,所以没有什么可以捕获 ElementClickInterceptedException
.
elementToBeClickable
检查元素是否可见,如果元素的一部分可见,则为 true
,如果元素已启用,则为 true
,除非它具有明确的 disabled
属性,但 Selenium 会尝试单击可能被覆盖的元素的中间。要通过这个问题你可以等待覆盖消失然后等待元素可点击
wait.until(ExpectedConditions.invisibilityOfElementLocated(ovferlayLocator));
waitForElementThenClick();