如何检查来自浏览器的待处理请求(Ajax及其变体)

我处理的一些网站有很多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。 所以我无法编辑webapp。

我找到了答案,它适用于我检查过的几个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); 

这不起作用? http://api.jquery.com/ajaxstop/

 $(document).ajaxStop(function() { // Do stuff here... }); 

如果您正在使用JSONP请求,则需要启用active处理 :

 jQuery.ajaxPrefilter(function( options ) { options.global = true; }); 

我认为使用active是正确的,但是你可能使用的方式可能会在条件的instanceof返回false。

(可选) 请参阅在Selenium测试中使用active来等待jQuery ajax调用的另一种方法 :

 browser.wait_for_condition("selenium.browserbot.getCurrentWindow().jQuery.active === 0;", '30000') 

根据我们对评论的讨论,这可能对您有用。

使用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(); } } 

来源: 检查待处理的AJAX请求或HTTP GET / POST请求