How to Handle Loading State in Cypress Tests
cy.get() with should('not.exist') or cy.intercept() with cy.wait(). This ensures tests run only after loading completes, preventing flaky failures.Why This Happens
When a page or component is loading data, Cypress may try to interact with elements before they are ready. This causes tests to fail because the elements are not visible or enabled yet.
Commonly, tests fail because they do not wait for the loading spinner or loading indicator to disappear before continuing.
cy.get('#submit-button').click(); cy.get('#result').should('contain', 'Success');
The Fix
Wait explicitly for the loading state to finish before interacting with elements. You can wait for the loading spinner to disappear or wait for a network request to complete.
This makes sure Cypress only continues when the page is ready.
cy.intercept('GET', '/api/data').as('getData'); cy.visit('/page'); cy.wait('@getData'); cy.get('#loading-spinner').should('not.exist'); cy.get('#submit-button').click(); cy.get('#result').should('contain', 'Success');
Prevention
Always identify loading indicators or network calls that signal when data is ready. Use cy.get() with should('not.exist') or cy.intercept() with cy.wait() to wait for these.
Use clear and stable selectors for loading elements. Avoid arbitrary cy.wait() with fixed times as it makes tests flaky and slow.
Write tests that reflect real user behavior by waiting for UI readiness.
Related Errors
Similar errors include:
- Element not found: Happens when tests run before elements appear.
- Timed out retrying: Occurs if Cypress waits but the loading never ends due to app bugs.
- Detached DOM element: When elements change during loading and Cypress loses reference.
Fixes involve waiting properly and ensuring stable selectors.
Key Takeaways
cy.intercept() and cy.wait() to wait for network requests.