8
votes

I've made a React app, which all works perfectly and I'm now writing some end to end tests using Cypress.

The React app all works on the same url, it's not got any routes, and api calls from inside the app are handled through button clicks.

The basis of the app is the end user selects some options, then presses filter to view some graphs that are dependant on the selected options.

cy.get('button').contains('Filter').click()

When the button is pressed in cypress, it runs the 3 api calls which return as expected, but looking over the cypress docs there is no easy way unless I use inline cy.wait(15000) which isn't ideal, as sometimes they return a lot faster, and sometimes they return slower, depending on the selected options.

Edit 1 I've tried using server and route:

cy.server({ method: 'GET' });
cy.route('/endpoint1*').as('one')
cy.route('/endpoint2*').as('two')
cy.route('/endpoint3*').as('three')
cy.get('button').contains('Filter').click()
cy.wait(['@one', '@two', '@three'], { responseTimeout: 15000 }) 

Which gives me the error:

CypressError: Timed out retrying: cy.wait() timed out waiting 5000ms for the 1st request to the route: 'one'. No request ever occurred.

After further investigation

Changing from responseTimeout to just timeout fixed the error.

cy.server({ method: 'GET' });
cy.route('/endpoint1*').as('one')
cy.route('/endpoint2*').as('two')
cy.route('/endpoint3*').as('three')
cy.get('button').contains('Filter').click()
cy.wait(['@one', '@two', '@three'], { timeout: 15000 }).then(xhr => {
  // Do what you want with the xhr object
}) 
3
Have you run tests without wait ? I think my tests passed because cypress take care of wait.N..
They just go to the next action with out the wait.Geoff
@BostonStar I thought this would be the solution when I was on it earlier, but it didn't work as I expected, it was timing out after 5000, maybe needs the timeout parameter like in the below answer. I'll try it again as this is the tidyer option really.Geoff
Anyone who is facing that it waits till the timeout, endpoint should be mentioned as /endpoint2** notice the two stars - docs.cypress.io/api/commands/route.html#Without-StubbingManu Viswam

3 Answers

8
votes

Sounds like you'll want to wait for the routes. Something like this:

cy.server();
cy.route('GET', '/api/route1').as('route1');
cy.route('GET', '/api/route2').as('route2');
cy.route('GET', '/api/route3').as('route3');

cy.get('button').contains('Filter').click();

// setting timeout because you mentioned it can take up to 15 seconds.
cy.wait(['@route1', '@route2', 'route3'], { responseTimeout: 15000 });

// This won't execute until all three API calls have returned
cy.get('#something').click();
6
votes

Rather than using a .wait you can use a timeout parameter. That way if it finished faster, you don't have to wait.

cy.get('button').contains('Filter', {timeout: 15000}).click()

This is mentioned as one of the options parameters in the official docs here.

0
votes

Try this:

    cy.contains('button', 'Save').click();
    cy.get('[data-ng-show="user.manage"]', { timeout: 10000 }).should('be.visible').then(() => {
      `cy.get('[data-ng-show="user.manage"]').click();
   })