我已经使用@FindBy很长一段时间了,我喜欢这样的事实:元素直到必要时才定位(而不是实例化)。
但是,网页上的任何位置都可以是某个元素的2-10,元素上的id被编号(因此第一个元素的id为"element1“,等等)
我想写一个函数,在这里我可以传递一个整数,它将返回一个带有适当ID的WebElement,和是延迟实例化的。这意味着拥有如下功能将无法工作:
public WebElement getElement(int numOnPage){
return driver.findElement(By.id("element"+numOnPage));
}因为我一调用这个函数,WebElement就被定位了。(不能实例化它的原因是,我有一个函数,通过在元素上一次又一次地调用isDisplayed()来等待元素存在,并捕获NoSuchElementExceptions)。
我还意识到我可以创建一个List<WebElement>,它可以通过CSS选择ID以" element“开头的每个元素,但在其他情况下,我希望返回一个动态生成的元素,并且必须在那里使用解决方案。
谢谢!
发布于 2013-08-04 05:26:26
首先,我不太明白为什么您绝对需要在元素真正在页面中之前获得一个WebElement引用。在正常情况下,您可以检查页面是否已完全加载,然后查找WebElement。第一种方法通常是通过循环和NoSuchElementException捕获来完成,就像您提到的那样。
但是,如果在页面中找不到WebElement之前需要对它进行引用,我只需创建一个代理,该代理将延迟加载(仅在第一次需要时)真正的WebElement实例。就像这样:
public WebElement getElement(final int numOnPage) {
return (WebElement) Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class<?>[] { WebElement.class }, new InvocationHandler() {
// Lazy initialized instance of WebElement
private WebElement webElement;
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if (webElement == null) {
webElement = driver.findElement(By.id("element" + numOnPage));
}
return method.invoke(webElement, args);
}
});
}通过调用getElement,可以检索WebElement类型的对象。一旦调用它的方法之一,就会使用WebDriver.findElement检索它。注意,如果在代理实例上调用一个方法,元素必须在页面中,否则您当然会得到一个NoSuchElementException。
发布于 2013-08-04 09:37:19
如果我正确理解了这个问题,您就不能用@FindBy注释来完成这个任务。问题是Java中的注释是在编译期间处理的,因此不能动态地修改它们:
http://docs.oracle.com/javase/tutorial/java/annotations/
但是,听起来您的问题可以很容易地通过使用显式等待来解决:
public WebElement getElement(int numOnPage){
WebDriverWait waiting= new WebDriverWait(driver, 15, 100);
return waiting.until(ExpectedConditions.visibilityOfElementLocated(By.id("element"+numOnPage)));
}这将扫描页面,等待元素的存在和可见,以及当它返回一个WebElement给您。
https://stackoverflow.com/questions/17818074
复制相似问题