英文:
Cypress: How to catch error when the 'should' assertion is failed
问题
I need to catch an error when the should
assertion is failed.
Imagine that the first assertion for .should('not.exist') is failed (the element is still visible)
Example of what I need (but this is not working for Cypress and JS):
this.containsInIframe('tr', assetName)
.find('div.loader', { timeout: 100000 })
.should('not.exist')
.catch((error) => {
this.reloadPage();
this.containsInIframe('tr', assetName)
.find('div.loader', { timeout: 100000 })
.should('not.exist');
});
How to deal with this situation using Cypress and JS? Can anyone suggest a way of solving this problem?
How to catch the error thrown by the Cypress 'should' assertion?
英文:
I need to catch an error when the should
assertion is failed.
Imagine that the first assertion for .should('not.exist') is failed( the element is still visible)
Example of what I need(but this is not working for Cypress and JS):
this.containsInIframe('tr', assetName)
.find('div.loader', { timeout: 100000 })
.should('not.exist')
.catch((error) => {
this.reloadPage();
this.containsInIframe('tr', assetName)
.find('div.loader', { timeout: 100000 })
.should('not.exist');
});
How to deal with this situation using Cypress and JS? Can anyone suggest a way of solving this problem?
How catch the error thrown by the cypress 'should' assertion?
答案1
得分: 5
抓取错误相当复杂,因为Cypress的操作方式并不完全一样。
如果您想要重试(如捕获代码所示),Cypress测试运行器内建了该功能。
it('重试测试', {retries: {runMode: 2, openMode: 1}}, function() {
.. 测试代码
})
英文:
Catching the error is fairly complicated, as Cypress doesn't operate exactly that way.
If you want to retry (as the catch code suggests), that feature is built in to Cypress runner.
it('retries the test', {retries: {runMode: 2, openMode: 1}}, function() {
.. test code
})
答案2
得分: 3
以下是翻译好的部分:
- 你可以尝试递归
- 递归重复执行代码,直到满足条件(例如
$loader.length === 0
,等同于.should('not.exist')
,但不会导致测试失败并停止) cy.reload()
清除页面并创建新元素,因此不要依赖先前的结果,而是始终重新查询(看起来你正在这样做)- 在递归调用之前进行小的
cy.wait()
可以阻止不必要的循环,但你应该调整等待时间,确保重新加载和后台操作已完成 - 递归调用应该在“队列上”执行,因为涉及到 Cypress 队列命令,这就是为什么它被包装在
cy.then()
中的原因 - 如果你怀疑会有时候加载器永远不会消失,你应该限制递归的次数,否则堆栈可能会溢出。
英文:
You could try recursion
function reloadUntilLoaderHasGone() {
this.containsInIframe('tr', assetName)
.then($tr => {
const $loader = $tr.find('div.loader')
if ($loader.length > 0) {
cy.reload()
cy.wait(300)
cy.then(() => reloadUntilLoaderHasGone())
}
})
}
reloadUntilLoaderHasGone()
It's a bit hard to get the exact pattern from the code fragment, but the basic points are
-
recursion repeats the code until a condition is met (e.g
$loader.length === 0
which is equivalent to.should('not.exist')
but does not fail and stop the test) -
cy.reload()
clears the page and creates new elements, so don't rely on any prior result, instead always re-query (looks like you are doing that) -
a small
cy.wait()
before the recursive call stops unnecessary cycles, but you should tune the wait time - enough so that reload and background action has completed -
the recursive call should be done "on-the-queue" since you have Cypress queue commands involved, which is why it's wrapped in
cy.then()
-
if you suspect there will be times when the loader never goes away, you should put a limit on the number of recursions - otherwise stack will overflow
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论