我开始尝试使用Nightmare和mocha进行自动化测试。我收到了下面的错误,尽管遵循了错误本身的指令。
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.
忏悔:我还没有(还)熟悉承诺,但我不明白为什么摩卡没有考虑到我所做的完成回调在里面提供。
答案 0 :(得分:1)
这是因为Mocha的默认超时时间为2秒,您的梦魇动作可能需要比完成时间更长的时间。 (Google花了很长时间才完成加载。)
在describe
或it
内,您可以设置this.timeout(ms)
,或在运行mocha命令时使用--timeout [ms]
。
答案 1 :(得分:0)
我一直在努力解决这个完全相同的问题几个小时,终于找到了一个有效的解决方案!
首先@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已经忘记利用图像'这是该类的innerHTML。
总结,
我不是querySelector(selector).innerHTML
仍可以使用,但是,针对特定的类和ID getElementById()
是更安全的选择。它们也可以串联工作,例如下面的代码运行时没有错误,因为在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;
})