FluentWait with WebElement

原文-FluentWait with WebElement

我在 WebDriver 上的同步策略一般都是围绕 WebDriverWait 和 自定义 ExpectedCondition 来做文章。当我第一眼看到 FluentWait,
我以为这是一个自定义化更多的一个 WebDriverWait。 但是当我仔细研究它的构造函数的时候,我注意到它使用了 Generics (范型)。
Generics 的使用意味着我不需要再传一个 WebDriver 了, 我可以使用 WebElement 或者 By 或者任何我想要的。 这样对于 Ajax 的应用,真是方便了不少。

org.openqa.selenium.support.ui
Class FluentWait\

java.lang.Object
org.openqa.selenium.support.ui.FluentWait\

Type Parameters:
T - The input type for each condition used with this instance.

All Implemented Interfaces:
Wait\

Direct Known Subclasses:
WebDriverWait

看下面这段代码, 我用了一个倒计时的计数器做例子。

这段代码实现了:

  1. 用一个 WebDriverWait 等待元素出现。
  2. 看计数器是否倒数到 04.
1
2
3
4
5
6
7
8
9
10
11
12
13
WebElement countdown = driver.findElement(By.id("javascript_countdown_time"));
new WebDriverWait(driver,10).until(ExpectedConditions.visibilityOf(countdown));
new FluentWait<WebElement>(countdown).withTimeout(10, TimeUnit.SECONDS).
pollingEvery(100,TimeUnit.MILLISECONDS).
until(new Function<WebElement , Boolean>() {
@Override
public Boolean apply(WebElement element) {
return element.getText().endsWith("04");
}
}
);

注意在上述代码中,我告诉 FluentWait, apply 方法里接收的将是一个 WebElement。FluentWait 可以接受一个 Predicate 或者 Function 做为 until 方法的参。
我用了 Function 并在 这个 Function 里面返回一个 Boolean。

FluentWait 非常灵活,你可以很轻松的调整等待和轮询时间, 你也可以设置哪些 exceptions 可以忽略, 比如:

1
2
3
4
5
6
7
8
9
10
11
12
// Waiting 30 seconds for an element to be present on the page, checking
// for its presence once every 5 seconds.
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, SECONDS)
.pollingEvery(5, SECONDS)
.ignoring(NoSuchElementException.class); // 我们主动忽略了 NoSuchElementExceptions 的异常
WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(By.id("foo"));
}
});

怎样,看上去是不是优雅多了?

文章目录
|