nilesh の回答をさらに一歩進めると、SearchContext インターフェイスを使用して、より細かく調整された検索 (たとえば、WebElement のコンテキスト内) を許可することもできます。
Function<SearchContext, WebElement> elementLocated(final By by) {
return new Function<SearchContext, WebElement>() {
public WebElement apply(SearchContext context) {
return context.findElement(by);
}
};
}
実行は、(WebDriverWait ではなく) FluentWait<SearchContext> インスタンスによって実行されます。その実行と必要な例外処理をユーティリティ メソッドでラップすることにより、適切なプログラミング インターフェイスを作成します ( PageObject型階層のルートは適切な場所です)。
/**
* @return The element if found before timeout, otherwise null
*/
protected WebElement findElement(SearchContext context, By by,
long timeoutSeconds, long sleepMilliseconds) {
@SuppressWarnings("unchecked")
FluentWait<SearchContext> wait = new FluentWait<SearchContext>(context)
.withTimeout(timeoutSeconds, TimeUnit.SECONDS)
.pollingEvery(sleepMilliseconds, TimeUnit.MILLISECONDS)
.ignoring(NotFoundException.class);
WebElement element = null;
try {
element = wait.until(elementLocated(by));
}
catch (TimeoutException te) {
element = null;
}
return element;
}
/**
* overloaded with defaults for convenience
*/
protected WebElement findElement(SearchContext context, By by) {
return findElement(context, by, DEFAULT_TIMEOUT, DEFAULT_POLL_SLEEP);
}
static long DEFAULT_TIMEOUT = 3; // seconds
static long DEFAULT_POLL_SLEEP = 500; // milliseconds
使用例:
WebElement div = this.findElement(driver, By.id("resultsContainer"));
if (div != null) {
asyncSubmit.click();
WebElement results = this.findElement(div, By.id("results"), 30, 500);
if (results == null) {
// handle timeout
}
}