如何检查在赛普拉斯 e2e 测试中元素是不是永远不可见?

Posted

技术标签:

【中文标题】如何检查在赛普拉斯 e2e 测试中元素是不是永远不可见?【英文标题】:How to check if element is never visible in Cypress e2e testing?如何检查在赛普拉斯 e2e 测试中元素是否永远不可见? 【发布时间】:2019-05-13 17:23:37 【问题描述】:

在赛普拉斯中路由时,有什么方法可以断言元素在任何时候都不可见?

我有一个服务器渲染的网络应用程序,有时它不应该显示“正在加载”状态。因此,当我在页面之间导航时,“加载”指示器会显示几秒钟然后消失。

我知道赛普拉斯的断言有时会“等待”——在这种情况下,赛普拉斯一直等到加载指示器消失,这使得测试认为它已经通过了。但我希望测试失败,因为加载指示器在某些时候是可见的

我正在使用这两个断言:

cy.get('[data-test="loading"]').should('not.exist');

cy.get('[data-test="loading"]').should('not.be.visible');

但是由于加载指示器消失了,它们都通过了。

我已经检查了所有文档,但似乎没有某种方法可以检查元素是否从不可见。是否有一些我遗漏的方法或一些黑客来测试这个不同的方式?

【问题讨论】:

你能添加某种 0 的等待,所以我不等待吗? 【参考方案1】:

Cypress 有一个精简版的 jQuery,所以我们可以观察不应该存在的元素的父元素的变化。

只要发生变化,就会应用@Maccurt 的测试。

您希望将手表触发保持在最低限度,因此请找到测试元素的直接(或最近)父级。

注意这涵盖了exists 测试,但如果元素一直存在但不可见,则visible 测试不应该是必需的。


在这个例子中,一个按钮被添加到body。 第一个测试监视span(从未添加,因此测试成功)。button 的第二次测试手表失败了。

describe('watching for an element to not appear', () => 

  const watchAndTest = function(parentSelector, assert) 
    Cypress.$(parentSelector).bind('DOMNodeInserted', function(event) 
      assert()
    );
  

  it('should succeed because "span" does not exist', () => 
    const parentSelector = 'body'
    const watchForSelector = 'span'
    watchAndTest(parentSelector, 
      () => 
        // Place your 'assert' code here
        cy.get(`$parentSelector $watchForSelector`, timeout: 0 )
          .should('not.exist');
      
    )

    // Place your 'act' code here
    cy.get(parentSelector).then(parent => 
      var newElement = document.createElement('button');
      parent[0].appendChild(newElement)
    )
    Cypress.$(parentSelector).unbind('DOMNodeInserted')
  )

  it('should fail because "button" exists', () => 
    const parentSelector = 'body'
    const watchForSelector = 'button'
    watchAndTest(parentSelector, 
      () => 
        // Place your 'assert' code here
        cy.get(`$parentSelector $watchForSelector`, timeout: 0 )
          .should('not.exist');
      
    )

    // Place your 'act' code here
    cy.get(parentSelector).then(parent => 
      var newElement = document.createElement('button');
      parent[0].appendChild(newElement)
    )
    Cypress.$(parentSelector).unbind('DOMNodeInserted')
  )

)

【讨论】:

感谢您发布此答案,我会看看。 这很漂亮,干得好!【参考方案2】:

我可能疯了,我还没有测试过这个,但我想把它扔出去

我假设您正在测试不应该有加载指示器,并且它正在等待默认的 4 秒并且指示器消失,因此您的测试通过。所以下面我将等待设置为零,所以它不等待。我也很困惑为什么你不修复实际代码,所以如果你不应该看到指示器,你就看不到。也许您无权访问代码..

cy.get('[data-test="loading"]', timeout: 0 ).should('not.exist');

cy.get('[data-test="loading"]', timeout: 0 ).should('not.be.visible');

【讨论】:

是的,超时工作完美,非常感谢!我也可以访问代码,但我基本上暂时使用加载指示器作为后备。它的工作方式是在服务器上呈现页面(我正在使用 React / Next.js)并显示一个完全加载的页面。 这只会测试元素在特定时刻是否可见。您的问题是在寻找一种“断言元素在任何时候都不可见”的方法。该元素可能在整个测试期间一直存在,直到您调用上述代码之前的一毫秒,测试就会通过。 @Brendan 你能提供一个替代方案吗,我愿意接受。我怀疑这是否是一件好事。我愿意学习.. @Maccurt 负面测试总是很棘手。显示加载状态时是否发送了 XHR 请求?如果是这样,您可以在测试结束时检查该路线。 docs.cypress.io/api/commands/route.html#Syntax

以上是关于如何检查在赛普拉斯 e2e 测试中元素是不是永远不可见?的主要内容,如果未能解决你的问题,请参考以下文章

如何在赛普拉斯 e2e 测试之前设置 NGRX 状态?

赛普拉斯:检查元素是不是存在无异常

如何使用赛普拉斯检查可能不存在的元素

赛普拉斯:测试元素是不是不存在

使用赛普拉斯,我将如何编写一个简单的测试来检查页面上是不是存在徽标图像

使用赛普拉斯的 e2e 测试中的身份验证错误:chrome-error://chromewebdata