guberland
guberland

Reputation: 55

JS Cypress: unable to use alias for array

I am quite new to Cypress and I have some before() calling commands that create bunch of things via API calls and return the IDs of created which I use in the after() for removing them, but somehow it works perfectly if I only return one ID and store in the alias but will fail if I store an array of IDs in alias, is this intended or I did something wrong.

in my code:

before(() => {
  cy.setupEnv()
    .as('access_token')
    .then((token) => cy.setupFlow(token).as('data_id'))
})

after(function () {
  console.log(this.access_token)
  console.log(this.data_id)
})

console.log(this.data_id) shows fine if setupFlow returns only one ID but becomes undefined if I try to return [id1,id2,id3]and store the array using .as("data_id")

Upvotes: 1

Views: 896

Answers (2)

Fody
Fody

Reputation: 32148

You've struck a strange issue, worth raising with Cypress.

It only seems to happen if you have more than one test.

For example, if I run the following it logs the array.

before(() => {
  cy.wrap(1).as('access_token')
  cy.then(() => {
    return [1,2,3]
  }).as('data_id')
})

after(function () {
  console.log(this.access_token)            // 1
  console.log(this.data_id)                 // [1,2,3]
})

it('test1', () => {
  console.log('test1')
  expect(true).to.eq(true)
})

If I add a test it logs undefined!


before(() => {
  cy.wrap(1).as('access_token')
  cy.then(() => {
    return [1,2,3]
  }).as('data_id')
})

after(function () {
  console.log(this.access_token)            // 1
  console.log(this.data_id)                 // undefined
})

it('test1', () => {
  console.log('test1')
  expect(true).to.eq(true)
})

it('test2', () => {
  console.log('test2')
  expect(true).to.eq(true)
})

One way around this is to use Cypress.env() instead


before(() => {
  cy.wrap(1).as('access_token')
  cy.then(() => {
    Cypress.env('data_id', [1,2,3])
    return [1,2,3]
  }).as('data_id')
  console.log('before')
})

after(function () {
  console.log(this.access_token)            // 1
  console.log(this.data_id)                 // undefined
  console.log(Cypress.env('data_id'))       // [1,2,3]
})

beforeEach(function() {
  console.log(cy.state())
  console.log(this.data_id)
  cy.wrap(this.data_id).as('data_id')
})

it('test1', () => {
  expect(true).to.eq(true)
  console.log('test1')
})

it('test2', () => {
  console.log('test2')
  expect(true).to.eq(true)
})

Upvotes: 1

Alapan Das
Alapan Das

Reputation: 18586

Assuming that cy.setupFlow(token) generates an array of values something like [id1, id2, id3]. This will work even when there is one value in the array. You after each should look this:

after(function () {
  cy.get('@data_id').then((data_id) => {
    //Get individual values
    cy.log(data_id[0])
    cy.log(data_id[1])
    cy.log(data_id[2])

    //Get all values using forEach
    data_id.forEach((id) => {
      cy.log(id) //get all values one by one
    })
  })
})

I created a small POC for this and it is working as expected.Below are the results.

Code:

describe('SO Ques', () => {
  before(function () {
    cy.wrap([1, 2, 3]).as('array')
  })

  it('SO Ques', function () {
    cy.log('Hello')
  })

  after(function () {
    cy.get('@array').then((array) => {
      cy.log(array[0])
      cy.log(array[1])
      cy.log(array[2])
    })
  })
})

Result:

Test Runner screenshot

Upvotes: 0

Related Questions