Cypress:测试元素是否不存在

383
我希望能够单击复选框并测试在 Cypress 中元素是否不再存在于 DOM 中。有人能建议一下该如何做吗?

我想要能够单击复选框并测试在 Cypress 中元素是否不再存在于 DOM 中。有人能建议一下该如何做吗?

// This is the Test when the checkbox is clicked and the element is there

cy.get('[type="checkbox"]').click();
cy.get('.check-box-sub-text').contains('Some text in this div.')

我想做与上面测试相反的事情。

因此,当我再次点击时,具有类check-box-sub-text

不应存在于DOM中。


2
我知道这与你的问题无关,但我非常好奇。为什么要使用只支持Chrome的东西,并且Cypress有什么更好的地方?我一直在开源项目Courgette https://github.com/canvaspixels/courgette 上工作,想知道是哪些功能吸引了大家使用Cypress。 - alexrogers
1
我喜欢Cypress,因为它大多数情况下很容易使用,而且它的工作效果很好。我知道它只能在Chrome中使用的问题,但对我来说,这个问题并不是很大。 - Maccurt
cy.get('.check-box-sub-text').contains('Some text in this div.') 在某些情况下可能无法正常工作(在某些设备上)。您可以将其替换为 cy.contains('.check-box-sub-text', 'Some text in this div.'),它将以相同的方式工作。 - ulou
2
我认为你应该将问题澄清为“测试元素是否已被删除”。否则,它会与另一个问题“测试元素是否从未存在”混淆。根据情况不同,技术含义和答案也会有所不同。 - Eric Burel
@alexrogers,有时候你并不需要进行跨浏览器测试,而只需要快速启动一些端到端测试。对于不能承担测试所有浏览器却能勉强支持端到端测试的小型团队来说,这尤其有帮助。 - chesscov77
@alexrogers:如果你开发Android应用程序,Chrome就是你所需要的;适应不同的目标会带来更多的复杂性和潜在的错误...另外:没有必要测试你的目标是否正确实现(这是目标开发人员的职责)。你只需要测试自己的代码...至少理论上是这样的... - Fred
19个回答

521

嗯,这似乎起作用了,所以它告诉我还有更多关于.should()的知识需要学习。

cy.get('.check-box-sub-text').should('not.exist');

13
你好!我将尽力为您翻译以下内容:HI! 我正在使用几乎相同的代码:cy.get(data-e2e="create-entity-field-relation-contact-name").should('not.exists'),但在执行 get 时失败了,然后尝试多次调用 should,每次都失败了......你有什么想法吗?谢谢。 - volk
抱歉,我刚看到你的评论,你的选择器是在数据属性上工作吗?你可以在评论中粘贴你的HTML吗?那个选择器对我来说看起来很奇怪! - Maccurt
13
@Maccurt, @YingYang:实际上我发现了错误,而且这个错误有点儿傻:在 should 中存在多余的s.should('not.exists') -> .should('not.exist') - volk
10
这适用于被移除的情况。但是,如果你希望它从未存在过......https://docs.cypress.io/guides/references/assertions.html#Existence 它会重试直到它消失。这并不适用于标题问题,这是大多数人会寻找的内容。 - Urasquirrel
你也可以使用 cy.get('.check-box-sub-text').contains('Some text in this div.').should('not.exist'); ... 基本上只需添加 .should('not.exist'); 就可以使其相反。 - nawlbergs
显示剩余2条评论

110

您还可以搜索一个不应存在的文本:

cy.contains('test_invite_member@gmail.com').should('not.exist')

这里是Cypress的结果:0匹配元素

在此输入图片描述

参考文献:文档 - 断言,存在性


13
这对我没用,contains超时导致测试失败。 CypressError: 超时重试:期望找到内容:“我不应该在这里”,但从未找到。 - Tim Abell
我在我的回答中添加了更多的解释和示例。删除用户“test_invite_member@gmail.com”后,我正在检查该电子邮件是否存在于其他地方。结果是“0个元素”。您使用的Cypress版本是什么? - Alan
感谢更新。npx cypress --version - Cypress包版本:3.5.0 Cypress二进制版本:3.5.0 - Tim Abell
1
现在对我来说可以工作了,我其实不确定我错过了什么。谢谢你的帮助。 - Tim Abell
5
在 Cypress 4 中对我无效。它似乎适用于已删除的元素,而不是根本不存在的元素(例如在测试服务器端渲染时)。 - Eric Burel
should('not.exist') is the other way round to should('exist') where contains is at the end: cy.getByData('success_msg').should('exist').contains(address) - Timo

79

使用.should('not.exist')来断言元素在DOM中不存在。


