Cypress env variable is undefined when it's called in different method

Viewed 25

In first method below I set env. variable, but when it's necessary to get this variable in another method, executed under the same test run, it's returned as undefined. What can be the cause of such behavior?

setEnvVar = () => {
    cy.get('tbody > tr').first().find('span').first().then(($span) => {
        Cypress.env('est-id', $span.text())
    })
}
fillParameters = () => {    
    cy.get('div[id=estimates_select]').find('input').type(Cypress.env('est-id'))
}
1 Answers

TLDR

Put the fillParameters() code inside a cy.then().

fillParameters = () => {
  cy.then(() => {
    cy.get('div[id=estimates_select]')
      .find('input')
      .type(Cypress.env('est-id'))
  })
}

Explanation

All Cypress commands run on a queue. When the test runner runs a test, the parameters for commands like .type() and .log() are set before the command queue starts running.

In your code, that means .type(Cypress.env('est-id')) evaluates env('est-id') before it is set in the preceding function setEnvVar().

The exception is commands added inside a callback such as

cy.then(() => {
  // commands added here defer parameter setting 
  // until this callback is executed in the queue
})

Using Cypress.env() to save values is a hack (IMO)

The .env() was designed to set values outside of the test (why it's called environment)

It's often used as a data store, but closure variables or aliases are better in the situation you describe.

Examples:

Closure variable

let est-id;

setEnvVar = () => {
  cy.get('tbody > tr').first().find('span').first()
    .then(($span) => est-id = $span.text() )
}

fillParameters = () => {
  cy.get('div[id=estimates_select]').find('input')
    .type(est-id)
}

Alias

setEnvVar = () => {
  cy.get('tbody > tr').first().find('span').first()
    .invoke('text').as('est-id')
}

fillParameters = () => {
  cy.get('@est-id').then(est-id => {
    cy.get('div[id=estimates_select]').find('input').type(est-id)
  })
}
Related