我的Selenium测试需要等待ajax请求处理,以避免出现竞争条件。在PrimeFaces 3.5中,您可以使用以下方法等待(直接从PrimeFaces-svn repo复制):
private static final String JQUERY_ACTIVE_CONNECTIONS_QUERY = "return $.active == 0;";
private static final int DEFAULT_SLEEP_TIME_IN_SECONDS = 2;
private static final int DEFAULT_TIMEOUT_IN_SECONDS = 10;
protected void waitUntilAjaxRequestCompletes() {
new FluentWait<WebDriver>(driver)
.withTimeout(DEFAULT_TIMEOUT_IN_SECONDS, TimeUnit.SECONDS)
.pollingEvery(DEFAULT_SLEEP_TIME_IN_SECONDS, TimeUnit.SECONDS)
.until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver d) {
JavascriptExecutor jsExec = (JavascriptExecutor) d;
return (Boolean) jsExec.executeScript(JQUERY_ACTIVE_CONNECTIONS_QUERY);
}
});
}
不幸的是,这段代码在PrimeFaces4.0中不起作用,jQuery连接似乎从未处于活动状态。
所以问题是:在4.0版本中,我如何等待PrimeFaces ajax请求的处理?
PrimeFaces 4.0使用自己的ajax事件处理程序,您可以使用以下代码:
private static final String JS_JQUERY_DEFINED = "return typeof jQuery != 'undefined';";
private static final String JS_PRIMEFACES_DEFINED = "return typeof PrimeFaces != 'undefined';";
private static final String JS_JQUERY_ACTIVE = "return jQuery.active != 0;";
private static final String JS_PRIMEFACES_QUEUE_NOT_EMPTY = "return !PrimeFaces.ajax.Queue.isEmpty();";
private static final int TIME_OUT_SECONDS=10;
private static final int POLLING_MILLISECONDS=500;
private void waitForJQueryAndPrimeFaces() {
new FluentWait(driver).withTimeout(TIME_OUT_SECONDS, TimeUnit.SECONDS)
.pollingEvery(POLLING_MILLISECONDS, TimeUnit.MILLISECONDS)
.until(new Function < WebDriver, Boolean >() {
@Override
public Boolean apply(WebDriver input) {
boolean ajax = false;
boolean jQueryDefined = executeBooleanJavascript(input, JS_JQUERY_DEFINED);
boolean primeFacesDefined = executeBooleanJavascript(input, JS_PRIMEFACES_DEFINED);
if (jQueryDefined) {
// jQuery is still active
ajax |= executeBooleanJavascript(input, JS_JQUERY_ACTIVE);
}
if (primeFacesDefined) {
// PrimeFaces queue isn't empty
ajax |= executeBooleanJavascript(input, JS_PRIMEFACES_QUEUE_NOT_EMPTY);
}
// continue if all ajax request are processed
return !ajax;
}
});
}
private boolean executeBooleanJavascript(WebDriver input, String javascript) {
return (Boolean) ((JavascriptExecutor) input).executeScript(javascript);
}