保持残存的响应,直到柏树断言成功,避免响应延迟

时间:2019-09-03 17:18:06

标签: cypress

我想测试“等待服务器回复” UI行为。我如何可靠地做到而不会因硬编码延迟而暂停测试

说,我有一个按钮,该按钮会触发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,则存在创建不稳定测试的风险,因为在我检查是否存在“等待...”文本之前,有可能会处理响应,届时该内容将被删除。

是否有一种方法可以确保仅在检查“等待...”文本之后才产生响应,而不会造成严重的延迟?

我很天真的尝试从路由的onResponse进行柏树断言,但是柏木对此并不满意:

  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.

3 个答案:

答案 0 :(得分:0)

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

我认为Bredan's answer是做到这一点的最佳解决方案。你可以

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

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

我对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);
  })

答案 1 :(得分:0)

这行得通吗?

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

cy.wait('getResponse')

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

答案 2 :(得分:0)

您可以使用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))