量角器:如何获取 ngb-alert 的文本
Protractor: how to get the text of ngb-alert
我想测试添加数据源是否有效。通常我在模态中提供信息,单击确认,模态消失并且我的数据源列表现在更长。 (我检查了添加数据源前后的长度,所以我希望列表在编辑后会更长)。
但是,当数据源不存在或已添加时,会弹出 bootstrap 警报并显示错误消息,并且模态保持不变。
我想要的:检查是否出现错误消息,以便我可以显示该错误消息而不是数据源的计数。这样我就能更快地知道为什么我的测试失败了。
我尝试了很多东西,我试过等待浏览器和不等待浏览器。但每次它只是不想看到警报。
来自 SO 的 post 似乎正是我的问题: 但也没有解决我的问题。
这是弹出的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 来确保程序等待,所以下面代码中的所有函数都是异步函数。
所以我尝试像这样达到它(也没有捕获并且有一个额外的超时功能)。这是页面对象中的一个方法,这就是为什么它 returns 值:
(脚本 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)
})
此处无论是否出现警报,测试总是进入 'is present (false)'。我喜欢它不会在我的测试中失败,但我希望它在弹出警报时注意到。
像这样(也在测试里面):
(脚本 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 搜索它以前是有效的。
编辑:
所以我注意到我的脚本 2 已经很好了,但是由于某种原因 until.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)
})
这个returns
browser.wait.then 真: 假
browser.wait.catch: JavascriptError: javascript 错误: angular 未定义
再试一次...
好的,所以这里我使用 until.presenceOf (until = 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 秒)还长。
我找到了答案here:
...the alert’s internal dismiss functionality has been implemented with Angular’s $timeout service which increments $browser’s outstanding request count and protractor with ignoreSynchronization=false waits correctly until there is any outstanding requests. This means if you do not disable the synchronization, you cannot see the opened alert, because protractor suspends execution until it is visible...
但是 ignoreSynchronization 已被弃用 所以你需要使用
await browser.waitForAngularEnabled(false)
。这确保它不会等到警报消失后才检查警报的内容。
所以这是我在出现警报时获取 ngb-alert 文本的代码(对于我的代码,我不希望发生错误,但当它发生时,我想知道是什么错误):
await browser.waitForAngularEnabled(false);
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)
})
await browser.waitForAngularEnabled(true);
P.S.: 通过绑定获取元素不是你可以用angular 5,会出现如下错误:
"JavascriptError: javascript error: angular is not defined".
我想测试添加数据源是否有效。通常我在模态中提供信息,单击确认,模态消失并且我的数据源列表现在更长。 (我检查了添加数据源前后的长度,所以我希望列表在编辑后会更长)。
但是,当数据源不存在或已添加时,会弹出 bootstrap 警报并显示错误消息,并且模态保持不变。
我尝试了很多东西,我试过等待浏览器和不等待浏览器。但每次它只是不想看到警报。
来自 SO 的 post 似乎正是我的问题:
这是弹出的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 来确保程序等待,所以下面代码中的所有函数都是异步函数。 所以我尝试像这样达到它(也没有捕获并且有一个额外的超时功能)。这是页面对象中的一个方法,这就是为什么它 returns 值:
(脚本 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)
})
此处无论是否出现警报,测试总是进入 'is present (false)'。我喜欢它不会在我的测试中失败,但我希望它在弹出警报时注意到。
像这样(也在测试里面): (脚本 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 搜索它以前是有效的。
编辑:
所以我注意到我的脚本 2 已经很好了,但是由于某种原因 until.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)
})
这个returns
browser.wait.then 真: 假
browser.wait.catch: JavascriptError: javascript 错误: angular 未定义
再试一次...
好的,所以这里我使用 until.presenceOf (until = 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 秒)还长。
我找到了答案here:
...the alert’s internal dismiss functionality has been implemented with Angular’s $timeout service which increments $browser’s outstanding request count and protractor with ignoreSynchronization=false waits correctly until there is any outstanding requests. This means if you do not disable the synchronization, you cannot see the opened alert, because protractor suspends execution until it is visible...
但是 ignoreSynchronization 已被弃用 所以你需要使用
await browser.waitForAngularEnabled(false)
。这确保它不会等到警报消失后才检查警报的内容。
所以这是我在出现警报时获取 ngb-alert 文本的代码(对于我的代码,我不希望发生错误,但当它发生时,我想知道是什么错误):
await browser.waitForAngularEnabled(false);
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)
})
await browser.waitForAngularEnabled(true);
P.S.: 通过绑定获取元素不是你可以用angular 5,会出现如下错误:
"JavascriptError: javascript error: angular is not defined".