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

Nat*_*ill 5 java selenium webdriver

我已经使用@FindBy了一段时间了,我喜欢这个元素直到它必要时才被定位的事实(不是实例化).

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

我想写一个函数,我可以传入一个整数,它将返回一个具有适当ID的WebElement,并且是懒惰实例化的.这意味着具有以下功能将无法正常工作:

public WebElement getElement(int numOnPage){
    return driver.findElement(By.id("element"+numOnPage));
}
Run Code Online (Sandbox Code Playgroud)

因为即时我调用WebElement所定位的函数.(它无法实例化的原因是因为我有一个函数,通过一遍又一遍地调用isDisplayed()来等待元素存在,捕获NoSuchElementExceptions).

我也意识到我可以创建一个List<WebElement>通过CSS选择ID以"element"开头的每个元素,但我还有其他情况需要返回一个动态生成的元素,并且还必须在那里使用解决方法.

谢谢!

Lau*_*ntG 1

首先,我真的不明白为什么在WebElement元素真正出现在页面中之前您绝对需要获取引用。在正常情况下,您可以检查页面是否已完全加载,然后查找WebElement. 正如您提到的,首先通常会使用循环和 catch 来完成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);
            }
        });
    }
Run Code Online (Sandbox Code Playgroud)

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