尝试跟踪 Firefox 中未完成的 AJAX 请求的数量
我正在使用 Selenium 来测试 Web 应用程序,并且不允许修改应用程序的 javascript 代码。我试图通过使用 GreaseMonkey 覆盖 XMLHttpRequest.send 来跟踪未完成的 AJAX 请求的数量。新的 send() 基本上将包装设置为 onreadystatechange 回调的内容,检查readyState,适当增加或减少计数器,并调用原始回调函数。
我遇到的问题似乎是权限问题,因为如果我只是浏览到普通 Firefox 浏览器中的页面,打开 Firebug 并粘贴以下代码,它似乎工作正常:
document.ajax_outstanding = 0;
if (typeof XMLHttpRequest.prototype.oldsend != 'function') {
XMLHttpRequest.prototype.oldsend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function() {
console.log('in new send');
console.log('this.onreadystatechange = ' + this.onreadystatechange);
this.oldonreadystatechange = this.onreadystatechange;
this.onreadystatechange = function() {
if (this.readyState == 2) {
/* LOADED */
document.ajax_outstanding++;
console.log('set ajax_outstanding to ' + document.ajax_outstanding);
}
this.oldonreadystatechange.handleEvent.apply(this, arguments);
if (this.readyState == 4) {
/* COMPLETED */
document.ajax_outstanding--;
console.log('set ajax_outstanding to ' + document.ajax_outstanding);
}
};
this.oldsend.apply(this, arguments);
};
}
现在,如果我使用稍作修改的版本GreaseMonkey 用户脚本中的该片段如下所示:
unsafeWindow.document.ajax_outstanding = 0;
if (typeof unsafeWindow.XMLHttpRequest.prototype.oldsend != 'function') {
unsafeWindow.XMLHttpRequest.prototype.oldsend = unsafeWindow.XMLHttpRequest.prototype.send;
unsafeWindow.XMLHttpRequest.prototype.send = function() {
GM_log('in new send');
GM_log('this.onreadystatechange = ' + this.onreadystatechange);
this.oldonreadystatechange = this.onreadystatechange;
this.onreadystatechange = function() {
if (this.readyState == 2) {
/* LOADED */
unsafeWindow.document.ajax_outstanding++;
GM_log('set ajax_outstanding to ' + unsafeWindow.document.ajax_outstanding);
}
this.oldonreadystatechange.handleEvent.apply(this, arguments);
if (this.readyState == 4) {
/* COMPLETED */
unsafeWindow.document.ajax_outstanding--;
GM_log('set ajax_outstanding to ' + unsafeWindow.document.ajax_outstanding);
}
};
this.oldsend.apply(this, arguments);
};
}
我转到一个页面,执行一些导致 AJAX 请求的操作,我在 javascript 错误控制台中收到以下消息:
http://www.blah.com/gmscripts/overrides: in new send
uncaught exception: [Exception... "Illegal value" nsresult: "0x80070057 (NS_ERROR_ILLEGAL_VALUE)" location: "JS frame :: file:///tmp/customProfileDir41e7266f56734c97a2ca02b1f7f528e1/extensions/%7Be4a8a97b-f2ed-450b-b12d-ee082ba24781%7D/components/greasemonkey.js :: anonymous :: line 372" data: no]
因此,在尝试访问时似乎会抛出异常this.onreadystatechange
据推测,这是由于沙盒环境造成的。 任何帮助将不胜感激。我不依赖于这个解决方案,所以欢迎任何其他建议来完成我需要的事情。只是我已经尝试了其他几种,这似乎是最有希望的。要求是我需要确保在readyState变为4并且onreadystatechange回调完成执行之后计数器变为0。
I am using Selenium to test a web application and am not allowed to modify the application's javascript code. I am trying to track the number of outstanding AJAX requests by using GreaseMonkey to override XMLHttpRequest.send. The new send() will basically wrap what was set as the onreadystatechange callback, check the readyState, incrementing or decrementing the counter as appropriate, and calling the original callback function.
The problem that I'm having appears to be a privilege issue because if I just browse to a page in a normal firefox browser, open firebug and paste in the following code, it seems to work fine:
document.ajax_outstanding = 0;
if (typeof XMLHttpRequest.prototype.oldsend != 'function') {
XMLHttpRequest.prototype.oldsend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function() {
console.log('in new send');
console.log('this.onreadystatechange = ' + this.onreadystatechange);
this.oldonreadystatechange = this.onreadystatechange;
this.onreadystatechange = function() {
if (this.readyState == 2) {
/* LOADED */
document.ajax_outstanding++;
console.log('set ajax_outstanding to ' + document.ajax_outstanding);
}
this.oldonreadystatechange.handleEvent.apply(this, arguments);
if (this.readyState == 4) {
/* COMPLETED */
document.ajax_outstanding--;
console.log('set ajax_outstanding to ' + document.ajax_outstanding);
}
};
this.oldsend.apply(this, arguments);
};
}
Now if I use a slightly modified version of that snippet from within a GreaseMonkey user script like so:
unsafeWindow.document.ajax_outstanding = 0;
if (typeof unsafeWindow.XMLHttpRequest.prototype.oldsend != 'function') {
unsafeWindow.XMLHttpRequest.prototype.oldsend = unsafeWindow.XMLHttpRequest.prototype.send;
unsafeWindow.XMLHttpRequest.prototype.send = function() {
GM_log('in new send');
GM_log('this.onreadystatechange = ' + this.onreadystatechange);
this.oldonreadystatechange = this.onreadystatechange;
this.onreadystatechange = function() {
if (this.readyState == 2) {
/* LOADED */
unsafeWindow.document.ajax_outstanding++;
GM_log('set ajax_outstanding to ' + unsafeWindow.document.ajax_outstanding);
}
this.oldonreadystatechange.handleEvent.apply(this, arguments);
if (this.readyState == 4) {
/* COMPLETED */
unsafeWindow.document.ajax_outstanding--;
GM_log('set ajax_outstanding to ' + unsafeWindow.document.ajax_outstanding);
}
};
this.oldsend.apply(this, arguments);
};
}
and I go to a page, do something that causes an AJAX request, I get the following message in the javascript error console:
http://www.blah.com/gmscripts/overrides: in new send
uncaught exception: [Exception... "Illegal value" nsresult: "0x80070057 (NS_ERROR_ILLEGAL_VALUE)" location: "JS frame :: file:///tmp/customProfileDir41e7266f56734c97a2ca02b1f7f528e1/extensions/%7Be4a8a97b-f2ed-450b-b12d-ee082ba24781%7D/components/greasemonkey.js :: anonymous :: line 372" data: no]
So it appears to be throwing the exception when trying to access this.onreadystatechange
Presumably, this is due to the sandboxed environment.
Any help would be greatly appreciated. I am not tied to this solution, so any other suggestions for doing what I need are welcome. It's just that I've tried several others and this seems to be the most promising. The requirement is that I need to make sure that the counter gets to 0 after the readyState goes to 4 and the onreadystatechange callback has finished execution.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我自己做了一些东西: http://jsfiddle.net/rudiedirkx/skp28agx/ (更新22 2015 年 1 月)
脚本(应该在其他任何事情之前运行):
以及 jsFiddle 的测试脚本:
它会在每个动画帧(每秒约 60 次)更新按钮中的计数器,与 AJAX 请求分开。无论您做什么,无论点击速度有多快、点击次数多多,几秒钟后计数器都应该始终为 0。
I've made something myself: http://jsfiddle.net/rudiedirkx/skp28agx/ (updated 22 Jan 2015)
The script (should run before anything else):
And the jsFiddle's test script:
It updates the counter in the button every animation frame (~ 60 times per second), separate from the AJAX requests. Whatever you do, however fast and much you click it, the counter should always end up at 0 after a few seconds.
我最终使用了以下内容:
I ended up using the following: