Cypress: Return conditional data based an XHR's request details

Created on 30 Jun 2016  路  5Comments  路  Source: cypress-io/cypress

Often a server will respond conditionally to a request based on information in the POST data. Would be helpful to be able to do this using cy.route() - currently if a function is passed in it is called immediately, not at the point of requesting.

Most helpful comment

While the xhr object passed to the response function includes method and url of the request, it seems to be missing the request body.

Example desired usage:

let users = { 1: { id: 1, name: 'Foo', usesCypress: true } };
cy.route('GET', '/users/1', users[1]);

cy.route('PATCH', '/users/1', ({ request: { body } }) => {
  return { ...users[1], ...body };
});

// App code calls `patch('/users/1', { name: 'Bar' })` and expects
// to get back `{ id: 1, name: 'Bar', usesCypress: true }`

The above would mirror the data that gets passed to a then handler on cy.wait('@someStubbedRoute').

I am hard-coding in the responses in my tests today, but this would be useful for creating generic reusable routes.

All 5 comments

@sarahgracesmith can you give me a little code snippet of what you would like to see ideally here?

for example, the following commentsResponse would check the request variables and dynamically return different results. Similar to how a server might behave. This would allow returning different results for the same route in a single test even if there's no logical point to re-route() in the test.

const commentsResponse = (routeData) => {
  //routeData is a reference to the current route's information
  if ( ... request contains some field ... )
    return {
      data: foo
    }
  } else {
    return {
      data: bar
    }
  }
}

cy.route('POST', '/comments/**', commentsResponse)

馃憤 I have this test passing

it('returns data based on response', () => {
    let req
    cy
      .route({
        url: '/users?_limit=3',
        response: r => {
          req = r
          return [1, 2, 3]
        },
        headers: {
          'access-control-allow-origin': '*'
        }
      })
      .as('users')
    cy.visit('has-fetch.html')
    cy.wait('@users').then(() => {
      expect(req).to.deep.equal({
        method: 'GET',
        url: '/users?_limit=3'
      })
    })
  })

which confirms the right logic

While the xhr object passed to the response function includes method and url of the request, it seems to be missing the request body.

Example desired usage:

let users = { 1: { id: 1, name: 'Foo', usesCypress: true } };
cy.route('GET', '/users/1', users[1]);

cy.route('PATCH', '/users/1', ({ request: { body } }) => {
  return { ...users[1], ...body };
});

// App code calls `patch('/users/1', { name: 'Bar' })` and expects
// to get back `{ id: 1, name: 'Bar', usesCypress: true }`

The above would mirror the data that gets passed to a then handler on cy.wait('@someStubbedRoute').

I am hard-coding in the responses in my tests today, but this would be useful for creating generic reusable routes.

Was this page helpful?
0 / 5 - 0 ratings