我需要检查页面上某个元素的可见性。
我正在使用(psuedocode)wait.until(ExpectedCondition.visibilityOfElement(locator));
但是,默认的ExpectedCondition仅检查DOM中与定位器匹配的第一个元素。
我的定位器不能足够具体,只能匹配一个元素(这是我被要求自动化的限制,不能更改)。但是,在找到的元素中,任何显示的都是公平的游戏。
因此,我使用自定义的ExpectedCondition,遍历找到的元素,找到显示的任何元素,并返回找到的第一个元素。
代码如下:
public WebElement WaitForElementToBeVisible(WebDriver theDriver, By locator) {
return new WebDriverWait(theDriver, STANDARD_WAIT_TIME)
.pollingEvery(1, TimeUnit.SECONDS)
.withTimeout(5, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class)
.until((ExpectedCondition<WebElement>) driver -> {
List<WebElement> els = driver.findElements(locator);
for (WebElement el : els) {
try {
if (el.isDisplayed()) {
return el;
}
} catch (StaleElementReferenceException e) {
/* Ignore Exception */
} catch (NullPointerException e) {
System.out.println("NullPointerException thrown");
}
}
return null;
});
}
但是,在某些情况下,对el.isDisplayed的调用将引发NullPointerException。我在其他答案中看到,如果元素不在页面上,则将发生这种情况。但是在这种情况下,我知道该元素存在。
我添加了一些日志,告诉我:
该元素存在(实际上,其中有三个)
在所有三个元素上调用isDisplayed
这三个元素都抛出NullPointerException
另外,由于它需要等待5秒钟才能显示该元素,因此我有足够的时间查看和看到,是的,该元素似乎确实已显示。
如果删除catch块,则NullPointerException的堆栈跟踪如下(仅最后一行,因为其他所有内容都是公司特定的,而我的老板不希望我共享它):
java.lang.NullPointerException
at org.openqa.selenium.remote.RemoteWebElement.isDisplayed(RemoteWebElement.java:323)
该跟踪导致:
public boolean isDisplayed() {
Object value = execute(DriverCommand.IS_ELEMENT_DISPLAYED, ImmutableMap.of("id", id))
.getValue();
try {
return (Boolean) value;
} catch (ClassCastException ex) {
throw new WebDriverException("Returned value cannot be converted to Boolean: " + value, ex);
}
}
该错误由return语句引发,因此无论出于何种原因,execute命令都将返回null。
我相信这些是pom文件的相关部分:
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.10.0</version>
</dependency>
<dependency>
<groupId>io.github.bonigarcia</groupId>
<artifactId>webdrivermanager</artifactId>
<version>3.6.2</version>
</dependency>
任何调试此问题的帮助将不胜感激。
最佳答案
根本问题似乎是ChromeDriver 77版本中的错误。
我正在此上运行的Salesforce正在修改内置AsyncFunction对象的构造函数,这导致所有Selenium的Javascript调用失败,而不仅仅是isDisplayed。
应该在Chrome / ChromeDriver的版本78中修复。
参考错误和答案:
https://bugs.chromium.org/p/chromedriver/issues/detail?id=3103#c6