Skip to content
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

Clear sessionStorage in between tests #413

Closed
brian-mann opened this issue Feb 6, 2017 · 29 comments
Closed

Clear sessionStorage in between tests #413

brian-mann opened this issue Feb 6, 2017 · 29 comments
Assignees
Labels
pkg/driver This is due to an issue in the packages/driver directory type: feature New feature that does not currently exist v12.0.0 🐛

Comments

@brian-mann
Copy link
Member

brian-mann commented Feb 6, 2017

Currently we clear cookies and localStorage but somehow we missed automatically clearing sessionStorage as well.

This needs to be added, and we likely need to add a new cy.clearSessionStorage API command.

Thanks to @abadstubner for finding this one.

Currently as a workaround you can manually clear sessionStorage like this:

cy.window().then((win) => {
  win.sessionStorage.clear()
})
@jennifer-shehane jennifer-shehane added the type: feature New feature that does not currently exist label Feb 6, 2017
@aluzardo
Copy link

aluzardo commented Feb 20, 2017

I am having the same issue. I need one method to clear sessionStorage.

Thanks @brian-mann for the workaround.

cy.window().then((win) => {
  win.sessionStorage.clear()
});

@acthp
Copy link

acthp commented Dec 6, 2017

I'm hitting this, but the workaround isn't helping. Can you provide more detail?

The problem is that if I place this before cy.visit(), it seems to operate on the wrong window object, and if I place it after cy.visit(), the application code has already read sessionStorage by the time the cy.window.then() callback fires.

To get a repeatable test, sessionStorage needs to be managed before the app executes.

@brian-mann
Copy link
Member Author

Browsers partition sessionStorage by origin not by window.

In fact the cy.window().then((win) => stuff isn't actually even necessary .

Because Cypress test code is always on the same origin as your application, modifying sessionStorage from any window will work.

Another option is using the onBeforeLoad callback of cy.visit.

There's no reason though for this not to be working. Just place debugger everywhere and you can use the dev tools tabs to inspect the Application area and you will see exactly what session and local storage is in use. In other words - you can prove what is happening, no need to guess or theorize.

My guess is that you're not putting this code in a beforeEach and its being reset and then it's coming back whenever your application is visited.

@brian-mann
Copy link
Member Author

screen shot 2017-12-05 at 8 44 09 pm

@acthp
Copy link

acthp commented Dec 6, 2017

Using beforeEach doesn't help. Setting breakpoints, the issue seems to be that beforeEach runs before the previous page is unloaded, and so the app's beforeunload handler will then save to sessionStorage after it's been cleared, and before the next test starts.

It's pretty confusing trying to follow how the window is being manipulated. beforeunload never fires if there's only one test. If there are two tests, beforeunload fires between the two tests. I guess this means the window is destroyed between test runs, but is reused between test cases.

To get a consistent environment, then, we need to destroy the window between each test, or navigate away from the app in afterEach to trigger the beforeunload handler, then clear sessionStorage in beforeEach. Any suggestions?

Update: Visiting a static page (no javascript) in afterEach does resolve the problem by coercing the beforeunload.

@brian-mann
Copy link
Member Author

This sounds like a classic anti pattern of building up state between tests.

Each test should start from a clean slate and visit before each test.

https://docs.cypress.io/guides/references/best-practices.html#Having-tests-rely-on-the-state-of-previous-tests

As I also suggested, you could use the onBeforeLoad callback handler of cy.visit to clear the sessionState prior to your application loading.

@brian-mann
Copy link
Member Author

Okay taking a second look I understand a bit better and can answer your questions.

beforeunload would naturally fire between two tests because that's what cy.visit does. It navigates the window - same as changing the URL. This is expected and correct behavior.

The window is not re-used (that's impossible), it is nuked as per what happens whenever there is a page navigation caused by cy.visit. When a run starts, we do wipe away everything including the window and outer iframe holding the window. Between tests it would be too slow to do this, and we actually don't do anything to nuke the application.

We have an open issue explaining lifecycle events and the reason they need to be refactored here. #686 It goes into a lot of detail and is related to your problem.

Using afterEach hooks like that is also an anti pattern ;-)

https://docs.cypress.io/guides/references/best-practices.html#Using-after-or-afterEach-hooks

You really should just use the onBeforeLoad callback handler of the visit as it will do exactly what it is you want it to do without needing an afterEach hook.

@acthp
Copy link

acthp commented Dec 6, 2017

Ah, cool, I'll try that. afterEach had another problem, which is that if there were any pending ajax requests, they would be canceled on page navigation, which would return an ajax error 0, causing the afterEach to error out & abort the rest of the suite. The same thing happens (canceled requests) while running tests, but in that case doesn't abort the suite. Not sure why the difference, but I'll try onBeforeLoad.

Update: onBeforeLoad works perfectly.

@jennifer-shehane jennifer-shehane added the pkg/driver This is due to an issue in the packages/driver directory label Dec 7, 2017
@lgandecki
Copy link

lgandecki commented Jan 7, 2018

any reasons why not add this clearing to the onBeforeLoad in the cypress itself? I think we should either have all cookies/localStorage/sessionStorage clean automatically, or none of them + deal with them manually :)

Thanks for the solution though!

@brian-mann
Copy link
Member Author

Yup it's part of a much larger story here: #686

@CoenWarmer
Copy link

