In my application, I have the following flow that I need to check in cypress:
- User goes to page
- The request needed to render the page is being sent.
- In the time between the request has been sent and the response has been received, the user should see a loading spinner. After the response has been received, the loading spinner should be removed.
The first thing I tried to test it is simple:
it('should display spinner during page load', () => {
cy.visit(myPageUrl);
cy.get(selectors.spinner).should('exist');
cy.get(selectors.spinner, { timeout: 5000 }).should('not.exist');
});
However, this creates a race condition. The page might load and the spinner will disappear before the cypress reaches the assertion of the existence of the spinner. Here's a visual explanation:
Here's what I expected: Expected result
And here's what might actually happen, which would cause the test to fail: Possible result
And so, after researching for a bit, I tried the following thing to solve the race condition:
it('should display spinner during page load', () => {
let sendResponse;
const trigger = new Promise((resolve) => {
sendResponse = resolve;
});
cy.intercept('GET', '/myRequiredPageData', (req) => {
return trigger.then(() => {
req.reply();
});
});
cy.visit(myPageUrl);
cy.get(selectors.spinner).should('exist').then(() => {
sendResponse();
cy.get(selectors.spinner, { timeout: 5000 }).should('not.exist');
});
});
However, now I sometimes get this error:
A request callback passed to cy.intercept() timed out after returning a Promise that took more than the defaultCommandTimeout of 4000ms to resolve.
I assume the cy.intercept is stuck in the cypress command queue for more than the defaultCommandTimeout
and that's why the test fails. Assuming I can't change the configuration key and the configuration of the test, I wonder what else I can do to check for the spinner and whether I am even in the right direction when it comes to best practices regarding loading spinners.