すべてのajaxコンテンツがロードされるまで待つSeleniumの普遍的なアプローチはありますか? (特定のWebサイトに関連付けられていないため、すべてのAjax Webサイトで機能します)
JavascriptとjQueryの読み込みが完了するまで待つ必要があります。 Javascriptを実行して、jQuery.active
は0
およびdocument.readyState
はcomplete
で、JSとjQueryのロードが完了したことを意味します。
public boolean waitForJSandJQueryToLoad() {
WebDriverWait wait = new WebDriverWait(driver, 30);
// wait for jQuery to load
ExpectedCondition<Boolean> jQueryLoad = new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
try {
return ((Long)((JavascriptExecutor)getDriver()).executeScript("return jQuery.active") == 0);
}
catch (Exception e) {
// no jQuery present
return true;
}
}
};
// wait for Javascript to load
ExpectedCondition<Boolean> jsLoad = new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor)getDriver()).executeScript("return document.readyState")
.toString().equals("complete");
}
};
return wait.until(jQueryLoad) && wait.until(jsLoad);
}
Mark Collinが著書「Mastering Selenium Webdriver」で説明したように、JavascriptExecutorを使用すると、jQueryを使用するWebサイトがAJAX呼び出しを完了したかどうかを把握できます
public class AdditionalConditions {
public static ExpectedCondition<Boolean> jQueryAJAXCallsHaveCompleted() {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
return (Boolean) ((JavascriptExecutor) driver).executeScript("return (window.jQuery != null) && (jQuery.active === 0);");
}
};
}
}
AJAXが終了するまで繰り返す間、この単純なdoを使用してきました。一貫して動作します。
public void waitForAjax() throws InterruptedException{
while (true)
{
Boolean ajaxIsComplete = (Boolean) ((JavascriptExecutor)driver).executeScript("return jQuery.active == 0");
if (ajaxIsComplete){
info("Ajax Call completed. ");
break;
}
Thread.sleep(150);
}
}
すぐに使える普遍的なアプローチがあるとは思わない。通常、要素をポーリングする.waituntilrowcount(2)
またはwaituntilvisible()
を実行するメソッドを作成します。