Reputation: 396
We used to login into our application using the cy.request() method and here the JSESSIONID cookie is set.
login(): void {
cy.clearCookie('JSESSIONID');
cy.request({
method: 'POST',
url: `${apiUrl()}/sessions`,
body: {
userName: 'xxx',
password: 'yyy',
},
});
}
I had the JSESSIONID cookie preserved once with:
Cypress.Cookies.defaults({ preserve: 'JSESSIONID',});
in the file support/index.js
Now we want to migrate to Cypress 12. But there the "Cypress.Cookies.defaults" has been deprecated. It said, you have to use cy.session, instead.
After the migration process the above code is located in e2e.js. But how would you there preserve the cookie? I tried several ways but with now luck so far.
e.g.: in cypress documentation is this code snippet:
// Caching session when logging in via API
cy.session(username, () => {
cy.request({
method: 'POST',
url: '/login',
body: { username, password },
}).then(({ body }) => {
window.localStorage.setItem('authToken', body.token)
})
})
This does not work as body.token does not exist (at least in version 12.3.0)
Upvotes: 0
Views: 782
Reputation: 5441
cy.session()
would be called in a beforeEach()
if you want to preserve data across multiple tests.
General approach:
beforeEach(() => {
cy.session('session name', callback_function)
})
These are the steps:
On the every test cy.session()
checks it's cache for key 'session name'
On first test, nothing is found so callback_function
is called
After callback_function
finishes, all the session data is stored under the key 'session name'
On second test, the cache key 'session name'
is found, so cy.session()
restores that data to the browser. It doesn't call the callback a second time.
So in your case you can change the POM login method to this.
Note the key should be login
instead of username, so data is preserved using the same key.
login(): void {
cy.session('login', () => {
cy.request({
method: 'POST',
url: `${apiUrl()}/sessions`,
body: {
userName: 'xxx',
password: 'yyy',
},
});
})
}
In the test code you can wrap the login in a beforeEach()
const loginPage = new LoginPage()
beforeEach(() => {
loginPage.login('Jon')
})
it('test 1 logged in', () => {
...
})
it('test 2 logged in', () => {
...
})
Or you can just call .login()
where the test needs to be logged in.
const loginPage = new LoginPage()
it('test 1 logged in', () => {
loginPage.login('Jon')
...
})
it('test 2 logged in', () => {
loginPage.login('Jack')
...
})
it('test 3 not logged in', () => {
// don't call login here
...
})
Upvotes: 4
Reputation: 7125
From the session()
documentation
[Use cy.session() to] Cache and restore cookies, localStorage, and sessionStorage (i.e. session data) in order to recreate a consistent browser context between tests.
So, cy.session()
should be caching your cookies that have been set in previous tests that use the same cy.session()
identifier. Your login()
function could look something like this:
login(userName: string = 'xxx'): void {
cy.session(userName) {
cy.request({
method: 'POST',
url: `${apiUrl()}/sessions`,
body: {
userName,
password: 'yyy',
},
});
}
}
As for the Cypress documentation not working, it would be because your request to /login
does not return a response with a body object that contains the field token
.
Upvotes: 0