Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cypress wait for API after button click

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
}) 
like image 818
Geoff Avatar asked Jun 28 '19 15:06

Geoff


People also ask

How do you wait after clicking in Cypress?

Wait for API response Cypress works great with http requests. If you are waiting for some resources to be loaded in your app, you can intercept a request and then create an alias for it. That alias will then be used with . wait() command.

How do you make Cypress wait for some time?

To wait for a specific amount of time or resource to resolve, use the cy. wait() command.

What is the best way to wait and test the page in Cypress?

With cypress, cy. visit() can be used to wait for a page to load.

How do you check if a button is clickable in Cypress?

You can use the jquery enabled selector to check whether the button is enabled or not and based on that perform other actions.


2 Answers

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.

like image 188
Josh Pittman Avatar answered Sep 21 '22 00:09

Josh Pittman


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();
like image 20
Brendan Avatar answered Sep 20 '22 00:09

Brendan