Search code examples
cypresse2e-testingcypress-intercept

How to make cypress wait for a response that depends on another response?


From response A (/list.json) my app receives a list of items. Based on the output of A, my app makes another set of requests B for individual items (/one.txt, /two.txt, ...).

Now in my test I want to make sure that all responses B return HTTP 200.

Waiting (cy.wait) for response A is fine. However, waiting for responses B is more difficult, because I have to start waiting just upon receiving response A where I learn about responses B.

I tried 2 options:

  1. start waiting inside of cy.wait of response A - code,
  2. start waiting outside of cy.wait of response A - code

Neither of those work. With option 1 I get

`cy.wait()` timed out waiting `5000ms` for the 1st request to the route: `one.txt`. No request ever occurred

And with option 2 I get a pass, even though /two.txt doesn't exist. Looks like cy.wait for responses B is added after the responses were received


Solution

  • Since all requests are triggered off the visit, and are dynamic, you need a single intercept that handles all requests.

    To me that means adding some javascript and dynamic aliases.

    
    // avoid status code 304, disable browser cache
    Cypress.automation('remote:debugger:protocol', {
      command: 'Network.clearBrowserCache'
    })
    
    
    describe('spec', () => {
      it('test', () => {
        let items = [];
        cy.intercept('GET', '*', (req) => {
    
          const slug = req.url.substring(req.url.lastIndexOf('/') + 1)
          if (slug === 'list.json') {
            req.alias = 'list'
          } 
          if (items.includes(slug)) {
            req.alias = 'item'
          }
    
          req.continue((res) => {
            if (slug === 'list.json')) {
              items = res.body;
            }  
          })
        })
    
        cy.visit('https://demo-cypress.netlify.app');  
    
        cy.wait('@list')                          // wait for list
          .then(() => {                           // now items is populated
            for (let item of items) {             // really just need the count
              cy.wait('@item').then(interception => {     // wait n-times
                expect(interception.response.statusCode).to.eq(200);
              })
            }
          })
      })
    })