Cypress: cy.clearCookies should clear *ALL* cookies of all domains

Created on 1 Feb 2017  路  26Comments  路  Source: cypress-io/cypress

After extensive R&D we've decided to deviate from the Webdriver spec and enhance clearing cookies to include all domains.

By default, Webdriver will only ever clear cookies based on the current domain context. So if you are visiting http://localhost and you issue HTTP requests to other domains (which set cookies) - those cookies will not be cleared.

We currently respect this spec, and our own cookie implementations also have this same restriction.

However, this is really just a limitation of Webdriver - and not necessarily something Cypress ever has to abide to. We've built Cypress with cross browser functionality in mind, and any time we deviate from the Webdriver spec, we are forced to ensure we can create compatibility across all other browsers.

Even though we don't support cross browsers now, it's a fundamental part of our strategy and we intend to support them down the road.

What is the proposed change?

  • cy.clearCookies will clear all cookies on all domains, irrespective of the current browsing context
  • Between tests Cypress automatically clears cookies as well, and it will also clear all cookies across all domains.

How will Cypress be able to consistently clear all cookies?

Cypress's architecture is completely different than that of Webdriver, which puts us in a unique situation to do lots of low level network tricks to pull this off.

While this is subject to change, the way this can be done is by inspecting all of the network traffic that goes through the browser (and therefore Cypress, as we already do), and for all domains, we can manually keep track of all the domains with cookies having been set on them.

At the end of the test, or on a cy.clearCookies command, we can then issue multiple HTTP requests out of the browser (through the Cypress driver) to these various endpoints.

Instead of allowing those requests to pass onto the remote server, Cypress will trap the requests, and automatically respond to the requests by issuing a Set-Cookie header for each cookie that needs to be cleared by setting the Max-Age or Expires directive.

The browser will then run its natural course and clear all of the cookies. This will be a bit slower than programatic API's, but will only have to be done when the browser does not expose any kind of automation API to achieve the same result programatically.

Related issues

pkdriver ready for work topic enhancement

Most helpful comment

is there a timeline when this will be resolved?

All 26 comments

I think I'm having this same issue (that they are not cleared at the moment). I have the following script:

  1. clearCookies()
  2. request() my application's login route (which backend requires you to not already be logged in
  3. run tests

Right now this fails in some situations. I find it hard to get a clear repro, but it seems to be when already logged in before.

The workaround I found (which sounds the same as this issue) is to first do a visit() on my application's domain as step 0. Then indeed the clearCookies() relates to my application's domain and the login works fine.

Maybe in the meantime we should update the docs to make this a bit more clear.
But of course I'd love to see this implemented.

is there a timeline when this will be resolved?

Is there any update on this issue?

+1

+1

+1

Similarly, we want to ensure localStorage is cleared for all domains when using cy.clearLocalStorage() https://github.com/cypress-io/cypress/issues/2573

This is a genuine issue for us:

  • We're testing multiple authenticated states (different roles), two have different cookies and one has no cookie at all (anonymous).
  • We're testing embedded content, so the domain of the test is not the domain our cookies are set against, as the cookies are set with the domain of the embedded (iframe) content.
  • We set the cookies manually using cy.setCookie, however in some situations our embedded content will set the cookie automatically

cy.clearCookies doesn't clear our cookies because they're not in a first-party context. We can't even overwrite the automatic cookies (this would be enough) because cy.setCookie prefixes cookies with a ., as explained in this issue.

This would be very useful for apps that might use a hosted login page from another domain.

Hi team,

Is there a timeline on when we can expect this particular issue to be resolved? This is hindering some automation tests I'm building when utilizing cy.request to make requests. In this suite of tests I've created, it's necessary to clear cookies before each cy.request invocation, and in my particular case, cy.request is the way to go in making requests. I've had to use workarounds, such as the one documented by another user in https://github.com/cypress-io/cypress/issues/1547, so I can continue forward. However, this isn't ideal for maintenance reasons.

I hope someone can respond soon - it seems many others are also relying on this issue to be fixed, and it's been a year since there's been any update on this thread from a team member. If there's another spot we should look to for updates, it would be helpful to let us know of that as well (apologies in advance if that's been pointed out/documented as well).

