2

Im currently trying to learn Cypress 10 and I came to an issue where I see that every it I do, it clears the cookies which is not what I want and here is my code...

Suite('My First Test', () => {
  before(() => {
    prepare();

    cy.visit('https://barrythrill.com');

    cy.get('.start-from-zero').should('be.visible').click();

    ...
  });

  Scenario('My first test cases', () => {
    Given('we are on the webpage');

    When('we save the list', () => {
          // no cy.visit
      ... // we save the list it will automatically login and it creates a cookie called BAR (has a dynamic cookie)
    });

    Then('we are able to open all-list and close it', () => {
      ... // no cy.visit
    });

    When('we remove the list through API', () => {
      ... // no cy.visit
    });
    Then('we should still be logged it', () => {
        ... // cy.visit(''https://barrythrill.com')
            // We should still be logged in through ` When('we save the list', ()`
    });
  });
});

I was not able to figure out how I can use cy.session here or to create a correct tests for my test cases. I wonder if anyone here can help me on either how I can improve my code where I can still be logged in through whole test or how I can implement cy.session without needing to call cy.visit for each it?

PythonNewbie
  • 1,031
  • 1
  • 15
  • 33

1 Answers1

3

I presume prepare() is getting your cookies?

I think what you need to do is add a beforeEach() with cy.session() and call prepare() inside it.

beforeEach(() => {
  cy.session('prepare', () => {
    prepare();
  })
})

The session is invoked for every it(), but only the first time calls prepare() - after that it sets cookies from cache.

You probably still need the before() as-is to allow cy.visit() to work.

Here I'm starting at the top of Cypress recipe page, and test1 ends up at the Blogs section which is where test2 starts off.


Preserving location between tests

Not sure this works with cucumber, or if any visit at all mucks up your test flow.

Cypress recommends performing cy.visit() straight after cy.session() as in the following sample.

You can preserve the last location after each test with a afterEach(). The visit in the next beforeEach() call will use that location.

Cypress.session.clearAllSavedSessions()

let location = 'https://docs.cypress.io/examples/examples/recipes'

beforeEach(() => {
  cy.session('cookies', () => {
    cy.setCookie('test', 'my-cookie')
  })
  cy.visit(location)
})

afterEach(() => {
  location = cy.state('window').location.href
})

it('test1', () => {
  expect(cy.state('window').location.href)
    .to.eq('https://docs.cypress.io/examples/examples/recipes')

  cy.getCookie('test').then(cookie => {
    expect(cookie.value).to.eq('my-cookie')
  })

  // navigate elsewhere
  cy.visit('https://docs.cypress.io/examples/examples/recipes#Blogs')
});

it('test2', () => {
  expect(cy.state('window').location.href)
    .to.eq('https://docs.cypress.io/examples/examples/recipes#Blogs')

  cy.getCookie('test').then(cookie => {
    expect(cookie.value).to.eq('my-cookie')
  })
});
Fody
  • 23,754
  • 3
  • 20
  • 37
  • Its the row `When('we save the list', () => {` where it logins the user and then it will automatically create a cookie. so prepare just does some settings such as auth, enabling some features and such. Not logging in. – PythonNewbie Jun 29 '22 at 08:11
  • Is the code there something you can shift to `beforeEach()`? – Fody Jun 29 '22 at 08:13
  • I mean what I could do is that I could do a login before a test... but it feels odd that I need to login then for every `it` I do? - Unless I misunderstood how it works? – PythonNewbie Jun 29 '22 at 08:14
  • and I also believe if I do the way you recommended, dont I need to do cy.visit for every IT? – PythonNewbie Jun 29 '22 at 08:16
  • You're not really logging in every `it`, because of the cache effect of `session` the login code inside `session` callback is only ever called once (to prime the cache) thereafter session restores the cookies from cache. You can try it and add a `console.log('login')` inside `session`, it will only print out once. – Fody Jun 29 '22 at 08:18
  • I do get the message: We always navigate you here after cy.session() To continue your test, follow up the command with cy.visit(), meaning that it wont continue without a cy.visit for each `it` - feels odd... – PythonNewbie Jun 29 '22 at 08:21
  • Actually from previous question `cy.session()` resets location to a blank page - so you will need to visit on each test. A bit of a blunder wrt to that IMO. – Fody Jun 29 '22 at 08:22
  • Totally agree.. my problem is that I am not able to do cy.visit for each `it` due to when I click on some button, it redirects to a page with a dynamic URL session (in the url) and that means I cannot pre-know what URL I will get. If that make sense? Maybe you have other suggestions? – PythonNewbie Jun 29 '22 at 08:25
  • I think you can still use the cookie preserve functions at the moment. I think they will modify `session` (it's still experimental). – Fody Jun 29 '22 at 08:26
  • I tried to use the cookie preserve but it seems to be deprecated already in Cypress 10 – PythonNewbie Jun 29 '22 at 08:29
  • Hi, I just saw your updated code. This will unfortunately also fail for me. Atleast for my test cases. I will need to figure out something else. Perhaps I will just end up needing to do a login button where I can call it – PythonNewbie Jun 29 '22 at 10:17
  • Bad luck - BTW I think cookie preserve requires `experimentalSessionAndOrigin: false`. It seems to be working in v 10.3.0. – Fody Jun 29 '22 at 10:25
  • Weird, according to https://docs.cypress.io/api/cypress-api/cookies#Defaults - It says deprecated – PythonNewbie Jun 29 '22 at 10:45
  • 1
    But not removed... You get strike-through in VSCode because of `cypress.d.ts` but the code still works. Just took me a while to realize the `experimentalSessionAndOrigin` needed to be off. Same with `cy.route()`, it stuck around for ages after `cy.intercept()` was live. – Fody Jun 29 '22 at 11:11