Would it be possible to provide an example of how to use the onBeforeLoad handler in this scenario? I'm encountering the same issues and can't figure out how to proceed.

@brian-mann
Copy link
Member Author

clearing sessionStorage are just synchronous methods you call on the window.

cy.visit('...', {
  onBeforeLoad: (win) => {
    win.sessionStorage.clear()
  }
})

Read https://docs.cypress.io/api/events/catalog-of-events.html as well.

@salty-blue-mango
Copy link

I am using the onBeforeLoad workaround to clear the session storage. When I initially open my login test in the test runner the sessionStorage does not get cleared. If I use the refresh in the test runner, the sessionStorage is cleared and works as expected. Why would it be that upon initial start up of the test runner my session storage is not being cleared?

@kud

This comment has been minimized.

@surfjedi

This comment has been minimized.

@rwralitera

This comment has been minimized.

@jennifer-shehane jennifer-shehane added the stage: ready for work The issue is reproducible and in scope label Feb 15, 2019
jhoerr added a commit to indiana-university/itpeople-app that referenced this issue Jan 21, 2020
@Jacek-fstack
Copy link

I am still facing this and the provided solution is not helping : / Just started automating a new app, this wasn't the issue with the other app I work on. Anything else I can do to clear sessions between tests?
I tried adding

beforeEach(function () {
    cy.window().then((win) => {
        win.sessionStorage.clear()
    });
});

to index.js and cy.clearCookies();
Neither help, still hitting the issue every few tests

@mattmbrightside
Copy link

mattmbrightside commented Jun 11, 2020

This solution works for me at the start of each test
cy.visit('/', { onBeforeLoad: (win) => { win.sessionStorage.clear() } });

@Jacek-fstack
Copy link

Tried that one as well : /

@jpaquit
Copy link

jpaquit commented Jun 18, 2020

I managed to remove session Storage this way (Cypress 4.7.0, Win10 x64) (cy.clearCookies() and cy.clearLocalStorage() do not affect session storage).

beforeEach(() => {
...
...
// No leaks between scenarii
 sessionStorage.clear()
 cy.clearCookies()
 cy.clearLocalStorage()
 });

https://developer.mozilla.org//docs/Web/API/Window/sessionStorage

@Jacek-fstack
Copy link

It worked for me, thank you @jpaquit

@single-stop-justin
Copy link

single-stop-justin commented Aug 14, 2020

When will cy.clearSessionStorage be implemented?

None of the workarounds have worked here. I am even clearing session store beforeEach and onBeforeLoad. The result is tests randomly passing, definitely a race condition.

One time the entire suite passes.
The next time one test fails.
The next time three fails.
The next time two different tests fail....

@jennifer-shehane
Copy link
Member

We've outlined some work to be done to address some of the concerns of 'session storage' in this issue: #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.

The session related data would include sessionStorage.

I recommend reading the entire proposal in #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.

@AhmedYousseff
Copy link

AhmedYousseff commented Mar 6, 2021

describe('Required Object e2e test', () => {
  let startingObjectsCount = 0;

  before(() => {
    cy.window().then(win => {
      win.sessionStorage.clear();
    });

    cy.clearCookies();

    cy.intercept('GET', '/api/objects*').as('entitiesRequest');
    cy.visit(''); // is configured in cypress.json 
    cy.wait('@entitiesRequest').then(({ request, response }) => (startingObjectsCount = response.body.length));
    cy.visit('/');
  });
})

@jennifer-shehane
Copy link
Member

We released cy.session() as an experimental command (set experimentalSessionSupport to true in config) in Cypress 8.2.0. This command can be used to cache and restore cookies, localStorage, and sessionStorage. We especially see this command as being useful for testing Auth flows and recommend giving it a try to replace your existing tests around authentication and login.

If you have any feedback about cy.session() for general UX improvements, new features, or unexpected behavior, please leave your feedback in our Cypress Session Experimental Feedback Discussion.

@jayanthktn
Copy link

@jennifer-shehane
This works really well, I was trying so many things to suppress the session handling, by default clearing option is really great !
image

@tnrich
Copy link
Contributor

tnrich commented Mar 18, 2022

This has not yet been fixed on the latest cypress version (9.5.2)

@cypress-bot cypress-bot bot added stage: backlog and removed stage: ready for work The issue is reproducible and in scope labels Apr 29, 2022
@emilyrohrbough
Copy link
Member

emilyrohrbough commented Nov 7, 2022

This behavior will be enabled by default via test isolation when the experimentalSessionAndOrigin is released as GA.

In v12.0.0 (soon-to-be-released), we are introducing the concept of Test Isolation. There will be two modes of test isolation, on and off, with on being the new default mode. When test isolation is on, before each test, Cypress will:

  • clear the page by visiting about:blank
  • clear cookies
  • clear local storage
  • clear browser storage

Closing this issue as done since will enable this behavior by default.

Please following #24277 for the cy.clearSessionStorage() command implementation.

@cypress-bot
Copy link
Contributor

cypress-bot bot commented Dec 6, 2022

Released in 12.0.0.

This comment thread has been locked. If you are still experiencing this issue after upgrading to
Cypress v12.0.0, please open a new issue.

@cypress-bot cypress-bot bot locked as resolved and limited conversation to collaborators Dec 6, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
pkg/driver This is due to an issue in the packages/driver directory type: feature New feature that does not currently exist v12.0.0 🐛
Projects
None yet
Development

No branches or pull requests