cypress: Cypress doesn't always clean up cookies

Current behavior:

We have a test that checks if an unauthorized user is redirected to the login page when directly visiting a URL to the “backend” site. This test occasionally fails. From the screenshot it is clear that the user was just sent to the specific backend page without login.

image

I checked (console props of the cy.visit command & cy.getCookies + cy.writeFile) and in some cases the auth cookie from the previous test is not cleared. For that I’m using a custom login command that only fetches cookies once (per username) and stores them in the global scope. Then I use cy.setCookie() to set the cookie again.

In this case the cookie was set in the beforeEach hook of the previous test.

Obviously this never fails if I just run the latter spec.

Desired behavior:

Obviously, by default (unless Cypress.Cookies.preserveOnce() is used), all cookies should be cleared before a test run starts.

How to reproduce:

This is hard. I couldn’t narrow it down to one specific always-reproducable scenario but these are things I can confidently say about it:

  • I’ve seen it fail multiple times in headless runs
  • I’ve seen it fail multiple times in headed runs (cypress run --headed)
  • I’ve seen this fail one time in the UI (cypress open)
  • I’ve seen it fail in all 3 browsers in headed runs

I’m not sure but it seems to fail easier if I change the focus to other apps (or spaces) while running the tests, but even that isn’t deterministic for me.

  • Operating System: Mac OS X Sierra
  • Cypress Version: 1.0.2
  • Browser Version: All

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 90
  • Comments: 114 (33 by maintainers)

Commits related to this issue

Most upvoted comments

Can confirm, Cypress does not clear the cookies between tests, it let it leaks. This not happens all the time though.

This is definitely a significant issue! Feel like something that requires warnings in the docs until it’s resolved, as it took us a while to figure out why tests were failing when the documentation claims that cookies are cleared between tests.

Like many others have noted in our case the problem was that we wanted to clear a JWT cookie that had a domain set like mycompany.com instead of say localhost so these cookies won’t be cleared by cypress. So I had to use this undocumented feature with a fix for TypeScript since our tests use .ts files:

// @ts-ignore
cy.clearCookies({ domain: null })

This issue celebrated it’s second birthday yesterday and the third birthday for the related issue #408 is a few months away. Is there anything we can to do help? Is Cypress still being supported?

What is the status of this problem?

Any update on cleaning up lingering XHR requests from previous tests?

My temporary workaround:

