【发布时间】:2017-11-13 10:13:15
【问题描述】:
我在使用 Protractor 为 AngularJS 应用程序开发的测试套件中编写其中一个测试时遇到了一个奇怪的问题。
在最初开发测试时,我使用了对browser.pause() 的调用来确保我必须手动告诉测试在运行测试脚本时执行每一行。我现在很高兴到目前为止我编写的测试都正确执行并且所有测试都根据它们的标准正确通过/失败。
我现在想删除对browser.pause() 的调用,以便脚本可以自动运行每个测试,而无需任何用户交互。但是,由于应用程序是 Angular,这样做会导致一些时间问题/在执行引用它们的测试步骤之前等待元素加载 - 所以我目前正在检查每个测试,并试图确保它们是允许元素在与元素交互之前加载/等待元素所需的时间等。
当我现在运行我的测试脚本时,它在第二次测试中失败了(导航到导出页面),我编写如下:
it('should navigate to the Export page', function() {
browser.waitForAngularEnabled(false);
browser.wait(EC.elementToBeClickable(exportMenuBtn), 25000).then(
browser.actions().mouseMove(exportMenuBtn).perform().then(
exportMenuBtn.click().then(
function() {
console.log("Export page test completed ");
expect(browser.getCurrentUrl()).toBe(VM + '/#/export');
}
)
)
);
});
我在运行脚本的命令行中收到的错误消息是:
失败:未知错误:元素 ... 在点 (40, 301) 处不可点击。其他元素会收到点击:
<div tabindex="-1" role="dialog" class="modal fade ng-isolate-scope ult-loading modal-message ng-animate in-remove in-remove-active" ng-class="{in: animate}" ng-style="{'z-index': 1050 + index*10, display: 'block'}" ng-click="close($event)" modal-window="" window-class="ult-loading modal-message" size="sm" index="0" animate="animate" style="z-index: 1050; display: block;; transition-property: opacity;transition-duration: 0.15s;">...</div>
(会话信息:chrome=62.0.3202.89) (驱动信息:chromedriver=2.33.506120 (e3e53437346286c0bc2d2dc9aa4915ba81d9023f),platform=Windows NT 10.0.16299 x86_64)
这向我表明 exportMenuBtn 元素在我的测试脚本试图对其调用 .click() 时不是“可点击的”。但这没有意义,因为我已经使用browser.wait(EC.elementToBeClickable(exportMenuBtn), 25000) 行等待exportMenuBtn 元素可点击,然后再尝试点击它...
我已尝试增加等待元素可点击的时间,但这似乎没有什么不同...
谁能解释为什么这个测试失败了?如何确保测试在尝试单击之前等待 exportMenuBtn 元素可单击?
编辑
所以我尝试按照@Ernst Zwingli 在他们的回答中建议的操作 - 添加了一个函数来关闭我的spec.js 文件的对话框:
var pageLoaded = function() {
var blockingElement = $('div[window-class="ult-loading modal-message"');
return EC.invisibilityOf(blockingElement);
}
module.exports = new pageLoaded();
然后将测试脚本更新为:
it('should navigate to the Export page', function() {
browser.waitForAngularEnabled(false);
browser.wait(pageLoaded, 5000);
exportMenuBtn.click();
browser.wait(pageLoaded, 5000);
browser.wait(EC.urlIs(VM + '/#/export'), 5000);
});
但我的测试脚本仍然失败,给出同样的错误信息:
失败:未知错误:元素
<a href="#/export" target="_self">...</a>
在点 (40, 301) 处不可点击。
其他元素会收到点击:
<div tabindex="-1" role="dialog" class="modal fade ng-isolate-scope ult-loading modal-message ng-animate in-remove in-remove-active" ng-class="{in: animate}" ng-style="{'z-index': 1050 + index*10, display: 'block'}" ng-click="close($event)" modal-window="" window-class="ult-loading modal-message" size="sm" index="0" animate="animate" style="z-index: 1050; display: block;; transition-property: opacity;transition-duration: 0.15s;">...</div>
(Session info: chrome=62.0.3202.89) (Driver info: chromedriver=2.33.506120 (e3e53437346286c0bc2d2dc9aa4915ba81d9023f),platform=Windows NT 10.0.16299 x86_64)
似乎导致问题的对话框在 Dialog/service.js 中定义:
function wait(msg, progress, title) {
// Create a wait dialog
var dlg = dialogs.wait(
title,
msg,
progress,
{
// Disable keyboard ESC to close dialogue instances
keyboard: false,
// lock the background window
backdrop: "static",
size: "sm",
windowClass: "ult-loading modal-message",
animation: false
}
);
// Push the dialog into the pool
dlgs.push(dlg);
// Return the created dialog
return dlg;
}
在手动运行测试/浏览页面时,此对话框实际上永远不可见,因此它似乎是在浏览/加载新页面时运行的某种“后台任务”。我还应该注意,此对话框是在 factory 中定义的:
.factory('DialogMgr', function($rootScope, $document, dialogs) {
...
function wait(...) {
...
}
});
我想知道这是否与对话框中设置的“淡入淡出”动画有关?我将如何解决这个问题?
【问题讨论】:
标签: angularjs protractor automated-tests wait