kenwilde
kenwilde

Reputation: 123

Cypress cy.request .then chaining returning undefined

I'm upgrading Cypress from 10.2.0 to 10.11.0 and I'm encountering some behaviour I'm trying to understand.

In the second .then, the response is undefined. This had previously worked on 10.2.0.

public makeRequest(params) {
  return cy.request({
    ...params
    })
    .then((response) => {
       // do something with response
    });
}

this.makeRequest(params)
   .then((response) => {
     // response is undefined
    });

Can anyone point me in the right direction, I have checked the changelogs for every version since 10.3.0 and cannot find anything to explain this behaviour.

Thanks!

Upvotes: 1

Views: 575

Answers (2)

Fody
Fody

Reputation: 31924

Cypress (version 10.11.0 and previous versions) returns the last command result taken within the cy.request().then() chain, when there is no explicit return value given.

For example, if // do some async tasks is a non-Cypress asynchronous query, the response is returned:

cy.visit('http://example.com');

function makeRequest(params) {
  return cy.request(params)
    .then((response) => {

      // do some async tasks
      setTimeout(() => {
        console.log(response.title)
        expect(response.body.title).to.eq('delectus aut autem')       // passes
      }, 1000)
    })
}

makeRequest({url: 'https://jsonplaceholder.typicode.com/todos/1'})
  .then(response => {
    expect(response.body.title).to.eq('delectus aut autem')           // passes
  })

If however you issue more Cypress commands inside the // do some async tasks block, the last chained "subject" changes, and you get a different return value

cy.visit('http://example.com');

function makeRequest(params) {
  return cy.request(params)
    .then((response) => {

      // do some async tasks
      cy.get('h1')               // changes "subject" from response to <h1> element 
    })
}

makeRequest({url: 'https://jsonplaceholder.typicode.com/todos/1'})
  .then(response => {
    console.log(response)  // not your response, but the last "subject" found above

    expect(response.text()).to.eq('Example Domain')                   // passes
  })

Upvotes: 2

kenwilde
kenwilde

Reputation: 123

Adding a return returns the response

public makeRequest(params) {
  return cy.request({
    ...params
    })
    .then((response) => {
       // do something with response
       return response;
    });
}

If you are doing some async tasks in makeRequest.then(), do your async tasks and return response in another .then. E.g:

public makeRequest(params) {
  return cy.request({
    ...params
    })
    .then((response) => {
       // do some async tasks
    })
    .then((response) => {
      return response;
    });
}

Upvotes: 1

Related Questions