cypress: cy.route() unable to mock same url multiple times if requests happen quickly

Current behavior:

If you make multiple requests to the same endpoint and want to mock each response differently based on the order that they occur, cypress appears to be unable to do it unless you wait X milliseconds between requests. If there is no pause between requests, cypress will never catch the first cy.wait(...) and will mock every request to that endpoint with the same response.

Desired behavior:

cy.server()
cy.route(url, res1).as(get)
cy.wait(@get)
cy.route(url, res2).as(get)

Should result in the first GET request to url responding with res1 and the second GET request to url responding with res2, regardless of the amount of time between requests.

Steps to reproduce: (app code and test code)

Run tests here

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 171
  • Comments: 67 (8 by maintainers)

Most upvoted comments

@ folks who have the same issue, please don’t forget to 👍 the OP. It’s easier to see how many people are interested in this by seeing the 👍 number. It’s also pretty difficult to read the comment discussion if all we see is rounds and rounds of “me too” “me too”.

Same. Need a way to specify the response of the Nth request.

@jennifer-shehane any followup on this? Mocking GraphQL calls is near impossible without this.

Any progress on this issue? This is kind-of a big deal.

It would be a non-breaking change to introduce a new cy-route-like API such as cy.listen(...) and cy.unlisten(...) that has the ability to:

  1. Match the most-recent route rather than the first one
  2. Provide an API to clear/remove/flush pending listeners on the route.

i have same shit ;/

Should be possible to discrimate request with body’s content?

This works for me:

cy.route('POST', '**/app/globalSearch', 'fixture:globalSearchErr.json').as('error')
    cy.get('#searchInput')
    .type('1234567890 {enter}')
    .wait(['@error'])

cy.route('POST', '**/app/globalSearch', 'fixture:globalSearch.json').as('success')
cy.get('#searchInput')
    .type('1762336105094 {enter}')
    cy.wait(['@success'])

also experiencing this issue, are there any updates?

I would like to see the resolution of this issue https://github.com/cypress-io/cypress/issues/9302, so that afterwards hopefully this can be resolved by using the new cy.intercept().

@jennifer-shehane any updates on this one?

any news?

@lifeiscontent one way to solve this using Apollo is to change your URL to include the queryname as a param. It allowed me to track requests in Cypress like

cy.route('POST', '**?q=getThing**)

I used the suggestions in this thread to write a blog post with something I hope is reusable across projects. Please take a look:

https://medium.com/life-at-paperless/cypress-graphql-response-mocking-7d49517f7754

Following this issue.

let useDefaultFixture = true;

describe('Use multiple fixture with single intercept', function () {
    beforeEach(() => {
        cy.intercept('GET', 'api/endpoint*', req => {
            if (useDefaultFixture) {
                req.reply(res => {
                    res.send({ fixture: 'defaultFixture.json' })
                })
            } else {
                req.reply(res => {
                    res.send({ fixture: 'secondFixture.json' })
                })
            }
        }).as('getSomething')
        cy.visit('/')
    })

    it('using defaultFixture', () => {
        // Uses defaultFixture.json when fetching api/endpoint*
    })

    it('needs secondFixture', () => {
        useDefaultFixture = false;
        // Using secondFixture.json when fetching api/endpoint*
    })

This works for me:

cy.route('POST', '**/app/globalSearch', 'fixture:globalSearchErr.json').as('error')
    cy.get('#searchInput')
    .type('1234567890 {enter}')
    .wait(['@error'])

cy.route('POST', '**/app/globalSearch', 'fixture:globalSearch.json').as('success')
cy.get('#searchInput')
    .type('1762336105094 {enter}')
    cy.wait(['@success'])

U saved my life!! It worked for me too

Ran into this problem as well. Need to be able to mock Nth request per route. Can we expect to see a solution in the foreseeable future?

I’ve run into the same issue and have created a command that supports 2 different methods which should be a good jumping off point for those that need it.

  • route('POST', url, requestBody => requestBody.property1 == 'something', 'some response')
  • route('POST', url, ...rand(1, 1000)) // some sort of counter endpoint and here is a link with install instructions. https://bitbucket.org/snippets/matt-tasc/onraxo If you improve it feel free to email me matt.meisberger@tasconline.com

Jup. Also have this issue. Have a polling service I’m trying to test. Want it to poll a few times, then change the response, and then it should trigger a call to a new endpoint. Doesn’t matter what I do, it just returns the original response.

Apollo/GraphQL user here too 👋. I was really surprised this didn’t work, because based on the documenation, it should… https://docs.cypress.io/api/commands/wait.html#Wait-automatically-increments-responses

But in the documentation it’s actually make new requests, it’s not making multiple XHR calls on page load.