如何从浏览器检查是否有待处理的请求(Ajax及其变体)

时间:2014-06-19 04:42:36

标签: java jquery ajax selenium webdriver

我处理的一些网站有大量的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。所以我无法编辑网络应用程序。

4 个答案:

答案 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();
    }
}

来源:Check Pending AJAX requests or HTTP GET/POST request