Cypress fixtures - Cannot read properties of undefined (reading 'data')

Viewed 6265

I'm trying to use fixtures to hold data for different tests, specifically user credentials. This is an example of the code. When it gets to the second test I'm getting 'Cannot read properties of undefined (reading 'data')'.

Any ideas why and how I can get around that? Is that wrong?

before(function () {
    cy.fixture('credentials').then(function (data) {
        this.data = data;
    })
})

    it('Login correct', () => {
        cy.visit('/')
        loginPage.signIn(this.data.admin.username,this.data.admin.password)
        cy.wait(5000)
        // assertion
        cy.contains('Dashboard').should('be.visible')
    })

And here is my credentials.json file:

{
  "admin": {
    "username": "*****",
    "password": "*****"
  }
}
3 Answers

As per the cypress docs:

If you store and access the fixture data using this test context object, make sure to use function () { ... } callbacks. Otherwise, the test engine will NOT have this pointing at the test context.

So, your it block should also use function:

before(function () {
  cy.fixture('credentials').then(function (data) {
    this.data = data
  })
})

it('Login correct', function () {
  cy.visit('/')
  loginPage.signIn(this.data.admin.username, this.data.admin.password)
  cy.wait(5000)
  // assertion
  cy.contains('Dashboard').should('be.visible')
})

I prefer using closure variables to assign fixture data.

describe('Some Test', () => {
  let data;
  before(() => {
    cy.fixture('credentials').then((fData) => {
        data = fData;
    });
  });

    it('Login correct', () => {
        cy.visit('/')
        loginPage.signIn(data.admin.username, data.admin.password)
        cy.wait(5000)
        // assertion
        cy.contains('Dashboard').should('be.visible')
    })
});

Gleb Bahmutov also recommends using closure variables.

I strongly recommend using closure variables instead of this properties. The closure variables are clearly visible and do not depend on function vs () => {} syntax.

The above answes are correct. One more way to do the above operation is use cypress.json instead other json files.

In your cypress.json u can add the credentials :

{
  "Env": {
    "username": "*****",
    "password": "*****"
  }
}

and refere json directy in your it fucntion.

it('Login correct', function () {
  cy.visit('/')
  loginPage.signIn(Cypress.env('username'), Cypress.env('password'))
  cy.wait(5000)
  // assertion
  cy.contains('Dashboard').should('be.visible')
})
Related