Cypress: Aliasing responses from cy.request

Created on 26 Mar 2019  路  1Comment  路  Source: cypress-io/cypress

Current behavior

From what I understand, as only works with cy.route.

Desired behavior

It'd be nice if as worked with cy.request as well. For instance, we have a frontend app that talks to a backend app, and in our Cypress tests for the frontend app we want a way to populate the backend app with data. If we have a lot of data that we need to populate, we need to make multiple requests to the backend. Using cy.request to do this is great, but if we need to reference some of the data that is created later on in the test, we can't do that without nesting:

cy.request("POST", "/create_test_data", {
  type: "user",
  name: "Bob"
})
  .then(({ body: user }) => {
    cy.request("POST", "/create_more_test_data", {
      type: "order",
      user_id: user.id
    }).then(({ body: order }) => {
      cy.get("[data-cy='sign_in']").click();
      cy.get("[data-cy='email']").type(user.email);
      // do something with order...
    });
  });

This is obviously a simple example but you can imagine creating more levels of test data here.

If we could do this instead then it might make things easier and potentially extractable:

cy.request("POST", "/create_test_data", {
  type: "user",
  name: "Bob"
})
  .as("@userResponse")
  .then((response1) => {
    const user = response1.body;
    cy.request("POST", "/create_more_test_data", {
      type: "order",
      user_id: user.id
    }).as("@orderResponse");
});

cy.wait("@userResponse").then(({ body: user }) => {
  cy.get("[data-cy='sign_in']").click();
  cy.get("[data-cy='email']").type(user.email);
  // perform the rest of the tests...
});

cy.wait("@orderResponse").then(({ body: order }) => {
  // do something with order...
});

Obviously, cy.request works differently than cy.route in that you can have successful and failed responses. In this case, I would want the alias to get assigned only on a successful response, although I can imagine other people wanting a failed response. I suspect this is why requests don't support aliases, so I see that that throws a wrench in things. But perhaps there could be a variant of as that would allow for this?

Most helpful comment

Using aliases with cy.request() is supported. Although, using cy.wait('@alias') does not work for request - since the cy.request() command itself will not resolve until it has a response.

Here is an example of this working with getting the alias via cy.get().

it('cy.request() - make an XHR request', () => {
  cy.visit('https://example.cypress.io/commands/network-requests')

  cy.request('https://jsonplaceholder.cypress.io/comments').as('comments')

  cy.get('@comments').should((response) => {
    expect(response.status).to.eq(200)
    expect(response.body).to.have.length(500)
    expect(response).to.have.property('headers')
    expect(response).to.have.property('duration')
  })
})

I created a new issue in our docs to document using an alias with cy.request() here: https://github.com/cypress-io/cypress-documentation/issues/1779. Our documentation is open source and contributions are welcome. 馃槃

You can also only write expectations if the response.status is 200 by adding an if statement.

it('cy.request() - make an XHR request', () => {
  cy.get('@comments').should((response) => {
    if (response.status === 200) {
      expect(response).to.have.property('duration')
    } else {
      // whatever you want to check here
    }
  })
})

I will close this issue as resolved. Please let us know if you feel this does not fully resolve your request by commenting.

>All comments

Using aliases with cy.request() is supported. Although, using cy.wait('@alias') does not work for request - since the cy.request() command itself will not resolve until it has a response.

Here is an example of this working with getting the alias via cy.get().

it('cy.request() - make an XHR request', () => {
  cy.visit('https://example.cypress.io/commands/network-requests')

  cy.request('https://jsonplaceholder.cypress.io/comments').as('comments')

  cy.get('@comments').should((response) => {
    expect(response.status).to.eq(200)
    expect(response.body).to.have.length(500)
    expect(response).to.have.property('headers')
    expect(response).to.have.property('duration')
  })
})

I created a new issue in our docs to document using an alias with cy.request() here: https://github.com/cypress-io/cypress-documentation/issues/1779. Our documentation is open source and contributions are welcome. 馃槃

You can also only write expectations if the response.status is 200 by adding an if statement.

it('cy.request() - make an XHR request', () => {
  cy.get('@comments').should((response) => {
    if (response.status === 200) {
      expect(response).to.have.property('duration')
    } else {
      // whatever you want to check here
    }
  })
})

I will close this issue as resolved. Please let us know if you feel this does not fully resolve your request by commenting.

Was this page helpful?
0 / 5 - 0 ratings