Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何返回延迟实例化的动态webelement_Java_Selenium_Webdriver - Fatal编程技术网

Java 如何返回延迟实例化的动态webelement

Java 如何返回延迟实例化的动态webelement,java,selenium,webdriver,Java,Selenium,Webdriver,我使用@FindBy已经有一段时间了,我喜欢元素在必要时才被定位(不是在实例化时) 但是,网页可能有2-10个特定元素,并且元素上的id已编号(因此第一个元素的id为“element1”,以此类推) 我想写一个函数,在这里我可以传递一个整数,它将返回一个具有适当ID的WebElement,并且是延迟实例化的。这意味着具有以下功能将不起作用: public WebElement getElement(int numOnPage){ return driver.findElement(By.

我使用
@FindBy
已经有一段时间了,我喜欢元素在必要时才被定位(不是在实例化时)

但是,网页可能有2-10个特定元素,并且元素上的id已编号(因此第一个元素的id为“element1”,以此类推)

我想写一个函数,在这里我可以传递一个整数,它将返回一个具有适当ID的WebElement,并且是延迟实例化的。这意味着具有以下功能将不起作用:

public WebElement getElement(int numOnPage){
    return driver.findElement(By.id("element"+numOnPage));
}
因为在我调用该函数的那一刻,WebElement就被找到了。(无法实例化它的原因是因为我有一个函数,它通过反复调用isDisplayed()来等待元素存在,并捕获
NoTouchElementException
s)

我还意识到,我可以创建一个
列表
,通过CSS选择ID以“element”开头的每个元素,但在其他情况下,我希望返回一个动态生成的元素,并且必须在那里使用变通方法


谢谢

首先,我真的不明白为什么在元素真正进入页面之前,您绝对需要获得
WebElement
引用。在正常情况下,您可以检查页面是否已完全加载,然后查找
WebElement
。正如您所提到的,第一种方法通常是使用一个循环和一个catch for
NoTouchElementException

但是,如果在页面中找不到
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);
            }
        });
    }
公共WebElement getElement(最终整数页){
return(WebElement)Proxy.newProxyInstance(this.getClass().getClassLoader(),新类[]{WebElement.Class},新调用处理程序(){
//WebElement的延迟初始化实例
私有WebElement WebElement;
公共对象调用(对象代理、方法、对象[]参数)
扔掉的{
if(webElement==null){
webElement=driver.findElement(By.id(“元素”+numOnPage));
}
invoke(webElement,args);
}
});
}

通过调用
getElement
,可以检索
WebElement
类型的对象。只要调用其中一个方法,就会使用
WebDriver.findElement
检索它。请注意,如果在代理实例上调用方法,元素必须在页面中,否则您当然会得到一个
NoSuchElementException

如果我正确理解了这个问题,那么@FindBy注释就不能这样做。问题在于Java中的注释是在编译时处理的,因此您不能动态修改它们:

不过,听起来您的问题可以通过使用显式等待轻松解决:

public WebElement getElement(int numOnPage){
    WebDriverWait waiting= new WebDriverWait(driver, 15, 100);
    return waiting.until(ExpectedConditions.visibilityOfElementLocated(By.id("element"+numOnPage)));
}

这将扫描页面,等待元素存在并可见,以及当它返回WebElement给您时。

原因是我有一个函数,在该函数中我反复调用isDisplayed()(带有try/catch)…但是如果我传入从getElement()返回的元素,而该元素还不存在,则getElement()将在异常到达等待它存在的函数之前抛出异常。非常感谢。