一尘不染

如何返回懒惰实例化的动态Web元素

selenium

我已经使用@FindBy了一段时间了,我喜欢这样的事实:该元素直到必要时才被定位(不在实例化时)。

但是,该网页可能具有某个元素2-10的任意位置,并且元素上的ID已编号(因此第一个元素的ID为“ element1”,依此类推)

我想编写一个函数,我可以在一个整数关口,它会返回一个WebElement与适当的ID, 被懒洋洋地实例化。这意味着具有以下功能将无法正常工作:

public WebElement getElement(int numOnPage){
    return driver.findElement(By.id("element"+numOnPage));
}

因为我立即调用该函数,即可找到WebElement。(之所以不能实例化它的原因是因为我有一个函数,可以通过在其上反复调用isDisplayed()来捕获NoSuchElementExceptions
,直到该元素存在为止。)

我还意识到,我可以创建一个List<WebElement>通过CSS选择ID以“ element”开头的每个元素的a
,但是在其他情况下,我想返回一个动态生成的元素,并且还必须使用一种变通方法。

谢谢!


阅读 256

收藏
2020-06-26

共1个答案

一尘不染

首先,我不太了解为什么您绝对需要WebElement在元素真正出现在页面中之前获得引用。在正常情况下,您可以检查页面是否已完全加载,然后查找WebElementNoSuchElementException如前所述,通常首先使用循环和捕获来完成。

但是,如果需要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。请注意,如果在代理实例上调用方法,则该元素必须在页面中,否则当然会得到a
NoSuchElementException

2020-06-26