[英]Cypress: Can I prevent Cypress cy.get from failing if no elements are found?
我正在使用 Cypress cy.get
来抓取元素,但如果没有,我的测试就会失败。 我不希望它失败。 我希望它继续。 测试只是简单地列出那里的项目,如果有的话。
const listItemTitle = '[data-cy-component=list-item-title]';
cy.get(listItemTitle).each(($el, index, $list) => {
cy.wrap($el).then(($span) => {
const spanText = $span.text();
cy.log(`index: ` + index + ' ' + spanText);
});
});
我本以为,如果那里没有元素——这段代码仍然可以,但事实并非如此。 当我运行它时,出现此错误: CypressError: Timed out retrying: Expected to find element: '[data-cy-component=list-item-title]', but never found it.
它在存在元素的地方工作正常。 如果没有找到元素,我想 go on & 做一个不同的测试。
这是我尝试过的一个实验:
let count: number = Cypress.$(listItemTitle).length;
cy.log('before:' + count);
cy.get(actionsBarActionsAdd).click();
cy.get(singlePickerSearch).type('Assets' + '{enter}');
cy.get(listItemCheckboxTitle)
.first()
.click();
cy.toast({
type: 'Success',
});
count = Cypress.$(listItemTitle).length;
cy.log('after:' + count);
cy.get(listItemTitle).each(($li, index, $lis) => {
cy.log('interface no. ' + (index + 1) + ' of ' + $lis.length);
cy.wrap($li).click();
});
这是结果:
18 LOG before:0
19 GET [data-cy-component-key="actions-add"] input
20 CLICK
21 GET [data-cy-component=single-picker-search] input
22 TYPE Assets{enter}
23 GET [data-cy-component="list-item-checkbox-title"]
24 FIRST
25 CLICK
26 GET .iziToast toast2
27 ASSERT expected [ <div.iziToast.iziToast-opening.fadeInUp.iziToast-theme-
alloy.iziToast-color-green.iziToast-animateInside>, 1 more... ] to have class iziToast-color-green
28 LOG after:0
29 GET [data-cy-component=list-item-title]
30 LOG interface no. 1 of 1
最终表明Cypress.$(listItemTitle).length
不计算带有选择器的元素数:listItemTitle。
更新:
通过放置cy.wait(1000)
; 在执行 Add 之后(在我的实验中)——让 DOM 有时间更新——找到了新元素。 使用更具体的选择器,不需要等待
您可以通过Cypress.$
使用 jquery 来检查是否存在。
const listItemTitle = '[data-cy-component=list-item-title]';
if (Cypress.$(listItemTitle).length > 0) {
cy.get(listItemTitle).each(($el, index, $list) => {
cy.wrap($el).then(($span) => {
const spanText = $span.text();
cy.log(`index: ` + index + ' ' + spanText);
});
});
}
执行此操作的理想方法是使用 Gleb Bahmutov 的cypress-if ,但由于 Cypress 版本 12 的更改,它目前已被阻止。
这个问题正在处理中,但与此同时,这里有一个 hack on .should()
执行重试检查,但在没有元素出现时不会失败 - 基于@M.Justin 的方法。
let start = Date.now()
const commandRetry = ($subject, {assert, timeout}) => {
const elapsed = Date.now() - start
console.log(elapsed, assert($subject))
if (elapsed < timeout && !assert($subject)) {
const err = new Error('Retry')
err.isDefaultAssertionErr = true
throw err
}
}
cy.get('li')
.should($subject => commandRetry($subject, {
assert: ($subject) => $subject.length > 0,
timeout: 3000
}))
.should("have.length.gte", 0)
.then($subject => cy.log(`Found ${$subject.length} items`))
下面是我用来测试的web页面。 它最初没有<li>
元素,两秒后添加一个。
您可以看到测试在控制台中重试断言,并在2 秒后通过。
如果您注释掉页面上的脚本,因此没有添加<li>
,您会看到测试运行了4 秒但没有失败。
如果这两种情况都会记录正确的元素计数。
<ul></ul>
<script>
setTimeout(() => {
const ul = document.querySelector('ul')
const li = document.createElement('li')
li.innerText = 'A list item'
ul.appendChild(li)
}, 2000)
</script>
您可以使用cy.get(".field").should("have.length", 0)
以下检索项目,即使没有:
cy.get(listItemTitle).should("have.length.gte", 0)
请注意,如果页面可能仍在加载项目,这不会等待项目存在,因此这可能会在元素尚未存在之前返回。 当您知道这些项目已经加载时,使用它应该是安全的。
这种模式很容易导致有问题的测试,因此请注意何时以及如何使用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.