Michael Lynch
Michael Lynch

Reputation: 3149

How can I use cookies across multiple Cypress tests?

I am using cypress to test my Register and Login forms. I want to set cookies in my register.js test and then make use of them in my login.js test.

I preserve the cookies in cypress/support/index.js:

Cypress.Cookies.defaults({
  preserve: ['test_email', 'test_password'],
});

My register.js test looks like this:

describe('Create new account', () => {
  it('Visit Register', () => {
    cy.visit(Cypress.env('URL_REGISTER'));

    cy.setCookie('test_email', '[email protected]');
    cy.setCookie('test_password', 'abc123');
  });

  it('Fill out register form', async () => {
    const email = await cy.getCookie('test_email');
    const password = await cy.getCookie('test_password');

    cy.get('[data-cy="register-email"]').type(email.value);
    cy.get('[data-cy="register-password"]').type(password.value);
  });
});

When I run this test, I get this error:

Cannot read property 'value' of undefined

I understand that cy.getCookie() returns an object and is async, which is why I'm trying to use await, but for some reason, this doesn't seem to be working. How can I set and get cookies across multiple cypress tests?

Upvotes: 0

Views: 4342

Answers (1)

Eddy Gilmour
Eddy Gilmour

Reputation: 3140

Preserve cookies between tests with Cypress.preserveOnce(), or in beforeEach() preserves for all tests.

beforeEach(() => {
  Cypress.Cookies.preserveOnce('test_email')
})

it('set cookie', async () => {
  cy.setCookie('test_email', '[email protected]')
})

it('once', async () => {
  const email = await cy.getCookie('test_email')
  expect(email).to.have.property('value', '[email protected]')  // passes
})

it('twice', async () => {
  const email = await cy.getCookie('test_email')
  expect(email).to.have.property('value', '[email protected]')  // passes
})

it('thrice', async () => {
  const email = await cy.getCookie('test_email')
  expect(email).to.have.property('value', '[email protected]')  // passes
})

You should stick with the documented way of using getCookie.

If I run

const email = await cy.getCookie(...)

after a cy.visit(), I get undefined.

If I use

cy.getCookie(...).then(...) 

on the next line it gets the value.

Since Cypress has not documented the await syntax anywhere, you are likely to get some flaky results.

Standard pattern is:

it('once', () => {
  cy.getCookie('test_email').then(email => {
    expect(email).to.have.property('value', '[email protected]')  // passes
  })
})

If you run tests in CI they may be run parallel, so better to setCookie in before() or beforeEach().

before(() => {
  cy.setCookie('test_email', '[email protected]')
})

beforeEach(() => {
  Cypress.Cookies.preserveOnce('test_email')
})

it('uses cookie once', () => {
  ...
})

it('uses cookie twice', () => {
  ...
})

it('uses cookie thrice', () => {
  ...
})

Upvotes: 3

Related Questions