-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Option to not flush cookies between tests #959
Comments
There is an API to preserve cookies in between tests: https://docs.cypress.io/api/cypress-api/cookies.html I'm closing this issue in favor of this one (below) because it goes in length to explain why what we do by default is a bad idea and what needs to change. It's a priority but its underneath other things unfortunately. |
This will preserve cookies in every test beforeEach(() => {
// Preserve cookie in every test
Cypress.Cookies.defaults({
whitelist: (cookie) => {
return true;
}
})
}); |
For those arriving from the future, starting in version 5.0.0 the https://docs.cypress.io/guides/references/changelog.html#5-0-0 |
I ended up using beforeEach(function () {
cy.getCookies().then(cookies => {
const namesOfCookies = cookies.map(c => c.name)
Cypress.Cookies.preserveOnce(...namesOfCookies)
})
}) Hopefully, this will help someone else. Power UpYou can also create a command if you are re-using this. // commands.js
Cypress.Commands.add('preserveAllCookiesOnce', () => {
cy.getCookies().then(cookies => {
const namesOfCookies = cookies.map(c => c.name)
Cypress.Cookies.preserveOnce(...namesOfCookies)
})
})
// your-suite.test.js
beforeEach(function () {
cy.preserveAllCookiesOnce()
}); ExplanationThe problem with
Is that according to the docs (https://docs.cypress.io/api/cypress-api/cookies#Defaults),
In other words, using |
You can also look into this code, This reads and preserves all cookies, If you are not particular about something you can use this |
Guys, we just started writing our automation in cypress, we will most require to store cookies to be used in all the spec files except for one or two specs say for ex: when testing authentication section. So added :
in cypress/support/index.js file. How can I exclude few files to not use cookies? Please suggest |
@mekalag that's separate to this issue but I wanted to add a suggestion in case it helps other people end up in this thread looking for an answer to your question. One userland idea I had is to clear the cookies for the command you need to run and then restoring them: /**
* Clears cookies before executing a callback and then restores the cookies.
* @param {Function} callback
* @param {{ domain, log, timeout }} options https://docs.cypress.io/api/commands/getcookies#Arguments
*/
Cypress.Commands.add('ignoreCookiesOnce', (callback, options) => {
return cy.getCookies(options).then(cookies => {
// Clear cookies
cy.clearCookies(options)
// Execute callback
callback()
// Restore cookies
cookies.forEach(({name, value, ...rest}) => {
cy.setCookie(name, value, rest)
})
})
}) Then you could do: cy.ignoreCookiesOnce(
() => {
cy.request({
url: 'https://...',
method: 'POST',
headers: {
Cookie: 'whateveryouwant'
},
body: `...`
}).then(({body}) => body)
},
{domain: 'yourdomain.com'} // optional
) Hope this helps 👍 You can also be much more flexible if you need to pass specific cookies to clear: /**
* Clears cookies before executing a callback and then restores the cookies.
* Usage:
* 1. cy.ignoreCookiesOnce(() => cy.visit(...))
* 2. cy.ignoreCookiesOnce(() => cy.request(...), { domain: 'yourdomain.com'})
* 3. cy.ignoreCookiesOnce(() => cy.visit(...), { cookies: ['foo', 'bar']})
* 4. cy.ignoreCookiesOnce(() => cy.request(...), { except: ['foo', 'bar']})
* @param {Function} callback
* @param {{ cookies: Array, except: Array, domain: string, log, timeout }} options See: https://docs.cypress.io/api/commands/getcookies#Arguments
*/
Cypress.Commands.add('ignoreCookiesOnce', (callback, options = {}) => {
Cypress.Cookies.debug(true, {verbose: true})
let {cookies, except, ...cyOptions} = options
return cy.getCookies(cyOptions).then((all = []) => {
// Obtain cookies from options
if (Array.isArray(cookies) && cookies.length > 0) {
cookies = cookies.map(n => all.find(c => c.name === n))
} else if (Array.isArray(except) && except.length > 0) {
cookies = all.filter(c => !except.includes(c.name))
} else {
cookies = all
}
// Clear cookies
if (cookies === all) {
cy.clearCookies(cyOptions) // clear all
} else {
cookies.forEach(c => cy.clearCookie(c.name, cyOptions))
}
// Execute callback
callback()
// Restore cookies
cookies.forEach(({name, value, ...rest}) => {
cy.setCookie(name, value, rest)
})
})
}) I also added this answer to stackoverflow: https://stackoverflow.com/a/75035723/4984618. |
Is this a Feature or Bug?
Unexpected bahaviour.
Current behavior:
Cookies are automatically flushed between tests (as per the documentation).
Desired behavior:
Have an option to not flush cookies between tests for more control.
How to reproduce:
Test code:
The text was updated successfully, but these errors were encountered: