cypresscypress-custom-commands

How to return HTTP response body from Cypress custom command?


I am trying to write a custom Cypress command that sends a POST request to an endpoint, & I then want to store the response body in my test.

Here is what the response body looks like in Postman:

enter image description here

Here is my custom command in cypress/support/commands.js, for simplicity, I've removed the request body values:

Cypress.Commands.add('createStudent', (email) => {
    cy.request({
        method: `POST`,
        url: `myUrl`,
        body: {}
      }).then((resp) => {
        return resp
      });
});

Here is the code in my spec file:

let response = cy.createStudent(email);
cy.log(response)

However, when I run the code I get back the below object rather than the response body:

enter image description here

Can someone please tell me where I am going wrong, & what changes are required to return the actual HTTP response body?


Solution

  • If you look at the console message, there's a type $Chainer shown which is a wrapper object around the result you actually want (response).

    The Chainer is fundamental to Cypress being able to retry queries that fail initially but may succeed within a timeout period (usually 4 seconds).

    But it means you can't use the return value. Instead you need to "unwrap" the value using .then().

    Cypress.Commands.add('createStudent', (email) => {
      cy.request({
        method: 'POST',
        url: 'myUrl',
        body: {...}
      })
      // The response is put on the "chain" upon exit of the custom command
      // You need nothing else here to get the raw response
    })
    
    cy.createStudent().then(response => {
      cy.log(response)
    });
    

    You can add a step to extract details from the response, like

    Cypress.Commands.add('createStudent', (email) => {
      cy.request({
        method: 'POST',
        url: 'myUrl',
        body: {...}
      })
      .then(response => {
        expect(response.success).to.eq(true)   // check expected response is good
        return response.body.id                // pass on just the id
      })
    })
    
    cy.createStudent().then(id => {
      cy.log(id)
    });