Javascript 噩梦:错误:超时超过2000毫秒。用于异步测试和挂钩
我已经开始用梦魇和摩卡咖啡进行自动化测试。我得到下面的错误,尽管按照错误本身中的说明操作Javascript 噩梦:错误:超时超过2000毫秒。用于异步测试和挂钩,javascript,nightmare,Javascript,Nightmare,我已经开始用梦魇和摩卡咖啡进行自动化测试。我得到下面的错误,尽管按照错误本身中的说明操作 var Nightmare = require('nightmare'); var expect = require('chai').expect; var url = 'http://www.google.com/' describe('Page availability', function() { it('Should open homepage', function(done) {
var Nightmare = require('nightmare');
var expect = require('chai').expect;
var url = 'http://www.google.com/'
describe('Page availability', function() {
it('Should open homepage', function(done) {
var nightmare = Nightmare();
nightmare
.goto(url)
.wait('body')
.evaluate(function () {
return document.querySelector('.gb_P').innerHTML
})
.end()
.then(function(text) {
expect(text).to.equal('images');
done();
})
});
});
使用“mocha test.js”运行上述脚本时,我得到的输出如下:
Page availability
1) Should open homepage
0 passing (2s)
1 failing
1) Page availability Should open homepage:
Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
自白:我(还)不太懂承诺,但我不太明白为什么摩卡咖啡没有解释我当时提供的已完成的回访 这是因为摩卡咖啡的默认超时时间是2秒,而你的噩梦动作可能需要更长的时间才能完成。(众所周知,谷歌需要很长时间才能完成加载。)
在
descripe
或it
中,您可以设置这个.timeout(ms)
,或者在运行mocha命令时使用--timeout[ms]
。我已经为这个完全相同的问题挣扎了好几个小时,终于找到了一个有效的解决方案
首先也是最重要的一点,@Ross在这里是正确的,虽然2秒就足够了,但它并不总是足够的时间等待谷歌或任何其他页面。出于这个原因,我把超时时间提高到了15000毫秒,这是一个安全的赌注,可能是杀伤力过大,但除非你的互联网连接速度非常慢,否则你是安全的
第二,我发现
querySelector(selector).innerHTML
通常返回null。这可能是因为编写选择器路径时涉及大量人为错误,或者javascript或噩梦的.evaluate()
函数在幕后发生了一些其他技术问题
值得一提的是,问题似乎并非源自wait()
函数,因为我发现框架使用相同的查询选择器非常满意,但将innerHTML
属性替换为length
属性
例如:
这将导致超时错误,并且.evaluate()
返回null:
.wait("body > div.wrap > h1")
.evaluate(() => {
return document.querySelectorAll("body > div.wrap > h1").innerHTML;
})
而将innerHTML更改为length将非常顺利
.wait("body > div.wrap > h1")
.evaluate(() => {
return document.querySelectorAll("body > div.wrap > h1").length;
})
我不确定这是为什么,然而,这些是我的发现
因此,为了解决OP的问题,我使用了document.getElementsByClassName()
,这对我来说是一种更简单和/或准确的获取DOM元素的方法
重新编写OP的代码,如下所示:
var Nightmare = require('nightmare');
var expect = require('chai').expect;
var url = 'http://www.google.com/'
describe('Page availability', function() {
this.timeout(15000);
it('Should open homepage', function(done) {
var nightmare = Nightmare();
nightmare
.goto(url)
.wait('body')
.evaluate(function () {
var headerDiv = document.getElementsByClassName("gb_P");
return headerDiv[1].innerHTML
})
.end()
.then(function(text) {
expect(text).to.equal('Images');
done();
})
});
});
通过测试
此外,OP忘记了大写“Images”,这是该类的内部HTML
总之
我不是querySelector(selector)。innerHTML
仍然可以工作,但是,对于针对特定类和id的getElementById()
是一个更安全的选择。它们也可以协同工作,例如,以下代码对我来说运行时没有错误,其中as阻塞了querySelector(selector)中的整个查询选择器。innerHTML
使测试崩溃
.wait("body > div#wpwrap > div#wpcontent > div#wpbody > div#wpbody-content > div.wrap > h1")
.evaluate(() => {
var headerDiv = document.getElementById("wpbody-content");
h1Html = headerDiv.querySelector(".wrap h1").innerHTML;
return h1Html;
})
哦,当我在阅读问题概述中的标题时,我以为你做了一场噩梦。。。但它只是一个图书馆。你找到解决办法了吗?