java Wait.until() 与 Webdriver PageFactory 元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9938986/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Wait.until() with Webdriver PageFactory elements
提问by Arthur
i'm using @FindBy annotations to locate elements on my page. Like this:
我正在使用 @FindBy 注释来定位我页面上的元素。像这样:
@FindBy(xpath = "//textarea")
public InputBox authorField;
Please, help. I want use wait (ExpectedConditions) with my annotated elements. Like this:
请帮忙。我想对带注释的元素使用等待(ExpectedConditions)。像这样:
wait.until(visibilityOfElementLocated(authorField));
instead of:
代替:
wait.until(visibilityOfElementLocated(By.xpath("//textarea")));
Thanks for advance
感谢提前
回答by Petr Jane?ek
The problem is that methods taking a WebElement
usually assume the WebElement was already found (And they are right! PageFactory arranges it so that just before the element is accessed by a method, it is found.), i.e. exists on the page. When giving a By to the method, you say "I want it to be found, I just don't know when will it show up."
问题在于,采用 a 的方法WebElement
通常假设已经找到了 WebElement(他们是对的!PageFactory 安排它以便就在元素被方法访问之前,它被找到。),即存在于页面上。当给方法一个 By 时,你说“我想要它被找到,我只是不知道它什么时候会出现。”
You can use
您可以使用
wait.until(visibilityOf(authorField));
in conjuction with
连同
// right after driver is instantiated
driver.manage().timeouts().implicitlyWait(...);
That should do it just the way you'd like.
那应该按照您想要的方式进行。
implicitlyWait()
documentationsays:
implicitlyWait()
文档说:
Specifies the amount of time the driver should wait when searching for an element if it is not immediately present.
When searching for a single element, the driver should poll the page until the element has been found, or this timeout expires before throwing a NoSuchElementException. When searching for multiple elements, the driver should poll the page until at least one element has been found or this timeout has expired.
指定驱动程序在搜索元素时应等待的时间(如果该元素不是立即出现)。
搜索单个元素时,驱动程序应轮询页面直到找到该元素,否则此超时将在抛出 NoSuchElementException 之前到期。搜索多个元素时,驱动程序应轮询页面,直到找到至少一个元素或超时已过期。
So, basically, it waits for an element to show up every time it is looked up. Which is good for all sorts of asynchronous requests, obviously.
因此,基本上,每次查找元素时,它都会等待元素出现。显然,这对各种异步请求都有好处。
回答by Pavel Zorin
ExpectedConditions.visibilityOf(authorField);
Look at the source code of any Expected condition. It's very easy to write your own condition that can do everything you want.
查看任何预期条件的源代码。编写自己的条件非常容易,可以做你想做的一切。
回答by Trevor Young
I know that this question is already answered and was asked a while ago, but I figured that I'd provide a concrete example of how to write your own Expected Condition for this. By creating this Expected Condition class:
我知道这个问题已经得到回答并在不久前被问到,但我想我会提供一个具体的例子来说明如何为此编写自己的预期条件。通过创建这个预期条件类:
/**
* Since the proxy won't try getting the actual web element until you
* call a method on it, and since it is highly unlikely (if not impossible)
* to get a web element that doesn't have a tag name, this simply will take
* in a proxy web element and call the getTagName method on it. If it throws
* a NoSuchElementException then return null (signaling that it hasn't been
* found yet). Otherwise, return the proxy web element.
*/
public class ProxyWebElementLocated implements ExpectedCondition<WebElement> {
private WebElement proxy;
public ProxyWebElementLocated(WebElement proxy) {
this.proxy = proxy;
}
@Override
public WebElement apply(WebDriver d) {
try {
proxy.getTagName();
} catch (NoSuchElementException e) {
return null;
}
return proxy;
}
}
Then this will allow you to do:
然后这将允许您执行以下操作:
wait.until(new ProxyWebElementLocated(authorField));
And that's all you really need. But if you want to take the abstraction one step further, you could create a class like this:
这就是你真正需要的。但是如果你想进一步抽象,你可以创建一个这样的类:
public final class MyExpectedConditions {
private MyExpectedConditions() {}
public static ExpectedCondition<WebElement> proxyWebElementLocated(WebElement proxy) {
return new ProxyWebElementLocated(proxy);
}
}
Which would then allow you to do something like this:
这将允许您执行以下操作:
wait.until(MyExpectedConditions.proxyWebElementLocated(authorField));
The MyExpectedConditions
class can be a bit overkill for one Expected Condition, but if you have multiple Expected Conditions, then having it will make things much nicer.
该MyExpectedConditions
班可为一个预期的条件有点大材小用,但如果你有多个预期时,则有它会让事情变得更好。
As a final note for any that really want to go the extra mile, you can also add methods to the MyExpectedConditions
class that wrap the methods in the ExpectedConditions
class, and then you can get all your Expected Conditions stuff from one place. (I'd suggest extending ExpectedConditions
instead of doing the wrapper methods, but it has a private constructor, making it impossible to extend. This leaves wrapper methods as the only option for those that really want everything in one place.)
对于任何真正想要加倍努力的人,最后要注意的是,您还可以将方法添加到MyExpectedConditions
类中,将方法包装在ExpectedConditions
类中,然后您可以从一个地方获取所有预期条件。(我建议扩展ExpectedConditions
而不是执行包装器方法,但它有一个私有构造函数,因此无法扩展。这使得包装器方法成为那些真正想要在一个地方所有东西的人的唯一选择。)
回答by Spriha
As mentioned in other answers, ExpectedConditions.visibilityOf(authorField);
will do the job. Mentioning a detailed solution below for more clarity.
如其他答案中所述,ExpectedConditions.visibilityOf(authorField);
将完成这项工作。为了更清楚,在下面提到一个详细的解决方案。
public class YourTestPage {
private WebDriver driver;
private WebDriverWait wait;
@FindBy(xpath = "//textarea")
private WebElement authorField;
public YourTestPage(WebDriver driver) {
this.driver = driver;
wait = new WebDriverWait(driver, 15, 50);
PageFactory.initElements(driver,this);
}
public void enterAuthorName() {
wait.until(ExpectedConditions.visibilityOf(authorField)).sendKeys("Author Name");
}
}