我正在使用Selenium和Selenium IDE测试一个非常重量级的Web应用程序。一切正常,直到最终提交。通常由于仍在进行中的ajax请求的数量(通常大约20个)而导致错误输出。有没有办法让selenium等待所有ajax请求完成?我试过waitForEval Value =“$ .active == 0”(如下图所示),但似乎没有做任何事
这是Selenium IDE可以实现的吗?
注意 - 我必须使用IDE,因为业务类型和我来回传递脚本。
答案 0 :(得分:6)
答案结果相当简单 - 您只需要使用waitForEval命令检查活动请求的数量(selenium.browserbot.getUserWindow()。$。active),并将值设置为0 - 并且这一切都发生在ide中。
答案 1 :(得分:1)
我暂时没有使用过IDE。这就是我用于WebDriver的内容。但算法转换; JavaScript是JavaScript。话虽如此,这取决于你的框架。
对于Angular,我用这个:
public boolean waitForAngularToLoad(WebDriver driver, int waitTimeInSeconds) {
WebDriverWait wait = new WebDriverWait(driver, waitTimeInSeconds, 2000L);
ExpectedCondition<Boolean> libraryLoad = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
try {
return ((Boolean)((JavascriptExecutor)driver).executeScript(
"return angular.element(document.body).injector().get(\'$http\').pendingRequests.length == 0;"
));
}
catch (Exception e) {
// Angular not found
log.info("Not found: " + "return angular.element(document.body).injector().get(\'$http\').pendingRequests.length == 0;");
return true;
}
}
};
// wait for browser readystate complete; it is arguable if selenium does this all the time
ExpectedCondition<Boolean> jsLoad = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor)driver).executeScript("return document.readyState;")
.toString().equals("complete");
}
};
return wait.until(libraryLoad) && wait.until(jsLoad);
}
对于Prototype,我使用:
public boolean waitForPrototypeToLoad(WebDriver driver, int waitTimeInSeconds) {
WebDriverWait wait = new WebDriverWait(driver, waitTimeInSeconds, 2000L);
// wait for jQuery to load
ExpectedCondition<Boolean> libraryLoad = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
try {
return ((Boolean)((JavascriptExecutor)driver).executeScript("return Ajax.activeRequestCount == 0;"));
}
catch (Exception e) {
// Prototype not found
log.info("Not found: " + "return Ajax.activeRequestCount == 0;");
return true;
}
}
};
// wait for browser readystate complete; it is arguable if selenium does this all the time
ExpectedCondition<Boolean> jsLoad = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor)driver).executeScript("return document.readyState;")
.toString().equals("complete");
}
};
return wait.until(libraryLoad) && wait.until(jsLoad);
}
对于jQuery,我使用它(你必须自定义等待微调器逻辑,每个人都做不同的事情):
public boolean waitForJSandJQueryToLoad(WebDriver driver, long waitTimeInSeconds) {
WebDriverWait wait = new WebDriverWait(driver, waitTimeInSeconds, 2000L);
/*
* If you are curious about what follows see:
* http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/support/ui/ExpectedCondition.html
*
* We are creating an anonymous class that inherits from ExpectedCondition and then implements interface
* method apply(...)
*/
ExpectedCondition<Boolean> libraryLoad = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
boolean isAjaxFinished = false;
boolean isLoaderSpinning = false;
boolean isPageLoadComplete = false;
try {
isAjaxFinished = ((Boolean)((JavascriptExecutor)driver).executeScript("return jQuery.active == 0;"));
} catch (Exception e) {
// no Javascript library not found
isAjaxFinished = true;
}
try { // Check your page, not everyone uses class=spinner
// Reduce implicit wait time for spinner
driver.manage().timeouts().implicitlyWait(10L, TimeUnit.SECONDS);
// isLoaderSpinning = driver.findElement(By.className("spinner")).isDisplayed(); // This is the default
// Next was modified for GoComics
isLoaderSpinning = driver.findElement(By.cssSelector("#progress_throbber > ul > li:nth-child(1) > img[alt='spinner']")).isDisplayed();
if (isLoaderSpinning)
log.info("jquery loader is spinning");
} catch (Exception f) {
// no loading spinner found
isLoaderSpinning = false;
} finally { // Restore implicit wait time to default
driver.manage().timeouts().implicitlyWait(new DriverFactory().getImplicitWait(), TimeUnit.SECONDS);
}
isPageLoadComplete = ((JavascriptExecutor)driver).executeScript("return document.readyState;")
.toString().equals("complete");
if (!(isAjaxFinished & !(isLoaderSpinning) & isPageLoadComplete))
log.info(isAjaxFinished + ", " + !(isLoaderSpinning) +", " + isPageLoadComplete);
return isAjaxFinished & !(isLoaderSpinning) & isPageLoadComplete;
}
}; // Terminates statement started by ExpectedCondition<Boolean> libraryLoad = ...
return wait.until(libraryLoad);
}
答案 2 :(得分:0)
最后,解决问题的原因是增加了AJAX。我正在测试它几天 - 一个巧妙的解决方案。关于每一步的附录,selenium会自动等待AJAX的执行。