jquery.active 总是返回 0(jquery 和 requireJS)

Viv*_*S V 5 javascript jquery selenium requirejs

在我们的 Selenium 自动化测试中,我们jquery.active用来检查 ajax 调用是否完成并继续测试。但是,最近我们的应用程序改为使用 requireJS。从那时起,jquery.active无论 Jquery Ajax 调用正在进行中,总是返回 0。

请让我知道如何查找是否有任何未决的 Ajax 调用正在进行...?或解决jquery.active使用requireJS时总是返回零

def ajax_complete(driver):
return 0 == driver.execute_script("return jQuery.active")
Run Code Online (Sandbox Code Playgroud)

小智 0

问题出现六年后,但也许它会对其他人有所帮助。我遇到了类似的问题,我必须使用浏览器开发控制台提供的任何信息,而 jQuery.active 始终 = 0,并且在 AJAX 调用开始运行之前 document.readyState 设置为“完成”。根据这个问题的公认答案,我能够构建以下解决方案。不是最优雅的,但它有效,所以我认为值得分享。

根据:

首先,在返回布尔值的方法中,我定义了要执行的 js 脚本:

  • 返回“资源”类型的请求数
  • 返回列表中最后一个类型为“resource”的请求的responseEnd值

我使用“资源”类型请求,因为这些是我需要完成才能继续的请求:

String jsGetNumberOfRequests = "var performance = window.performance || window.mozPerformance || window.msPerformance || window.webkitPerformance || {}; var network = performance.getEntriesByType('resource') || {}; return network.length;";
String jsGetLastRequestResponseEndValue = "var performance = window.performance || window.mozPerformance || window.msPerformance || window.webkitPerformance || {}; var network = performance.getEntriesByType('resource') || {}; return network[network.length-1].responseEnd;";
Run Code Online (Sandbox Code Playgroud)

添加一些用于逻辑目的的附加变量以及 js 执行器:

String numberOfRequests;
String newNumberOfRequests;
String lastRequestResponseEndValue;
Boolean areRequestsFinished;
JavascriptExecutor js = (JavascriptExecutor) driver;
Run Code Online (Sandbox Code Playgroud)

然后,我继续运行脚本并执行第一次检查 - 获取“资源”类型请求的当前数量,并获取最后一个请求的responseEnd值(getEntriesByType返回按连接开始时间排序的请求,因此从技术上讲,最后一个条目list 将为我们提供最后一次运行的请求,但我建议您自行检查是否需要先对列表进行排序以防万一):

try {
    numberOfRequests = (js.executeScript(jsGetNumberOfRequests)).toString();
    // in case a particular form has no xhr requests at all (these also happen): 
    if (numberOfRequests.equalsIgnoreCase("0")) { 
        return true;
    }
    lastRequestResponseEndValue = (js.executeScript(jsGetLastRequestResponseEndValue)).toString();
} catch (JavascriptException e) { // we started checking to early
        return false;
}
Run Code Online (Sandbox Code Playgroud)

然后剩下的就是检查最后一个请求是否有非空的responseEnd 值。并返回结果:

if (!lastRequestResponseEndValue.equalsIgnoreCase("null")) { 
    newNumberOfRequests = (js.executeScript(jsGetNumberOfRequests)).toString(); 
    areRequestsFinished = numberOfRequests.equalsIgnoreCase(newNumberOfRequests); 
} else { 
    areRequestsFinished = false;
}

return areRequestsFinished;
Run Code Online (Sandbox Code Playgroud)

如果不是 - 至少有一个请求仍在运行。如果是 - 值得检查,如果请求数量没有改变 - 如果没有改变,可以安全地继续进一步的测试步骤,如果改变了 - 我们知道在我们没有检查的同时出现了新请求,所以你应该重新运行整个过程。

此外:

您可以将其包装在while 循环或布尔类型的自定义 ExpectedCondition中,并在显式等待中使用(等待该条件返回 true)。您可以在此处找到如何创建自定义 ExpectedConditions 的信息。

public Boolean waitForAjaxCalls(int timeoutInSec) {
    WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(timeoutInSec));
    ExpectedCondition<Boolean> customEC = new ExpectedCondition<Boolean>() {
        @Override
        public Boolean apply(WebDriver driver) {
            //here put the whole body listed above
            //finish with return areRequestsFinished;
        }
    };
    return wait.until(customEC);
}
Run Code Online (Sandbox Code Playgroud)