问题是模式本身。它使用@FindBy注释(由PageFactory用于初始化必须由代理包装的字段),用它们的包含InvocationHandler的代理实例替换标准元素。
每次尝试访问使用@FindBy注释的字段时,调用处理程序都会尝试使用默认的ElementLocator查找元素。问题是,如果存在,则ElementLocator.findElement()方法会引发TimeoutException/NoSuchElementException DOM中没有元素。
public WebElement findElement(SearchContext context) {
List<WebElement> allElements = findElements(context);
if (allElements == null || allElements.isEmpty())
throw new NoSuchElementException("Cannot locate an element using "
+ toString());
return allElements.get(0);
}
因此,每次你需要检查是否显示元素或没有你要搜索的内容的列表,并检查它的大小。
@FindBy(css = "div.custom")
private List<WebElement> elements
...
public isElementPresented(){
return elements != null && elements.size > 0
}
解决这个问题的另一种方法是创建自己的实现LocatingElementHandler和ElementLocator的
所以,如果你需要自己isDisplayed()方法返回,而不是例外假的,你必须用ElementLocator中的findElement()方法替换:
...
List<WebElement> elements = searchContext.findElements(by)
if(elements != null && elements.size() > 0){
List<WebElement> visibleElements = []
elements.each {
if(it.displayed){
visibleElements.add(it)
}
}
if(visibleElements.size() > 0){
return visibleElements.get(0)
}
}
return null
...
并将新条件添加到LocatingElemen tHandler。调用()
喜欢的东西:
element = locator.findElement()
if(element == null){
if(method.name == "isDisplayed"){
return false
}
}
如果你的问题是检查元素的可见性,这可能有所帮助:http://stackoverflow.com/questions/2646195/how-to-check-if-an-element-is-visible-with-webdriver – phtrivier
@phrivier:不,这不起作用,因为这个问题不是关于可见的,而是关于存在。 – Ralph
是否可以接受由注释注入的另一个元素(一个像root一样存在)并使用rootELement.findElements(ByWhatever).isEmpty()? – phtrivier