我处理的一些网站有大量的ajax请求。我打算在点击断言元素之前等待Ajax请求完成。目前我使用
try {
if (driver instanceof JavascriptExecutor) {
JavascriptExecutor jsDriver = (JavascriptExecutor)driver;
for (int i = 0; i< timeoutInSeconds; i++)
{
Object numberOfAjaxConnections = jsDriver.executeScript("return jQuery.active");
// return should be a number
if (numberOfAjaxConnections instanceof Long) {
Long n = (Long)numberOfAjaxConnections;
System.out.println("Number of active jquery ajax calls: " + n);
if (n.longValue() == 0L) break;
}
Thread.sleep(1000);
}
}
else {
System.out.println("Web driver: " + driver + " cannot execute javascript");
}
}
catch (InterruptedException e) {
System.out.println(e);
}
但它适用于Ajax请求,但不适用于任何带有jQuery库变体的类似请求。
注意:
document.readyState == 'complete'
它不适用于Ajax请求或任何其他类似的替代方案。
这两项测试都不是由我编写的,也不属于单个webapp。所以我无法编辑网络应用程序。
答案 0 :(得分:12)
我找到了答案,它适用于我检查过的几个Ajax和非ajax网站。在这个补丁之后,我不再需要对ajax重页进行隐式等待,LeGac在他对这个问题的一个评论中指出了以下代码。
public static void checkPendingRequests(FirefoxDriver driver) {
int timeoutInSeconds = 5;
try {
if (driver instanceof JavascriptExecutor) {
JavascriptExecutor jsDriver = (JavascriptExecutor)driver;
for (int i = 0; i< timeoutInSeconds; i++)
{
Object numberOfAjaxConnections = jsDriver.executeScript("return window.openHTTPs");
// return should be a number
if (numberOfAjaxConnections instanceof Long) {
Long n = (Long)numberOfAjaxConnections;
System.out.println("Number of active calls: " + n);
if (n.longValue() == 0L) break;
} else{
// If it's not a number, the page might have been freshly loaded indicating the monkey
// patch is replaced or we haven't yet done the patch.
monkeyPatchXMLHttpRequest(driver);
}
Thread.sleep(1000);
}
}
else {
System.out.println("Web driver: " + driver + " cannot execute javascript");
}
}
catch (InterruptedException e) {
System.out.println(e);
}
}
public static void monkeyPatchXMLHttpRequest(FirefoxDriver driver) {
try {
if (driver instanceof JavascriptExecutor) {
JavascriptExecutor jsDriver = (JavascriptExecutor)driver;
Object numberOfAjaxConnections = jsDriver.executeScript("return window.openHTTPs");
if (numberOfAjaxConnections instanceof Long) {
return;
}
String script = " (function() {" +
"var oldOpen = XMLHttpRequest.prototype.open;" +
"window.openHTTPs = 0;" +
"XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {" +
"window.openHTTPs++;" +
"this.addEventListener('readystatechange', function() {" +
"if(this.readyState == 4) {" +
"window.openHTTPs--;" +
"}" +
"}, false);" +
"oldOpen.call(this, method, url, async, user, pass);" +
"}" +
"})();";
jsDriver.executeScript(script);
}
else {
System.out.println("Web driver: " + driver + " cannot execute javascript");
}
}
catch (Exception e) {
System.out.println(e);
}
}
每一步后你都需要打电话
checkPendingRequests(driver);
答案 1 :(得分:2)
这不起作用? http://api.jquery.com/ajaxstop/
$(document).ajaxStop(function() {
// Do stuff here...
});
答案 2 :(得分:1)
如果您使用的是JSONP请求,则需要enable the active
handling:
jQuery.ajaxPrefilter(function( options ) {
options.global = true;
});
我认为使用active
是正确的,但可能您使用的方式可能会在instanceof
条件下返回false。
可选择see another way to wait for jQuery ajax calls using active
in Selenium
tests:
browser.wait_for_condition("selenium.browserbot.getCurrentWindow().jQuery.active === 0;", '30000')
答案 3 :(得分:-3)
根据我们对评论的讨论,这可能适合您。
使用prototype.js:
var ACTIVE_REQUESTS = 0; // GLOBAL
ACTIVE_REQUESTS++
new Ajax.Request('/your/url', {
onSuccess: function(response) {
ACTIVE_REQUESTS--;
// Handle the response content...
}
}));
console.log("there are " + ACTIVE_REQUESTS + " open AJAX requests pending");
使用普通脚本:
interValRef = 0;
interValRef = setInterval("checkState();",100)
function checkState(){
if(document.readyState == 'complete'){
clearInterval(interValRef);
myFunc();
}
}