我想测试添加数据源是否有效。通常,我以模态形式输入信息,然后单击“确认”,模态消失,并且我的数据源列表现在更长。 (我在添加数据源之前和之后检查长度,因此我希望列表在编辑后会更长)。 但是,当数据源不存在或已被添加时,将弹出一个自举警报,并显示一条错误消息,并保留模式。 我想要的是:检查是否出现错误消息,以便可以显示该错误消息而不是数据源的数量。这样,我可以更快地知道测试失败的原因。
我尝试了很多事情,我尝试等待浏览器,而不等待浏览器。但是每次它都不想看到警报。
SO的这篇帖子似乎正是我的问题:protractor: testing bootstrap alerts,但也没有解决我的问题。
这是弹出的html代码:
<dm-alert>
<ngb-alert>
<div role="alert" class="alert alert-danger alert-dismissible">
<button aria-label="Close" class="close" type="button">
<span aria-hidden="true">×</span>
</button>
The description '4106-5002-5005-5006-02' has to be unique
</div>
</ngb-alert>
</dm-alert>
我使用async / await来确保程序正在等待,因此以下代码所在的所有函数都是异步函数。 因此,我尝试以这种方式达到目标(也没有问题,并且超时时有额外的功能)。这是页面对象中的一种方法,这就是它返回值的原因:
(脚本1)
import { $, browser, by, element, ExpectedConditions as until } from 'protractor';
await browser.wait(until.presenceOf(element(by.xpath('//ngb-alert/div[contains(@class, alert-danger)]'))), waitTimeForErrorInSeconds * 1000).then((isPresent) => {
return isPresent;
}).catch(() => {
console.log('no error occured')
return false;
})
return false;
就像这样,这个只是在测试中: (脚本2)
await browser.wait(until.presenceOf(element(by.xpath('//ngb-alert/div[contains(@class, alert)]'))), 10 * 1000)
.then((isPresent) => {
console.log('is present (true): ' + isPresent);
let text = element(by.xpath('//ngb-alert/div[contains(@class, alert)]')).getText();
console.log(text);
}, (isPresent) => {
console.log('is present (false): ' + isPresent)
}).catch((error) => {
console.log('browser.wait.catch: ' + error)
})
此处,无论是否出现警报,测试始终进入“存在(错误)”状态。我喜欢它不会失败,但是我希望它能够在警报弹出时发出通知。
并且这样(也在测试内): (脚本3)
expect(element(by.xpath('//ngb-alert/div[contains(@class, alert)]'))
.isDisplayed())
.toBeFalsy();
isDisplayed总是出现错误,因为找不到元素
(脚本4)
expect(element(by.xpath('//ngb-alert/div[contains(@class, alert)]'))
.isPresent())
.toBeFalsy();
isPresent在没有错误的情况下效果很好,但是在没有错误的情况下不会发出提示。
我通过在chrome的开发工具中搜索XPath来检查XPath,如果存在,它总是立即找到它,所以这不应该成为问题。在尝试所有这些东西之前,我已经使它起作用了。因此,以前通过XPath进行搜索就可以了。
所以我注意到我的脚本2已经很好,但是由于某种原因,直到.presenceOf无法正常工作,但是如果我对元素执行了.isPresent(),它似乎确实找到了该元素。但是为什么呢?
这是警报的代码:
<ngb-alert [type]="notification.category" (close)="close(notification)">
{{ notification.message }}
</ngb-alert>
所以我认为其中之一应在脚本2(第5行)中工作以获取通知文本:
element(by.xpath('//ngb-alert')).getText();
element(by.xpath('//ngb-alert/div')).getText();
element(by.xpath('//ngb-alert/div[contains(@class, alert)]')).getText();
element(by.binding('notification.message')).getText();
element(by.binding('notification.message')).$('ngb-alert').getText();
但是他们没有...
因此,可以尝试以下方法: (脚本5)
await browser.wait((element(by.xpath('//ngb-alert/div[contains(@class, alert-danger)]')).isPresent()), 3 * 1000)
.then((isPresent) => {
console.log('browser.wait.then true: ' + isPresent)
element(by.binding('notification.message')).$('ngb-alert').getText()
.then((text) => {
console.log(text);
});
}, (isPresents) => {
console.log('browser.wait.then false: ' + isPresents)
}).catch((error) => {
// if fails
console.log('browser.wait.catch: ' + error)
})
返回
browser.wait.then true:false
browser.wait.catch:JavascriptError:JavaScript错误:未定义角度
好,所以在这里我使用直到.presenceOf(直到= ExpectedConditions)并且没有xpath:
await browser.wait(until.presenceOf($('.alert-danger')), 3 * 1000)
.then((isPresent) => {
console.log('browser.wait.then true: ' + isPresent);
$('ngb-alert').element(by.binding('notification.message')).getText().then((text) => {
console.log(text);
});
}, (isPresents) => {
console.log('browser.wait.then false: ' + isPresents)
}).catch((error) => {
console.log('browser.wait.catch: ' + error)
})
这里发生的是,当没有警报显示时,它会给出我期望的响应:
browser.wait.then false: TimeoutError: Wait timed out after 3013ms
但是当警报显示时,它将等待直到警报消失,然后告诉我:
browser.wait.then false: TimeoutError: Wait timed out after 7664ms
那么为什么它突然等待的时间超过了我给出的超时时间(3秒)。
答案 0 :(得分:0)
最后,我找到了答案here。我必须添加ignoreSynchronization。因为在显示通知时计时器会关闭,所以它会一直等待直到检查通知为止。真是令人不安,这就是原因...
因此,这是对我有用的代码,用于在发生警报时获取ngb警报的文本(对于我的代码,我不希望发生错误,但是当发生错误时,我希望能够知道是什么错误):
browser.ignoreSynchronization = true;
await browser.wait(until.presenceOf(element(by.css('.alert-danger'))), 5 * 1000)
.then((isPresent) => {
console.log('presence of error: ' + isPresent);
$('ngb-alert').getText().then((errorAlert) => {
expect('no error').toBe('displayed',
'This error showed up when adding data source: ' + errorAlert)
});
}, (isNotPresent) => {
console.log('no presence of error: ' + isNotPresent)
}).catch((error) => {
console.log('checking presence of error caused an error: ' + error)
})
browser.ignoreSynchronization = false;
P.S .:显然,通过绑定来获取元素不是用angular 5可以做到的,但会出现此错误:
"JavascriptError: javascript error: angular is not defined".