Selenium - 等待网络流量 [英] Selenium - Wait for network traffic

查看:117
本文介绍了Selenium - 等待网络流量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

We're using Selenium with the Java API and some Javascript user extensions. We use a lot of AJAX calls in our app. A lot of our tests fail randomly because sometimes the AJAX calls finish slower than other times so the page isn't fully loaded. We fix that by waiting for specific elements or Thread.sleep. I was trying to find a way to instead just wait for the network traffic to finish. So that we could do this:

selenium.click("some JS button");
selenium.waitForNetwork();
assertTrue(something);

这样我们可以摆脱线程睡眠,并在服务器响应更快时让测试通过更快由于时间问题,没有那么多测试失败。

That way we can get rid of the thread sleep and have tests pass faster when the server responds faster and not have so many tests fail due to timing issues.

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

I haven't been able to find a way to do this searching Google. Does anyone have any ideas how we can accomplish this? (Preferably either through Javascript or the Java API but all suggestions are welcome).

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

Note: the other variations of "waitFor" are not what I'm looking for. We're already using those in clicks and other things. I'm looking for something that waits for the NETWORK TRAFFIC. Thanks for all the feedback, I'll be trying out a couple of the suggestions, but I'm still open to other ideas.

谢谢。

推荐答案

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

这是我们最终做的事情。
(注意,如果你总是只使用像JQuery这样的单一框架,那么如果运行Ajax调用有更简单的方法。我们不得不更多地使用jimmy-rig,因为我们有几个页面使用JQuery和一群使用GWT的人)

Here's what we ended up doing. (Note, there are easier ways of getting if an Ajax call is running if you are always using only a single framework like JQuery. We had to jimmy-rig this a bit more because we have a few pages that use JQuery and a bunch that use GWT)

我创建了一个Javascript文件,每个页面只在你测试时加载。 (我通过在JSP模板中包含一个片段来实现这一点:如果将测试查询字符串param作为true传入,则设置一个cookie。如果设置了该cookie,则包含javascript文件)
这个javascript文件实际上包装了XMLHttpRequest对象以保持所有发送请求的计数:

I created a Javascript file that every page loads only if you're testing. (I did this by including a snippet in our JSP's template: if the testing querystring param is passed in as true, set a cookie. If that cookie is set, include the javascript file) This javascript file essentially wraps the XMLHttpRequest object to keep count of all the send requests:

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);
        }
    }
}

还有更多内容比如果async == false,那应该很容易搞清楚。

There's a little more to it than that if async == false, but that should be easy enough to figure out.

然后我向selenium user-extensions.js添加了一个函数,它看起来像这个:

Then I added a function to the selenium user-extensions.js that simply looks like this:

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;
}

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

Also, notice the check on topWindow: this is because you get issues when an iframe is selected.

此外,您必须在每个加载的iFrame的XMLHttpRequest对象上调用wrapRequest方法。我现在正在使用: document.addEventListener(DOMNodeInserted,onElementAdded,true); 然后在onElementAdded中我只是在加载iframe时抓取iframe并传入XMLHttpRequest宾语。但这在IE中不起作用,所以我正在寻找替代方案。如果有人知道更好的方法,那么它适用于IE和FF我很乐意听到它。

Also, you will have to call the wrapRequest method on the XMLHttpRequest object of every iFrame that gets loaded. I do that right now using: document.addEventListener("DOMNodeInserted", onElementAdded, true); and then in onElementAdded I just grab the iframe when it's loaded and pass in the XMLHttpRequest object. but that doesn't work in IE so I'm looking for an alternative. If anyone knows of a better way to do that so it works in both IE and FF I would love to hear it.

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

Anyway, that's the gist of the implementation. Hope this helps anyone in the future.

这篇关于Selenium - 等待网络流量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