How to return a plain object from a cypress api call?

Viewed 30

I use cypress for testing api calls. I have functions which make api calls and return a Chainable like this Cypress.Chainable<Cypress.Response<SomeClass>>. Here, SomeClass can be a custom class or simply object type. I want to create a function which will return a custom class instead of a Chainable. Is that possible in Cypress? How to do it?

function getCar(model) : Cypress.Chainable<Cypress.Response<<Car>>{
  return cy.request({
    method: "POST",
    url: "api url"
    body: {model}
    headers: the headers
  });
}

I'd like to return Car instead of the above return type, as shown below. How to do this in Cypress?

function getCar(model) : Car{
  //the code.
}
1 Answers

Once you have asynchronous code like cy.request() you can't easily get back to a synchronous value like the Car object.

The options are:

  • Use .then() after your function

    getCar(model).then(car => {
      ...
    })
    
  • Wrap the request in a Promise and await it

    function getCar(model) : Cypress.Chainable<Cypress.Response<<Car>>{
      return new Promise((resolve, reject) => {
        cy.request({
          method: "POST",
          url: "api url"
          body: {model}
          headers: the headers
        })
        .then(response => 
          const car = ... // extract car from response
          resolve(car)
        })
      })
    }
    
    it('gets Car', async () => {
      const car = await getCar(model)
    })
    
  • Use Mocha before or beforeEach blocks to set up a global (handles awaiting for you)

    let car;
    before(() => getCar(model).then(result => car = result))
    
    it('uses Car', () => {
      // use car variable (in scope)
    })
    

Other variations of the last include

  • using an alias (but these are cleared between tests)
  • setting a Cypress.env('car') variable (ugly syntax and fails if page resets).
Related