describe('Auth', function () {

    before(() => {

        // remove this when issue will be solved
        // https://github.com/cypress-io/cypress/issues/781
        cy.visit('/')
        cy.clearCookies()
        cy.reload()
    })

...

Place this code at the very beginning of your tests (I guess they are ordered alphabetically).

same issue here with cypress 3.1.5. our setup is:

  • testing angular 5 frontend

  • most tests which start with login

  • cypress open -> run all tests : no problems

  • cypress run -> all tests against localhost (http) : no problems

  • cypress run -> all tests against dev system with https : after some successful specs the login stops to work, because there is still the access_token cookie from previous spec run available, all other test specs with login then fail

  • with the fix proposed by @anurbol we can work around the problem

This is an absolutely essential issue, don’t understand, why the bug is still open

I had the same problem: cookies are not cleared by cy.clearCookies()

So what I did was simply overwrite the clearCookies command, in support/commands.js

Cypress.Commands.overwrite("clearCookies", () => {
    cy.getCookies().then(cookies => {
        for (const cookie of cookies) {
            cy.clearCookie(cookie.name)
        }
    })
})

This is a long shot, but could this issue be caused by leftover XHR requests that contains set-cookie headers? Imagine test 1 completing whatever it is supposed to do and that you check that the page contains some string. The page fires some XHR requests to do some very important stuff. Meanwhile, Cypress moves on to the next test and goes about canceling the XHR requests and clearing cookies. Could it be that if we’re unlucky, the leftover XHR request gets treated by the browser to the point where the set-cookie header is read and applied and that this somehow (asynchronously?) happens after the clearCookie command has run?

We experience the same issues as above, and none of the fixes seems to have worked. But I did notice a bunch of XHR requests being cancelled in my beforeEach step (where I clear cookies). I tried introducing a little delay before clearing the cookies, and all of a sudden all my tests started passing:

  beforeEach(() => {
    cy.wait(2000);
    cy.clearCookies();
    cy.visit('/');
  });

This theory would explain why this has been hard to reproduce in a simple isolated case, as you would need a sufficient bunch of XHR requests happening directly after page load and that all of the has a set-cookie header.

We’re in exactly the same position. Ready to make a big investment in Cyprus (including becoming a paying customer), but this is the biggest blocker for us. The length of time and lack of communication is giving us second thoughts.

Clearing cookies should be delayed.

This one works fine, at least on my side the reason seems like in the application itself, sometimes cookies might be set after some time application boots/loads.

      cy.wait(100)
      cy.clearCookies()

too bad this issue still exist, just stumbled upon it today. The workaround to visit a page, clear the cookies and then reload again works though.

We’ve outlined some work to be done to address some of the concerns of ‘cookies’ in this issue: https://github.com/cypress-io/cypress/issues/8301

It outlines a proposal for a ‘session’ API, to quickly summarize:

With cy.session, you’ll be able to perform UI interactions before taking a “snapshot” of all the session related data and “restore” it before each test.

This session related data would include cookies.

I recommend reading the entire proposal in https://github.com/cypress-io/cypress/issues/8301 and following there for any updates. Please feel free to express any concerns or questions in that issue concerning the API and add a 👍 for general support.

Same issue for me. The workaround cy.clearCookies({domain: null}) from https://github.com/cypress-io/cypress/issues/408 solved it for me locally. Haven’t tried in CI.

Shouldn’t this be high prio and not backlog? The issue is now open for years and still not resolved, leaving us with flaky tests when dealing with cookies/session.

Like many others have noted in our case the problem was that we wanted to clear a JWT cookie that had a domain set like mycompany.com instead of say localhost so these cookies won’t be cleared by cypress. So I had to use this undocumented feature with a fix for TypeScript since our tests use .ts files:

// @ts-ignore
cy.clearCookies({ domain: null })

This worked for me! Specifying the actual domain also works but this is even better. Thanks!

Ok, 4 hours later of trying to write my own cookie layer on top of Cypress, it’s now obvious where’s the flake from cold run coming from:

  1. cypress on cold run opens a browser and visits http://localhost:53814 (or something like that) which is its own domain.
  2. you run cy.clearCookies() (well you don’t have to since Cypress does it before eachh test) in a before() hook in your index.js, and it clears the cookie from that domain, not your own.
  3. you then run cy.visit('your.domain/'), and it has the cookies from your previous run — provided you didn’t run cy.clearCookies() in an after() hook - use of which is usually discouraged because after() isn’t guaranteed to run (which is why we didn’t do that).

Thus, until https://github.com/cypress-io/cypress/issues/408 is implemented, the only way to solve this (without hacks such as recovering from flake and running cy.visit() twice) is to put cy.clearCookies() in the after() hook in index.js.

EDIT (18-11-18):

The main issue is this: on a cold run, setting an initial cookie before the first cy.visit will set a cookie with domain of the cypress runner’s empty page (localhost on a random port), and that cookie won’t be sent alongside the cy.visit request to your server. This can be fixed and automated away using this code (adapt for your purposes):

// cypress/support/index.js

Cypress.Commands.overwrite( 'setCookie', (origFn, name, value, opts) => {
    return origFn(name, value, {
        domain: '.' + new URL(Cypress.config('baseUrl')).hostname,
        ...opts
    });
});

before(() => {
    Cypress.config('baseUrl', 'http://your-app.test');
});

I understand this bug was opened in October 2017, but could we get some confirmation that this is indeed a high priority issue? I’m trying to convince a rather large Ruby team using Rspec to move over to Cypress and with inconsistent cookie handling, there’s simply no way we can start integrating this into our CI and start replacing the old (flaky) Ruby tests.

Love the work and philosophy behind Cypress but it is sometimes a bit hard to see what is actively being worked on and what is a priority. If this really is something which still “needs investigating” after the amount of user reproductions, I’m not sure I can convince my team this really is the right choice for us at the moment 😕 (I may be assuming too much of that label!)

After having upgraded to v5.5.0 from v3.4.0 (big mistake), we’ve started experiencing not only cookies not being cleaned up, but also cookies leaking into requests towards other origins. Do you have any idea how much fuckery this is causing? How have you, Cypress, not experienced all these cookie-issues in your own test suite?

can confirm that issue still is there in 4.12.1 (had it on 4.7.0, upgraded, but still have it)

rarely, but sometimes cypress does not delete cookies, and its completely random

Auth0 tokens are also not cleaned up from browser by using any of the available methods. When you first log in, it never cleans up the cookies and you never get to log in page for entering the credentials anymore. This is quite a serious issue.

In my case it was silly, I had whitelist configuration to keep session id between different cy.location() calls and I forgot about it:

Cypress.Cookies.defaults({whitelist: 'sid'});

So I need to clean up this particular cookie before run whole test spec: before(() => cy.clearCookie('sid'));. Just in case.

Like many others have noted in our case the problem was that we wanted to clear a JWT cookie that had a domain set like mycompany.com instead of say localhost so these cookies won’t be cleared by cypress. So I had to use this undocumented feature with a fix for TypeScript since our tests use .ts files:

// @ts-ignore
cy.clearCookies({ domain: null })

Thanks bro, your answer solved my problem =)

Still the same issue for me too on 8.2.0

I’m getting the same thing in cypress 5.2 Even though I clear cookies SEVERAL TIMES in a row:

    cy.window().then((win) => {
        win.sessionStorage.clear()
    });
    cy.clearCookies({domain: null});
    cy.clearCookies();
    cy.getCookies().should('be.empty');
    cy.clearLocalStorage();

And a few times before the test separately etc. The get cookies sometimes yields

 "before each" hook for "tests logging in with a new account admin user ":
     AssertionError: expected [ Array(2) ] to be empty

How can I log these cookies and see which ones fail to clear? When running in headless or headed, not the “OPEN” mode, where I can obviously go to the console and look.

Any update on cleaning up lingering XHR requests from previous tests?

@Jacek-fstack did you see my workaround above? https://github.com/cypress-io/cypress/issues/781#issuecomment-448977376

I thinking visiting a blank page is the best way to let browser clean up all lingering XHRs.

I think this has all been suggested before but wanted to share just in case it helps someone.


My experience with leaky cookies seems to depend on how I’m running Cypress [cypress@3.8.0]. I am using the Nuxt.js (Vue.js) framework so perhaps there are some unforeseen interactions between Cypress’ two different modes and Nuxt’s Server Side Rendering + rehydration.

In GUI mode cypress open:

  • my test passes.
  • suggests the cookies are being cleared correctly between tests.
  • can see the test running correctly in the browser.

In CI mode cypress run:

  • my test fails.
  • suggests cookies are not cleared correctly between tests.
  • can see the test failing, consistent with uncleared cookies, in the generated video.

Using the fix provided by others above seems to clear the problem up for me.

[Edit 20/12/2019: unfortunately I have found that this doesn’t solve the issue all the time, but the issue does occur a lot less frequently].

I’ve put it in a Cypress command for convenience. The cy.reload() part seems particularly important but that may be cutting through an issue to do with clearing Nuxt.js’ state, rather than Cypress.

// cypress/support/commands.js

// remove this when issue will be solved
// https://github.com/cypress-io/cypress/issues/781
Cypress.Commands.add('reallyClearCookiesCypressIssue781', () => {
  cy.visit('/')
  cy.clearCookies()
  cy.reload()
})
// cypress/integration/file_name.spec.js

  it(`Test name`, () => {
    cy.reallyClearCookiesCypressIssue781()
    // rest of test that relies upon clear cookies…
  })

The issue narrows down to the following:

  • Cypress visits the baseUrl in your cypress config.
  • If you didnt provide a baseurl it will visit localhost with a random port.
  • It clears cookies, sessionStorage, localStorage etc. on this domain.

Cookies are scoped per domain name. If your test spans over multiple domains cookies will NOT be removed on all of these.

This will result in your tests being really flaky, especially since your tests do not necessarily always run in the same order, and therefore different cookies will influence each other.

I am not sure if this should be considered a bug. Cypress doesn’t know which cookies in your browser are part of the test. This is how the browser operates.

So, bottomline:

Single host test: Set your baseUrl

Multi host test: Clear all cookies yourself by visiting each host that is going to be consulted in your test and calling clearCookies

We have set the baseurl in cypress.json and still see this behaviour erratically. The behaviour only occurs when doing a login with cy.request, it doesn’t appear to properly set the cookies and the previous cookies are used? See screenshots for reproduction. Note original cookie used in second test only after visiting a new address.

First user test screenshot

Second user test screenshot

Example done with something similar to below:

// log cookies here
cy.request({
  method: 'POST',
  url: '/account/login',
  followRedirect: false,
  form: true,
  body: {
    email: user.email,
    password: user.password
  }
}).then((resp) => {
  cy.visit(resp.redirectedToUrl);
});

// log cookies here
cy.visit('/home')

// log cookies here