这将是一个很长的问题:p
我有这个测试,大约有50%的时间没有找到"没有找到任何元素"即使我对element.isPresent和element.isDisplayed做了明确的等待并等待每个承诺得到解决,基本上删除了任何异步性。
基本上,场景如下:用户将鼠标悬停在表格单元格上,出现一个呼出(并且显示我的意思是创建不仅仅是可见的),如下所示:
用户然后单击编辑按钮,呼出变为:
用户输入一些文本,单击“保存”按钮,看到呼叫框中的值已更新。用户重复操作,但这次单击取消按钮,并看到已更改的值已被丢弃
除此之外我做的是保存初始值并重复"悬停和编辑"将细胞内容恢复到测试运行前的状态的动作。
这是代码:
规格:
var editMemoBoxAction = function(box){
var data = page.editMemoBox(box,'',false);
return data.then(function(backup){
if(backup == 'No data.') backup = '';
expect(page.editMemoBox(box,'abc',true)).toEqual('abc');
expect(page.editMemoBox(box,'xyz',false)).toEqual('abc');
return page.editMemoBox(box,backup,true);
});
};
it('does stuff', function(){
page.mouseOver('Future Contract Action').then(function(){
editMemoBoxAction('Future Contract Action').then(function(){
page.mouseOver('Future Contract Action');
});
});
});
页面对象:
this.mouseOver = function(box){
var headers = element.all(by.xpath('//table/thead/tr/th')).map(function(elm){
return elm.getText();
});
return headers.then(function(list){
if(list.length == 0) return undefined;
var elm = element(by.xpath('//table/tbody/tr[1]/td[' + (list.indexOf(box) + 1) + ']'));
return browser.actions().mouseMove(elm).perform().then(function(){
return true;
});
});
};
this.editMemoBox = function(box, value, save){
var headers = element.all(by.xpath('//table/thead/tr/th')).map(function(elm){
return elm.getText();
});
return headers.then(function(list){
if(list.length == 0) return undefined;
var timeout = 10000;
var text = element(by.xpath('//div[@class=\'popover-content\']/div/div/div[1]')); // CONTAINS THE INITIAL TEXT VALUE OF THE CALL OUT
return browser.wait(function(){return text.isPresent;}, timeout).then(function(){
return browser.wait(function(){return text.isDisplayed;}, timeout).then(function(){
return text.getText().then(function(backup){
if (backup == 'No data.') backup = '';
var button = element(by.xpath('//div[@class=\'popover-content\']/div/div/div[2]')); // THE EDIT BUTTON
return browser.wait(function(){return button.isPresent;}, timeout).then(function(){
return browser.wait(function(){return button.isDisplayed;}, timeout).then(function(){
return button.click().then(function(){
var edit = element(by.model('data.editValue')); // THE EDITABLE TEXT AREA
return browser.wait(function(){return edit.isPresent;}, timeout).then(function(){
return browser.wait(function(){return edit.isDisplayed;}, timeout).then(function(){
return edit.clear().then(function(){
return edit.sendKeys(value).then(function(){
var confirm; // EITHER THE SAVE OR CANCEL BUTTON
if(save == true){
confirm = element(by.xpath('//span[@class=\'glyphicon glyphicon-ok glyphicon-lg\']'));
}
else {
confirm = element(by.xpath('//span[@class=\'glyphicon glyphicon-remove glyphicon-lg\']'));
}
return browser.wait(function(){return confirm.isPresent;}, timeout).then(function(){
return browser.wait(function(){return confirm.isDisplayed;}, timeout).then(function(){
return confirm.click().then(function(){
var result = element(by.xpath('//div[@class=\'popover-content\']/div/div/div[1]')); // THE NEW VALUE OF THE CALL OUT
return browser.wait(function(){return result.isPresent;}, timeout).then(function(){
return browser.wait(function(){return result.isDisplayed;}, timeout).then(function(){
return result.getText();
});
});
});
});
});
});
});
});
});
});
});
});
});
});
});
});
};
这是非常难看的,因为我尝试了一切来消除代码中任何位置存在的任何异步性,因为我的问题绝对是时间问题而且我在这个讨厌的事情的第2天。 在文本编辑器中复制代码可能是值得的。
现在,它不应该有任何时间问题,因为在与元素的每次互动之前,我都会明确地等待element.isPresent
和element.isDisplayed
,并且在每一点都出现一个承诺我等待它在做任何其他事情之前要解决。
它现在做的是它失败了"没有找到任何元素"在我与之互动的其中一个元素(每次都不是同一个元素)。它经历的时间大约有50%。
如果我能说得更清楚,请告诉我。
我知道这很多阅读,但它既是一个有趣的问题,也可能是我的愚蠢,这两个都应该很有趣:p
谢谢!
答案 0 :(得分:2)
我会尝试的事情:
presenceOf
,visibilityOf
预期条件。并且,我认为您不需要明确解决browser.wait()
设置更大的隐式等待超时。把它放到onPrepare
:
browser.manage().timeouts().implicitlyWait(10000); // 10 seconds, try to play around with the value
必要时使用browser.sleep()
。一般来说,在测试中引入人为的“硬编码”延迟并不是一个好习惯,但在这里的屏幕转换之间,它可能会有所帮助
browser.isElementPresent(elem)
代替elem.isPresent()
(仅供参考,有差异,请参阅In protractor, browser.isElementPresent vs element.isPresent vs element.isElementPresent)