Selenium - 等待网络流量

Joe*_*oel 16 java networking selenium

我们将Selenium与Java API和一些Javascript用户扩展一起使用.我们在应用程序中使用了大量的AJAX调用.我们的很多测试都是随机失败的,因为有时候AJAX调用比其他时候完成得慢,所以页面没有完全加载.我们通过等待特定元素或Thread.sleep来解决这个问题.我试图找到一种方法,而不是等待网络流量完成.这样我们就可以这样做:

selenium.click("some JS button");
selenium.waitForNetwork();
assertTrue(something);
Run Code Online (Sandbox Code Playgroud)

这样我们可以摆脱线程休眠,并且当服务器响应更快并且由于时序问题而没有那么多测试失败时测试通过更快.

我无法找到一种方法来搜索Google.有没有人有任何想法我们如何才能做到这一点?(最好是通过Javascript或Java API,但欢迎所有建议).

注意:"waitFor"的其他变体不是我想要的.我们已经在点击和其他内容中使用了这些内容.我正在寻找等待NETWORK TRAFFIC的东西.感谢所有反馈,我将尝试一些建议,但我仍然对其他想法持开放态度.

谢谢.

Joe*_*oel 2

更新:我以与 Selenium2 相同的方式使用相同的方法(wrapRequest),它仍然有效。唯一的区别是我不使用用户扩展。我只是执行 javascript 来查询 JSP 加载的代码。

这就是我们最终所做的。(请注意,如果您始终只使用 JQuery 之类的单一框架,则有更简单的方法来获取 Ajax 调用是否正在运行。我们必须对此进行更多的调整,因为我们有几个页面使用 JQuery,还有一堆使用 GWT)

我创建了一个 Javascript 文件,每个页面仅在您进行测试时才加载。(我通过在 JSP 模板中包含一个片段来做到这一点:如果测试查询字符串参数作为 true 传入,则设置一个 cookie。如果设置了该 cookie,则包含 javascript 文件)此 javascript 文件本质上包装了 XMLHttpRequest 对象以保持计数所有发送请求的数量:

function wrapRequest(xmlRequest) {
    var oldSend = xmlRequest.prototype.send;
    xmlRequest.prototype.send = function() {
        var oldOnReady = this.onreadystatechange;
        oldOnReady = function() {
            oldOnReady.apply(this, arguments);
            // if call is complete, decrement counter.
        }
        // increment counter
        if(oldSend.apply)
            oldSend.apply(this, arguments);
        else if (oldOnReady.handleEvent) { //Firefox sometimes will need this
            oldOnReady.handleEvent.apply(this, arguments);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

除了 if async == false 之外还有更多内容,但这应该很容易弄清楚。

然后我向 selenium user-extensions.js 添加了一个函数,如下所示:

Selenium.prototype.getIsNetworkReady = function() {
    if(this.browserbot.topWindow.isNetworkReady) { //sometimes this method is called before the page has loaded the isNetworkReady function
        return this.browserbot.topWindow.isNetworkReady();
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

另外,请注意 topWindow 上的检查:这是因为选择 iframe 时会遇到问题。

此外,您还必须对加载的每个 iFrame 的 XMLHttpRequest 对象调用 wrapRequest 方法。我现在使用:document.addEventListener("DOMNodeInserted", onElementAdded, true);然后在 onElementAdded 中,我只是在加载 iframe 时获取它并传入 XMLHttpRequest 对象。但这在 IE 中不起作用,所以我正在寻找替代方案。如果有人知道更好的方法来做到这一点,以便它在 IE 和 FF 中都有效,我很想听听。

无论如何,这就是实施的要点。希望这对将来的任何人都有帮助。