【问题标题】:Hold stubbed response till cypress assertion succeeds, avoid response delay保持 stubbed 响应直到 cypress 断言成功,避免响应延迟
【发布时间】:2019-09-09 20:25:38
【问题描述】:

我想测试我的“等待服务器回复”用户界面行为。如何可靠地做到这一点不会因硬编码延迟而暂停测试

比如说,我有一个触发 http 请求的按钮,并且必须显示某些动画/动作,直到响应到达。

一个愚蠢的工作方法是:

  cy.route({
     delay: 1000,
     response: "blah blah",
  })

  // triggger submission  
  cy.get('#my-submit-button').click()

  // will disappear upon receiving response
  cy.contains('Waiting for response...')

我很确定“等待”文本会在响应暂停时在一秒钟内出现,但随后我提交了the sin of pausing the test for a whole second

如果我开始缩短或删除delay,那么我将面临创建片状测试的风险,因为在我检查是否存在“等待...”文本之前,有可能会处理响应,这到那时就会被删除。

有没有办法确保只有在检查“Waiting...”文本之后才产生响应,而不会出现硬延迟?

我天真地尝试从路由的 onResponse 中进行 cypress 断言,但 cypress 对此并不满意:

  cy.route({
     onResponse: xfr => {
        cy.contains('Waiting for response...')
        return xfr
     },
     response: "blah blah",
  })

  cy.get('#my-submit-button').click()

产生https://on.cypress.io/returning-promise-and-commands-in-another-command 错误:

Error: Uncaught CypressError: Cypress detected that you returned a promise from a command while also invoking one or more cy commands in that promise.

The command that returned the promise was:

  > cy.click()

The cy command you invoked inside the promise was:

  > cy.contains()

Because Cypress commands are already promise-like, you don't need to wrap them or return your own promise.

Cypress will resolve your command with whatever the final Cypress command yields.

The reason this is an error instead of a warning is because Cypress internally queues commands serially whereas Promises execute as soon as they are invoked. Attempting to reconcile this would prevent Cypress from ever resolving.

【问题讨论】:

    标签: cypress


    【解决方案1】:

    这行得通吗?

    cy.route({
         delay: 1000,
         response: "blah blah",
      }).as('getResponse')
    
    cy.wait('getResponse')
    

    https://docs.cypress.io/guides/guides/network-requests.html#Waiting

    【讨论】:

    • 不,抱歉。我需要检查之前响应完成,而不是之后。
    【解决方案2】:

    您可以使用cy.moment() 记录这些事情发生的时间,然后使用.isBefore() 或其他时刻函数之一进行比较。

    我在这里使用onResponse来记录响应的到来时间。

      let timeDisappeared;
      let timeResponded;
    
      cy.route({
         delay: 1000,
         response: "blah blah",
         onResponse: () => {
           timeResponded = Cypress.moment()
         }
      })
    
      // triggger submission  
      cy.get('#my-submit-button').click()
    
      // waits for the text to appear
      cy.contains('Waiting for response...').should('exist')
    
      // waits for the text to disappear
      cy.contains('Waiting for response...').should('not.exist').then(() => {
        timeDisappeared = Cypress.moment()
      })
    
      expect(timeResponded.isBefore(timeDisappeared))
    

    【讨论】:

    • 谢谢,这是一种有用的技术,但不允许我放弃固定的delay
    【解决方案3】:

    看到您的评论并检查其他答案后

    我认为Bredan's answer 是最好的解决方案。你可以

    1. 存根响应延迟:x 秒
    2. 检查要显示的文本。记录时间:timeAppear
    3. 检查文本是否消失。记录时间:timeDisappear
    4. 检查 timeDisappear - timeAppear > x 秒
      • 或检查timeDisappear - timeAppear - x seconds > 某些秒(可以定义容差) 这证明了文本显示在给定的响应时间内。

    您可以将响应延迟扩展为更长的值。

    我稍微修改了 Bredan 的答案以反映上述步骤,

     let timeAppear;
     let timeDisappear;
    
     //delay the response to come back after 20 seconds 
      cy.route({
         delay: 20000,
         response: "blah blah"
      })
    
      // triggger submission  
      cy.get('#my-submit-button').click()
    
      // waits for the text to appear and record the time starts. 
    
      cy.contains('Waiting for response...').should('exist').then(() => {
        timeAppear = Cypress.moment()
      })
    
      // waits for the text to disappear and record the time ends
      // add timeouts option here to make sure it is longer than delay
      cy.contains('Waiting for response...',{timeout:30000}).should('not.exist').then(() => {
        timeDisappear = Cypress.moment();
        //check the time is above the delay time 2000 ms
        expect(timeDisappear - timeAppear).to.be.above(20000);
        //or check the tolerance value e.g.5000 ms
        expect(timeDisappear - timeAppear - 20000).to.be.below(5000);
      })
    
    

    【讨论】:

    • 谢谢,问题不在于等待“等待”内容出现,而是确保在收到响应之前它不会消失。我更新了问题以更好地反映这一点。
    • @MykolaGurov,我修改了我的答案有帮助吗?
    猜你喜欢
    • 1970-01-01
    • 2015-01-02
    • 1970-01-01
    • 2018-04-05
    • 1970-01-01
    • 2012-08-27
    • 1970-01-01
    • 2016-10-09
    • 1970-01-01
    相关资源
    最近更新 更多