我们将Selenium与Java API和一些Javascript用户扩展一起使用。我们在应用程序中使用了大量的AJAX调用。我们的许多测试都会随机失败,因为有时AJAX调用的完成速度比其他时间要慢,因此页面没有完全加载。我们通过等待特定的元素或Thread.sleep来解决这个问题。我试图找到一种方法,而不是仅仅等待网络流量结束。这样我们就可以这样做:
selenium.click("some JS button");
selenium.waitForNetwork();
assertTrue(something);这样,我们就可以摆脱线程睡眠,让测试在服务器响应更快时通过得更快,而不会有那么多测试因为计时问题而失败。
我还没能找到一种在谷歌上搜索的方法。有谁知道我们如何才能做到这一点吗?(最好是通过Javascript或Java API,但欢迎所有建议)。
注意:"waitFor“的其他变体不是我要找的。我们已经在点击和其他东西中使用它们了。我在找等待网络流量的东西。感谢所有的反馈,我将尝试一些建议,但我仍然对其他想法持开放态度。
谢谢。
发布于 2010-11-20 13:06:38
更新:我以与Selenium2相同的方式使用相同的方法(wrapRequest),它仍然有效。唯一的区别是我不使用用户扩展。我只是执行javascript来查询由JSP.加载的代码
这就是我们最终要做的。(请注意,如果您始终只使用一个框架,如JQuery,那么获取Ajax调用是否正在运行有更简单的方法。我们必须对此进行更多的修改,因为我们有几个页面使用JQuery,还有一些页面使用GWT)
我创建了一个Javascript文件,只有在测试时才会加载每个页面。(我是通过在JSP的模板中包含一个代码片段来实现这一点的:如果测试querystring param作为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);
}
}
}如果异步==为假,还会有更多的问题,但这应该很容易弄清楚。
然后,我向selenium user-extsions.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;
}此外,请注意topWindow上的检查:这是因为当选择iframe时会出现问题。
此外,您还必须在加载的每个iFrame的XMLHttpRequest对象上调用wrapRequest方法。我现在使用:document.addEventListener("DOMNodeInserted", onElementAdded, true);来做这件事,然后在onElementAdded中,我只是在加载iframe时获取它,并传入XMLHttpRequest对象。但这在IE中不起作用,所以我正在寻找替代方案。如果有人知道有更好的方法来做到这一点,那么它在IE和FF中都可以工作,我很想听听。
无论如何,这就是实现的要点。希望这对将来的任何人都有帮助。
发布于 2010-11-06 06:42:46
Selenium中提供的waitFor类型很少。在您的测试用例中,如果您知道页面加载时会出现特定的文本,则可以使用waitForText。如果有不同的DOM元素需要填充(通过Ajax/pageload),您可以按顺序添加waitForText。
发布于 2010-11-07 03:19:38
在尝试了本页面上描述的所有变体后,我们最终得到了以下策略:
注入一个特殊的javascript,它基本上覆盖了所有相关的框架方法,并保留了一个未完成请求数量的计数器,该计数器在启动时增加,在完成时减少。由于javascript的异步特性,仅保留一个布尔变量是不够的,您可能会在自己的逻辑中使用竞争条件。
如果你使用视觉效果,你可能也想对视觉效果这样做;变形/淡入淡出和其他视觉效果也会有同样的问题。
所以我们基本上做了一个常规的“点击”,然后总是等待这个计数器再次达到0,使用javascript,就像其他人在这里建议的那样。在我们准备好之后,我们将暂时的问题减少到了零。
请记住,selenium只有在处理完所有同步onclick事件后才会从"click“返回,因此您必须确保onclick的直接结果是使这些计数器递增。
有关如何覆盖框架方法的说明,您需要参考框架文档;我们在prototype中使用addMethods。可以在一个特殊的javascript中保持这个覆盖,这个javascript只在运行测试时添加到页面中。
https://stackoverflow.com/questions/4110588
复制相似问题