如何返回一个延迟实例化的动态webelement [英] How to return a lazily-instantiated dynamic webelement
问题描述
我一直在使用 @FindBy
一段时间了,我喜欢这个元素直到必要时才会找到(不是实例化)。
I've been using @FindBy
for a while now, and I love the fact that the element doesn't get located until its necessary (not on instantiation).
但是,网页可能有2-10个特定元素,并且元素上的id已编号(因此第一个元素的id为element1 等等)
However, the webpage may have anywhere from 2-10 of a certain element, and the id's on the elements are numbered (so the first element has an id of "element1" and so forth)
我想编写一个函数,我可以传入一个整数,它将返回一个具有相应ID的WebElement, AND 懒惰地实例化。这意味着具有以下功能将无效:
I would like to write a function where I can pass in an integer, and it will return a WebElement with the appropriate ID, AND is lazily instantiated. That means having a function like the following won't work:
public WebElement getElement(int numOnPage){
return driver.findElement(By.id("element"+numOnPage));
}
因为我调用该函数的瞬间WebElement就位。 (它无法实例化的原因是因为我有一个函数,通过一遍又一遍地调用isDisplayed()来等待元素存在,捕获 NoSuchElementException
s )。
Because the instant I call that function the WebElement gets located. (The reason why it can't be instantiated is because I have a function that waits until it the element exists by calling isDisplayed() over and over on it, catching NoSuchElementException
s).
我也意识到我可以创建一个 List< WebElement>
,它通过CSS选择每个ID的元素以element开头,但我还有其他情况需要返回动态生成的元素,并且还必须在那里使用解决方法。
I also realize that I could create a List<WebElement>
that selects via CSS every element whose ID starts with "element" but I have had other cases where I've wanted to return a dynamically generated element, and had to use a workaround there as well.
谢谢!
推荐答案
首先,我真的不明白为什么你绝对需要一个 WebElement
元素真正在页面之前的引用。在正常情况下,您可以检查页面是否已完全加载,然后查找 WebElement
。首先通常会使用循环和 NoSuchElementException
的捕获来完成。
First, I don't really understand why you absolutely need to get a WebElement
reference before the element is really in the page. In a normal case, you could check that the page is completely loaded and then find for a WebElement
. First would be typically done with a loop and a catch for NoSuchElementException
as you mentioned.
但是,如果需要在页面中找不到 WebElement
的引用之前,我只想创建一个懒惰加载的代理(仅在第一次需要时)真正的 WebElement
实例。这样的事情:
However, if you need a reference for a WebElement
before it can't be found in the page, I would simply create a proxy which loads lazily (only when first time needed) the real WebElement
instance. Something like this:
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
。
By calling getElement
, you retrieve an object of type WebElement
. As soon as you call one of its method, it will be retrieved using WebDriver.findElement
. Note that, if you call a method on the proxy instance, the element must be in the page otherwise you get of course a NoSuchElementException
.
这篇关于如何返回一个延迟实例化的动态webelement的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!