不要使用not.visible断言。在版本号低于6.0之前会错误地通过,但现在会正确地失败:

// for element that was removed from the DOM
// assertions below pass in < 6.0, but properly fail in 6.0+
.should('not.be.visible')
.should('not.contain', 'Text')

迁移文档在此处:Migrating-to-Cypress-6-0


我会调查这个问题并升级到6版。 - Maccurt
1
我们能否检索布尔标志,例如true或false? - Ashok kumar Ganesan
这意味着 not.exist/exist 检查 DOM 中的存在性?而 visible/not visible 检查 UI 中的存在性。 - Ashok kumar Ganesan
1
在 Cypress 8 中,should not exist 不起作用。如果 Cypress 没有找到该元素,则会失败。相反,not visible 是有效的。 - Syed Ali
@t_dom93 这是一个很好的答案,我正在面临一个问题,我已经在这里发布了https://stackoverflow.com/questions/74546052/trigger-method-in-cypress。你能帮我解决这个问题吗? - madhuri varada

39

Cypress 6.x+ 迁移

根据Cypress文档的存在性检查

这种非常流行的尝试有点天真,它能够工作直到它不能工作为止,然后您将不得不再次重写它...一遍又一遍...

// retry until loading spinner no longer exists
cy.get('#loading').should('not.exist')

这对于大多数人关注的标题问题并不起作用。

它适用于被删除的情况。但是,如果您希望它永远不存在... 它将重试直到消失。

然而,在我们的情况下,如果您想测试该元素从未存在过。

是的,哈哈。这正是您真正想要的,除非您想再次头痛。

// Goes through all the like elements, and says this object doesn't exist ever
cy.get(`img[src]`)
  .then(($imageSection) => {
    $imageSection.map((x, i) => { expect($imageSection[x].getAttribute('src')).to.not.equal(`${Cypress.config().baseUrl}/assets/images/imageName.jpg`) });
})

1
同意,参见 https://github.com/cypress-io/cypress/issues/7651 - Eric Burel
如果你忽略返回值,使用.map似乎不太合适。如果你只是想在每个元素上触发副作用而不是对数组的每个元素进行不可变的转换,那么使用.forEach会更好。 - undefined

23
cy.get('[data-e2e="create-entity-field-relation-contact-name"]').should('not.exist');
可能会导致一些错误信息被隐藏,可能会导致一些错误结果。最好使用。
.should('not.visible');

在那种情况下。


2
如果DOM中不存在,那么not.visible会起作用吗?我会试一下。谢谢!!! - Maccurt
5
对我来说情况恰好相反!(should('not.exist') 修正了错误的 should('not.be.visible')) - Paul Melero
如果在DOM中不存在该元素,则 not.be.visible 将起作用。如果检查 Cypress 日志,您将得到类似于“expected undefined to not be visible”的内容,然后断言将通过。因此,在某种程度上,not be visible 实际上涵盖了不存在和不可见的断言。 - Shiva Srinivasan
2
不要使用should('not.visible')断言。在Cypress < 6.0中,它会错误地通过,但现在对于从DOM中删除的元素会正确地失败。请使用should('not.exist')。请参见我的答案:https://dev59.com/0VUM5IYBdhLWcg3wY_a2#64983253 - t_dom93

7
以下是我使用的方法:

以下是我使用的方法:

cy.get('[data-cy=parent]').should('not.have.descendants', 'img')

我查看了一些 <div data-cy="parent">,发现其中没有图片。 关于原问题,您可以在内部节点上设置 data-cy="某些内容, 如子节点" 属性,并使用以下断言:

cy.get('[data-cy=parent]').should('not.have.descendants', '[data-cy=child]')

5
你可以使用getcontains结合起来,以区分HTML元素。
<button type='button'>Text 1</button>
<button type='button'>Text 2</button>

假设您有2个带不同文本的按钮,并且您想要检查第一个按钮是否不存在,则可以使用以下代码:
cy.get('button').contains('Text 1').should('not.exist')

6
这个方法在你的情况下可行,但如果按钮不存在,"get" 操作会失败,因为 Cypress 无法在 DOM 中找到该按钮。 - chadyred

1

Cypress中没有try-catch流程

在Java-Selenium中,我们通常添加NoSuchElementException并进行测试用例。如果UI在某些基于角色的访问情况下未显示元素。


1

您还可以在内或元素的父容器内查询匹配的元素,然后对其长度进行一些断言:

cy.get("body").find(".check-box-sub-text").should("have.length", 0);

1

也可以使用cypress中的jQuery模式进行操作:

assert(Cypress.$('.check-box-sub-text').length==0)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接