我正在开发一套自动化测试,使用量角器在AngularJS应用程序上运行。在完成此任务之前,我从未使用过自动化测试,因此我仍然不熟悉它的工作原理/如何实现测试等。
我最近在实现自动单击对话框的"取消"按钮时遇到了一些麻烦,当其中一个测试浏览到特定页面时,该对话框会自动显示。
我现在已经单击"取消"按钮成功工作,但由于异步回调错误,测试脚本仍然失败。
测试脚本编写如下:
it('should navigate to the Charts page', function(done) {
console.log("Start Charts page test");
browser.waitForAngularEnabled(false);
browser.actions().mouseMove(chartsMenuBtn).perform();
chartsMenuBtn.click();
browser.waitForAngularEnabled(true);
//browser.sleep(5000);
browser.call(closeDlg);
//var closeDlgFn = closeDlg();
//browser.wait(closeDlgFn, 5 * 1000, 'Dialog should close within 5 seconds');
console.log("End Charts page test");
expect(browser.getCurrentUrl()).toBe('http://192.168.1.212:8080/#/charts');
});
脚本中调用的closeDlg()
函数定义如下:
function closeDlg(){
browser.waitForAngularEnabled(false);
console.log("closeDlg() function called ")
var EC = protractor.ExpectedConditions;
var chartConfigForm = element(by.id('chartConfigForm'));
var closeDlgBtn = element(by.id('editGraphCancelBtn'));
console.log("About to click closeDlgBtn ");
closeDlgBtn.click();
console.log("just clicked closeDlgBtn ");
console.log("End of closeDlg() function ")
}
browser.call(closeDlg).then(function(){console.log("End Charts page test"); done();});
当我按当前状态运行脚本时,我在命令行中得到以下输出:
."开始图表"页面测试
结束图表页面测试
-- 下一个命令:查找元素
-- 下一个命令:鼠标移动到
-- 下一个命令:查找元素
-- 下一个命令:单击元素
closeDlg() 函数调用
即将单击关闭DlgBtn
刚刚点击关闭DlgBtn
closeDlg() 函数结束 -- 下一个命令:查找元素
显示全部内容后,对话框当前仍在浏览器中打开。当我继续逐步完成测试时,我在命令行中收到以下两个提示:
-- 下一个命令:单击元素
结束图表页面测试
-- 下一个命令:执行异步脚本
这就是对话框关闭的时候。
如果我继续执行我的测试脚本,我会失败:
FA 茉莉花规格超时。重置 Web 驱动程序控制流。
茉莉花规格超时。重置 Web 驱动程序控制流。
失败:
1)应用程序应导航到图表页面
消息:
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
叠:
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL. at ontimeout (timers.js:386:11) at tryOnTimeout (timers.js:250:5) at Timer.listOnTimeout (timers.js:214:5)
消息:
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
叠:
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL. at ontimeout (timers.js:386:11) at tryOnTimeout (timers.js:250:5) at Timer.listOnTimeout (timers.js:214:5)
5 个规格,1 个故障
在260.014秒内完成
我在网上找到的所有内容似乎都表明我应该在jasmine.js
中增加j$.DEFAULT_TIMEOUT_INTERVAL
变量的值,我已经做到了 - 我已将其从 10000(默认值)增加到 500000。
我还在conf.js
文件中添加了一个allScriptsTimeout
值:
exports.config = {
framework: 'jasmine',
seleniumAddress: 'http://localhost:4444/wd/hub',
specs: ['spec.js'], // List all of the different files in which the tests are defined here
allScriptsTimeout: 120000,
onPrepare: function() {
browser.addMockModule('disableModalAnimations', function(){
angular.module('disableModalAnimations', []).value('foo', 'bar');
});
},
multiCapabilities: {
browserName: 'firefox'
}
}
我不明白为什么我会收到这个超时错误?
我尝试将测试脚本中对closeDlg()
的调用更改为:
browser.call(closeDlg).then(function(){console.log("End Charts page test"); done();});
但仍然得到相同的错误。
我怀疑这个问题实际上是超时问题,但我不确定我是否正确执行异步脚本。
谁能发现我在这里做错了什么?错误告诉我的异步回调在指定的超时时间内未调用是什么?我正在做的哪一部分是异步的?
因此,在对代码进行了大量混乱,砍伐和更改,尝试了不同的方法,并在网上查看了各种文章以获取有关如何执行此操作的建议之后,我终于通过将测试的expect
子句放在链接到对我的closeDlg()
函数调用的.then()
函数中(并将其从测试的it()
级别中删除):
it('should navigate to the Charts page', function() {
console.log("Start Charts page test");
browser.waitForAngularEnabled(false);
browser.actions().mouseMove(chartsMenuBtn).perform();
chartsMenuBtn.click();
browser.waitForAngularEnabled(true);
browser.call(closeDlg).then(function(){
expect(browser.getCurrentUrl()).toBe('http://192.168.1.212:8080/#/alarms');
});
此测试现在正确通过,并且逐步完成,我可以看到它按预期执行命令,并产生正确的结果。
虽然你自己回答了,但我会添加一些信息:
- 承诺按哪个顺序解决,可以在这里找到
- 这个答案在这里解释了,
browser.call()
是用来做什么的。
在我看来,只有函数调用,您的browser.call()
毫无意义。它甚至很可能导致您的问题,因为它将您调用的函数添加到 controlFlow 的末尾,导致在执行其他所有内容后最终执行它。
此外,您的关闭/打开/关闭browser.waitForAngularEnabled()
也令人困惑。我建议根本不打开它,因为它可能是您一开始关闭它的原因。
通过在浏览器调用后使用then()
,您可以强制expect
部分在browser.call()
之后执行。虽然你没有解决你遇到的问题,但你通过强制其他代码行在你的"问题"行后面来解决它。
阅读您的代码,我认为没有任何理由使用browser.call()
.
var closeDlgPage = require('[relativePathTo]/closeDlgPage.js');
it('should navigate to the Charts page', function(done) {
console.log("Start Charts page test");
browser.waitForAngularEnabled(false);
browser.actions().mouseMove(chartsMenuBtn).perform();
chartsMenuBtn.click();
//browser.waitForAngularEnabled(true);
closeDlgPage.closeDlg();
console.log("End Charts page test");
expect(browser.getCurrentUrl()).toBe('http://192.168.1.212:8080/#/charts');
});
和您的closeDlg()
(您当然可以删除所有console.log()
以使其更短:
//look how PageObjects in Protractor work, if this looks new to you.
closeDlgPage= function(){
this.closeDlg = function(){
console.log("closeDlg() function called ");
//var EC = protractor.ExpectedConditions; //You're not using EC in this function.
var chartConfigForm = element(by.id('chartConfigForm'));
var closeDlgBtn = element(by.id('editGraphCancelBtn'));
console.log("About to click closeDlgBtn ");
closeDlgBtn.click();
console.log("just clicked closeDlgBtn ");
console.log("End of closeDlg() function ")
};
};
module.exports = new closeDlgPage();