Gunnar Finkeldeh
Gunnar Finkeldeh

Reputation: 1

Cypress not re-using cookies or session in headless mode

Disclaimer: I am fairly new to Cypress, so if this has been answered before, my apologies

Scenario: I have structured my tests to run in separate spec files to avoid one long spec file, as such I have an initial login spec and then each page we navigate through is a separate one (not sure if this is best practise) The user logs in and then is taken to another page from which they can make selections

Problem: The tests run fine using Cypress in headed mode, but when I run them in CLI (headless mode) the second spec fails. I know the reason for this is cause Cypress closes the browser and then opens it again. My cookies, or session is not saved or carries over because of this.

What I have tried: I have managed to get a code snippets from here that stores the cookies after each test, which works well in headed mode, but not in headless mode. I am running Cypress 9.7.0 which now says that Cookies.preserveOnce, is deprecated, and recommends using cy.session(). This is where I am struggling, cause there seems to be conflicting info. Cypress says to use it as part of the Login Command, but others are using it in a before or beforeEach hook. In addition the posts I read all focus on using cy.session() when there are multiple it sections, not multiple spec files. This has left me rather stuck, as I have tried those methods, but then my second test fails in headed mode.

Index.js

//Code to Handle the Sesssions in cypress.
//Keep the Session alive when you jump to another test
afterEach(() => {
  let str = [];
  cy.getCookies().then((cook) => {
    cy.log(cook);
    for (let l = 0; l < cook.length; l++) {
      if (cook.length > 0 && l == 0) {
        str[l] = cook[l].name;
        Cypress.Cookies.preserveOnce(str[l]);
      } else if (cook.length > 1 && l > 1) {
        str[l] = cook[l].name;
        Cypress.Cookies.preserveOnce(str[l]);
      }
    }
  })
})

Commands.js

//Login 
Cypress.Commands.add('login', (email, password) => {
  email = Cypress.env('email')
  password = Cypress.env('password')

  // cy.session([email, password], () => {
  cy.visit('/login')
  cy.get('[class="CookiesPopup"').contains('OK').click()
  cy.get('[name="user"]').type(email)
  cy.get('[name="password"]').type(password, {
    log: false
  })
  cy.get('[type="submit"]').click()
  // })
})

Login Spec - Spec 1

describe('Dashboard Login Page', () => {

  it('Login (Valid) into Dashboard', () => {
    cy.login()
    cy.url().should('contain', '/home')
    cy.wait(1000)
  })
})

Home Page - Spec 2

describe('Dashboard Tabs', () => {

      it('Confirm User is on Spaces Landing Page', () => {
        //Assert
        cy.get('.list-reset > :nth-child(2) > .caps').click()
        cy.get('[class="flex justify-between pb1"]')
          .should('contain', 'Food Demand Spaces')
        cy.url().should('contain', '/spaces')
      });

What I need is to understand what I can do in this scenario, as we would want to run these tests eventually as part of CircleCI. If you need more info please let me know and I can provide it.

Upvotes: 0

Views: 2464

Answers (1)

Fody
Fody

Reputation: 32128

I think the cy.session() wrapped code needs to be called from every spec.

Did you try spec2 with a call to cy.login()?

With the cy.session() wrapping the actual login code, you should see that on 2nd spec the cookies are re-installed but the actual login code isn't executed a 2nd time.

describe('Dashboard Tabs', () => {

  it('Confirm User is on Spaces Landing Page', () => {

    cy.login()

    cy.get('.list-reset > :nth-child(2) > .caps').click()
    cy.get('[class="flex justify-between pb1"]')
      .should('contain', 'Food Demand Spaces')
    cy.url().should('contain', '/spaces')
  });

Upvotes: 1

Related Questions