Thanks!

I use a thirdparty service to handle authentication this means that the authentication cookies are set on a different domain to the one I'm actually testing. Until this new feature is introduced is there a workaround? How can I remove the cookies for all domains between test runs for now?
In my case I found a workaround which is to have a logout call before each test.

I was just browsing through different issues regarding this problem and found something in this this https://github.com/cypress-io/cypress/pull/5657 PR. The topic of the PR seems not to be relevant at first but this comment https://github.com/cypress-io/cypress/pull/5657#issuecomment-555743673 in there says:

I think the failures in the tests are just because we don't clear all cookies of all domains after each test (see #408 ), a cy.clearCookies({ domain: null }) should fix these up... I will look at this some more tomorrow.

I tried this out although its not documented that the cy.clearCookies() function accepts a domain property inside the config object but its actually does and it worked for me.

So what is it @brian-mann @jennifer-shehane ? Is it undocumented functionality or is not supposed to be used ?

FWIW we're blocked from upgrading to 3.8.1 due to these cookies not behaving as expected (or at all?)

Is it undocumented functionality or is not supposed to be used ?

@8BitJonny correct, passing {domain: null} will clear all domains. However, this is undocumented, unsupported, and may change when we improve the cookies API in the future.

@flotwig so cy.clearCookies({ domain: null }) should clear _all_ cookies on _all_ domains? I don't think we're getting that behavior locally - the cookies still persist.

@dylangarcia For me it works like a charm

@flotwig Alright, but for now I will use it as a workaround since it is the best one I found so far

@flotwig Calling cy.clearCookies({ domain: null }) did _not_ clear all of the cookies across domains for our tests (using Cypress v4.5.0 with Chrome 81).

We have some cookies (eg. my_cookie) being set by our server as a Set-Cookie response header with domain: www.flotrack.local. We sometimes want to override the value of this cookie by getting, setting, or clearing it. When our Cypress test runs, the cy.setCookie call appears to set the cookie on the domain: .www.flotrack.local (notice the . prefix) even when provided the domain option www.flotrack.local sans-.

To my surprise manually calling cy.clearCookie('my_cookie') in the after/before methods did work to clear the my_cookie.

We have the same issue, where we need to override a cookie set to a domain without a preceding dot (e.g. site.com) but Cypress adds the domain always with the dot (e.g. .site.com).

cy.clearCookies({ domain: null }) -workaround works for us on 4.6.0, Chrome 81.

cy.clearCookies({ domain: null }) does not work with Cypress 4.6.0 and TypeScript.

Argument of type '{ domain: null; }' is not assignable to parameter of type 'Partial<Loggable & Timeoutable>'.
  Object literal may only specify known properties, and 'domain' does not exist in type 'Partial<Loggable & Timeoutable>'.

cy.clearCookies({ domain: null }) does not work with Cypress 4.6.0 and TypeScript.

@msarakon this parameter is unsupported, undocumented, and so it is untyped as well. But you can override it like this:

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

cy.clearCookies({ domain: null }) is no longer working for me on Cypress 4.12.0

EDIT: I did some more testing and this is not true. Cypress is able to clear cookies via this method in 4.12.0. My problem was I was doing it after the site had loaded instead of before.

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.

My primary application is to clear authenticated session state between test runs, so yes this does address that deficiency for me.

Users who have a more refined or targeted need to clear a cookie they know would exist, but is outside the scope of the current testing run would still experience this deficiency.

Users who need to hand-pick what data they clear will also likely run into the use case where they need to clear _some_ but not _all_ data that is created by a session.

cy.clearCookies({ domain: null }) does not work with Cypress 4.6.0 and TypeScript.

@msarakon this parameter is unsupported, undocumented, and so it is untyped as well. But you can override it like this:

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

This worked for me in 4.12.1 version of cypress, thank you so much.
Added cy.reload(true) after clearing cookies. Made my day :)

For me doing cy.clearCookies() two times in a row also fixes the issue (also in Cypress 5.1)

Was this page helpful?
0 / 5 - 0 ratings