In Cypress tests, how do I retry a button click if an expected XHR request does not go out : waitUntil() with click XHR condition??

好久不见. 提交于 2021-01-28 07:43:51

问题


At a very high level, we click a button which commands a building-control point; turns a light on or off. The click is supposed to send a POST request to the server. The issue is sometimes, the button is clicked and the POST request does not go out. The button has no functionality to indicate if it has been clicked (minor enhancement) .

For the time being, I want to work around this using Cypress plug-in waitUntil() .

    // define routes
    cy.server();
    cy.route('POST', '\*\*/pointcommands').as('sendCommand');

    // setup checkFunction for cy.waitUntil()
    const waitForPost200 = () => cy.wait('@sendCommand', {timeout: 10000}).then(xhr => cy.wrap(xhr).its('status').should('eq', 200));

    // setup jQuery for cy.pipe()
    const click = $el => $el.click();

    // click the button
    cy.get('.marengo-ok')
      .should('be.visible')
      .pipe(click);
      // need to pass in a synchronous should() check so that the click is retried. How can we achieve this with waitUntil ?

    // wait until checkFunction waitForPost200() returns truthy
    cy.waitUntil( (): any => waitForPost200(), {
      timeout: 10000,
      interval: 1000,
      errorMsg: 'POST not sent `enter code here`within time limit'
    });

回答1:


As far as I know, there is no way to leverage the cy.wait('@sendCommand') command restoring the test in case of failure (in case the XHR call is not made).

The fastest solution that comes to my mind is the following:

let requestStarted = false; // will be set to true when the XHR request starts
cy.route({
  method: 'POST',
  url: '\*\*/pointcommands',
  onRequest: () => (requestStarted = true)
}).as('sendCommand');

cy.get(".marengo-ok").as("button");

cy.waitUntil(() =>
    cy
    .get("@button")
    .should('be.visible')
    .click()
    .then(() => requestStarted === true)
, {
  timeout: 10000,
  interval: 1000,
  errorMsg: 'POST not sent `enter code here`within time limit'
});

cy.wait("@sendCommand");

You can play with a repo I prepared for you where I simulate your situation. That's the end result of the test in my repo.

result screenshot

Let me know if you need more help 😊




回答2:


I think the underlying issue is that the test runner clicks on the button before an event listener gets attached. See the discussion in https://www.cypress.io/blog/2019/01/22/when-can-the-test-click/ My advice (aside from using waitUntil plugin), is to use https://github.com/NicholasBoll/cypress-pipe which provides cy.pipe and click the button using jQuery method

// cypress-pipe does not retry any Cypress commands
// so we need to click on the element using
// jQuery method "$el.click()" and not "cy.click()"
const click = $el => $el.click()

cy.get('.owl-dt-popup')
  .should('be.visible')
  .contains('.owl-dt-calendar-cell-content', dayRegex)
  .pipe(click)
  .should($el => {
    expect($el).to.not.be.visible
  })



来源:https://stackoverflow.com/questions/57695328/in-cypress-tests-how-do-i-retry-a-button-click-if-an-expected-xhr-request-does

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!