如何等待元素在柏树中消失?

Posted

技术标签:

【中文标题】如何等待元素在柏树中消失?【英文标题】:How to wait for element to disappear in cypress? 【发布时间】:2019-05-09 09:19:42 【问题描述】:

我有一个加载指示器,我需要等待它消失,然后再进行断言。

我已经看到一些使用以下内容,但它似乎对我不起作用,而且我不希望它成为一个断言。 cy.get('element, timeout: 10000).should('not.exist);

有人有什么建议吗?

【问题讨论】:

为什么不想使用断言?每次我需要等待一个元素消失时,我都会使用.should("not.be.visible"),它工作得很好。另外,请让我们知道您所说的“它似乎对我不起作用”是什么意思 - 有错误吗?暂停?发布输出。 当你的加载指示器完成后,DOM 是否会发生变化?加载指示器完成后,是否会将内容添加到 DOM 中? 这是您的实际代码吗?该代码会引发语法错误,因为它在 elementnot.exist 之后缺少单引号。 【参考方案1】:

如果您特别需要等待,可以在断言前使用cypress的wait()函数,并提供超时前等待的时间。

但请注意,这是一种反模式,您可以在文档中找到:

您几乎不需要等待任意时间。在 Cypress 中总是有更好的方式来表达这一点。

也就是说,如果您的加载指示器绑定到某个网络请求,您可以等待它们完成后再进行断言。这可以通过this 示例来实现:

// Wait for the route aliased as 'getAccount' to respond
// without changing or stubbing its response
cy.server()
cy.route('/accounts/*').as('getAccount')
cy.visit('/accounts/123')
cy.wait('@getAccount').then((xhr) => 
  // we can now access the low level xhr
  // that contains the request body,
  // response body, status, etc
)

更多关于等待请求的信息可以在here找到。

另外,请确保您确实要使用 .should('not.exist') 而不是 .should('not.be.visible')

【讨论】:

那么你如何等待动画完成? @EgorPavlikhin 请参阅赛普拉斯文档的this 部分。 加载指示器绑定到网络请求,但有时会发出多个请求,并且当我们使用 graphQL 时,所有请求看起来都一样。我只对最后一个感兴趣,因为这是应用程序关心的唯一请求。 你对cy.route(..)中的模式匹配url有什么建议吗?我似乎很难匹配我想等待的 url。 @TD1 在后台赛普拉斯使用 minimatch 来匹配 url 的 glob 模式。你可以测试一下here。【参考方案2】:

恕我直言,最干净的方法是不要在 get 中使用等待或超时,这有点反模式。

我建议使用Cypress waitUntil 命令并使用类似的东西:

 cy.waitUntil(function() 
  return cy.get('element').should('not.exist');
 )

或者根据应用代码,您可以使用not.be.visible

【讨论】:

来自 cypress-wait-until#readme The most common case is checking that an element exists or not, instead of using cy.get('#id').should('exist') you should check that Cypress.$('#id').length is greater than 0 这不会返回真实值,因此 waitUntil 永远不会退出【参考方案3】:

加载微调器实现通常只是隐藏元素而不是从 DOM 中删除它。因此,should("not.exist") 对他们不起作用。

cy.get("element").should("not.be.visible") 在这种情况下是正确的方法(正如Diogo's answer 已经暗示的那样)。

【讨论】:

有没有办法延长等待时间?否则,我将相应地设置 cy.interceptcy.wait 调用以等待底层网络请求。 @JohnnyFun 你可以传入等待时间 tp cy.get()。例如:cy.get("element", timeout: timeToWait )【参考方案4】:

cypress-wait-until 对我不起作用。我只是用了基本的:

cy.get('.ant-drawer-body').should('not.exist');

它会自动等待。

【讨论】:

【参考方案5】:

.findByTestId('loading-spinner-data-testid').should('not.be.visible')

这对我来说适用于类似的环境。

截至"@testing-library/cypress": "^5.3.1",

只要确保你给你的微调器组件一个 data-testid 属性。

<LoadingSpinner data-testid='loading-spinner-data-testid'>

【讨论】:

【参考方案6】:

Diogo Rocha 的方法在很多情况下都很重要,但要确定图像已经消失,您需要遵循 Philzen 的建议。断言它不可见,测试播放将等待它消失。

当您计划截取屏幕截图或视觉快照时,这一点尤其重要,因为 XHR 请求返回并不一定意味着图像已消失。

【讨论】:

【参考方案7】:

像这样使用cypress-wait-until:

cypress/support/commands.js:

import 'cypress-wait-until'

test.spec.js:

cy.waitUntil(() => cy.get('element').then($el => $el.length === 0))

【讨论】:

以上是关于如何等待元素在柏树中消失?的主要内容,如果未能解决你的问题,请参考以下文章

如何在柏树中获取条纹元素

如何在柏树的选择元素内选择第n个项目

在柏树中,我如何等待页面加载?

如何用柏树检查体内是不是存在元素?

python selenium中等待元素出现及等待元素消失操作

我如何等待在柏树中设置值?