typescriptvuejs3cypresse2e-testingcypress-intercept

Error when using nested cy.intercept in Cypress to mock request data


I'm trying to mock the response data in my Cypress test. Specifically, I want to remove an item from the fixture when a POST request is made to delete it. After filtering out the item, I want to intercept a subsequent GET request to load the updated data. However, I encounter an error when trying to use cy.intercept inside another cy.intercept.

Cypress error:

Cypress detected that you returned a promise from a command while also invoking one or more cy commands in that promise.

Here's my code:

// Remove an item from fixture
cy.fixture('items').then((items: any[]) => {
  // Intercept the POST request to delete an item from the fixture
  cy.intercept('POST', '**/delete', (request) => {
    const itemId = request.body.itemId;

    // Filter the items by removing the one that matches the request
    const filteredItems = items.filter(item => item.id !== itemId);

    // Here I get an error because I'm using intercept inside intercept
    cy.intercept('GET', '**/loadData**', filteredItems).as('loadDataRequest');
  }).as('delete');
});

How can I modify the test to intercept both the POST request and the subsequent GET request with the updated fixture data?


Solution

  • The routerHandler (the intercept callback (req) => ...) fires out of sync with the test flow, so Cypress checks for commands added inside this function.

    Since you have aliased the POST, you can wait on that alias and set the second intercept inside it's callback.

    To check if it's feasible, I ran a similar test using a public API. The fist call receives data with id 1, and this is used as a mock for the second call to endpoint normally returning data with id 2.

    let dataFromFirstIntercept;
    
    cy.intercept('https://jsonplaceholder.typicode.com/todos/1').as('first')
    
    // Simulate the app firing the first API call
    cy.window().then(win => {
      win.fetch('https://jsonplaceholder.typicode.com/todos/1')
    })
    
    cy.wait('@first').then(({request, response}) => {
      dataFromFirstIntercept = response.body
      cy.intercept('https://jsonplaceholder.typicode.com/todos/2', dataFromFirstIntercept).as('second')
    })
    
    // Simulate app firing 2nd API call to different endpoint 
    cy.window().then(win => {
      win.fetch('https://jsonplaceholder.typicode.com/todos/2')
    })
    
    cy.wait('@second').then(({request, response}) => {
      expect(response.body).to.deep.eq(dataFromFirstIntercept)
    })
    

    The final assertion confirms the mocked data is used correctly in the second API call.

    enter image description here