-
Notifications
You must be signed in to change notification settings - Fork 3.3k
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
Add option to allow LocalStorage entries to persist between tests #461
Comments
👍 Would a be nice feature! |
Yes, please! |
Yes, that would really help us with our application which uses cognito by AWS as a authentication provider (which under the hood uses localstorage) |
You can achieve this manually right now because the method thats clear local storage is publicly exposed as You can backup this method and override it based on the keys sent in. const clear = Cypress.LocalStorage.clear
Cypress.LocalStorage.clear = function (keys, ls, rs) {
// do something with the keys here
if (keys) {
return clear.apply(this, arguments)
}
} |
@brian-mann I had similar problem and this worked, thanks ! However, I assume that there's a typo and it should've been
|
@jurom Thanks, this has been fixed in brian's example. |
I've tried your example @brian-mann but i get empty keys array on every call. Any ideas why ? |
@lacroixdavid1 then it sounds like you don't have anything in localStorage. Are you sure you're not storing it in SessionStorage? You don't have to guess - just use Dev Tools Application Tab and it'll show you everything that's being stored. |
@brian-mann it is really stored in localstorage with key |
const clear = Cypress.LocalStorage.clear;
Cypress.LocalStorage.clear = function (keys, ls, rs) {
// do something with the keys here
if (keys) {
debugger;
// return clear.apply(this, arguments)
}
} This doesn't clear my localStorage, but i need to filter keys. |
Put the |
In .each (item) =>
if keys.length
@_ifItemMatchesAnyKey item, keys, (key) =>
@_removeItem(storage, key)
else
@_removeItem(storage, item) My localStorage gets fully cleared as Also, in Why this ? because of the following : Cypress.prependListener "test:before:run", ->
try
## this may fail if the current
## window is bound to another origin
clearLocalStorage(state, [])
catch
null you can clearly see that method @brian-mann am I missing something? is there anything broken? |
@brian-mann any suggestions ? |
Those misleading answers and that dead silence leave me disappointed about cypress.io. |
Sorry to hear @lacroixdavid1 - but notice that this goes against our philosophy of making each test independent from others. Suggestion - maybe in |
@bahmutov I know it can be done this way, but I feel like |
I hope that in the future cypress will allow us to define the behaviour. My current workaround is creating two helper commands which save and restore the local storage between tests. let LOCAL_STORAGE_MEMORY = {};
Cypress.Commands.add("saveLocalStorage", () => {
Object.keys(localStorage).forEach(key => {
LOCAL_STORAGE_MEMORY[key] = localStorage[key];
});
});
Cypress.Commands.add("restoreLocalStorage", () => {
Object.keys(LOCAL_STORAGE_MEMORY).forEach(key => {
localStorage.setItem(key, LOCAL_STORAGE_MEMORY[key]);
});
}); And then in one of my tests beforeEach(() => {
cy.restoreLocalStorage();
});
afterEach(() => {
cy.saveLocalStorage();
}); |
I have the same issue, and I think a slightly neater workaround using aliases rather than a variable to store the data from LocalStorage: cy.contains('Welcome to our site').then(() => {
cy.wrap( localStorage.getItem('currentUser') ).as('currentUser');
cy.wrap( localStorage.getItem('token') ).as('token');
}); and then restoring them in a describe('User login', function() {
beforeEach(function() {
if (this.currentUser) {
localStorage.setItem('currentUser', this.currentUser);
localStorage.setItem('token', this.token);
}
}); But I agree whitelisting the specific entries would be a better way to maintain authentication within a describe() context. |
Regarding @unrealprogrammer's approach, I have something like this: describe()
it()
it()
describe()
before()
it() Inside the The only solution I have for now is to move the |
I managed to come up with something that seems to be working for our needs. Here it is in case someone else could use it: let cachedLocalStorageAuth;
function restoreLocalStorageAuth() {
if (cachedLocalStorageAuth) {
localStorage.setItem('auth-token', cachedLocalStorageAuth);
}
}
function cacheLocalStorageAuth() {
cachedLocalStorageAuth = localStorage.getItem('auth-token');
}
Cypress.on('window:before:load', restoreLocalStorageAuth);
beforeEach(restoreLocalStorageAuth);
afterEach(cacheLocalStorageAuth); |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
"There are multiple reasons" is not very compelling. Back on topic, I think the workarounds in here are pretty helpful. Borderline good enough where I don't think Cypress should prioritize doing anything here. |
I would honestly just offer an option to "Don't reset localStorage between tests" as well. I would say, in the majority of cases (for us) we want to preserve it, and clearing it manually is literally a one liner we can add in |
@danatemple thanks for help, but your solution works for me only partially. I still receive "not-authorized" page after some time tests are running. Thank you anyway. I'm also trying workaround from @pietmichal but I got the same result. Silent sign on is called in Cypress very often and requests are often returned without token. Some of the requests contain token, but they're sent late and user is logged out. So I got test (it) where I'm logged out because of "not-authorized" but meanwhile is token sent so next test (it) is passing. I'm in dead end and it seems I need to wait to this issue fix. In Selenium is this working without any problem. "authority" is called once and returned with token which keep user signed into application. |
Thanks @brian-mann , I've been inspiring myself from this example to create my own in TypeScript. I'm setting the list of keys to ignore in my Local Storage but still manually clear it once at when Cypress start to ensure at least one authentication case. Works great for my needs. import { isArray } from 'util';
// Manually clear the localStorage before each session to ensure authentication at least once
window.localStorage.clear();
Cypress.LocalStorage.clear = (keys?: string[]) => {
const KEYS_IGNORED = [
...
];
// Specific clear
if (keys !== undefined && isArray(keys) && keys.length > 0) {
keys.forEach(key => window.localStorage.removeItem(key));
} else {
// Full clear
if (window.localStorage.length > 0) {
Object.keys(window.localStorage)
.filter(key => !KEYS_IGNORED.includes(key))
.forEach(key => window.localStorage.removeItem(key));
}
}
}; I've set this code in a custom .ts file that I import un the support folder of Cypress. |
This needs to get implemented soon as possible. super frustrating issue |
This comment has been minimized.
This comment has been minimized.
Same problem for me 😞 strange think is that it was working like charm for 3 weeks but somehow this issue popped up like 3 days ago ... |
This isn't working as expected! In fact it doesn't remove any local storage item at all. |
Hey everyone, we've outlined some work to be done to address some of the concerns of 'local storage' in this issue: #8301 It outlines a proposal for a 'session' API, to quickly summarize:
This session related data would include localStorage. 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. |
I cannot believe there isn't a proper solution for this. There I was trying out Cypress and thinking how easy it was to use and then realising I couldn't actually use it because it logs me out of the app I'm testing every time I try and run a test. Maybe they think authentication isn't really a thing? Why not just give an option not to close the browser after stopping tests or allow users to choose not to have some data removed? Update: the only workaround which I've found is to use this, which is of course incredibly dangerous:
But even then I couldn't get a test to run as it timed out because cypress wouldn't wait long enough to load the page / desired url after logging in. I've just noticed that there are 1200 + issues on this repo which is the highest I've ever seen (React has 400 - 500). Maybe something's going on at Cypress? |
this should be an option in the cypress.json :/ |
Until this is natively supported, the |
Works for me 😉 |
What a beautiful little plugin! Thanks! I ran into this problem today and was desperate for a solution. I don't understand the reasoning for why Cypress wipes localStorage between tests, it only makes sense to do that on a per-spec basis. It doesn't align at all with e2e testing either. |
Of course it won't work, it does: return clear.apply(this, arguments) Instead of: return clear.apply(this, keys) Btw, this function receives only one argument |
had to update suggested workaround as follows to make it work:
|
Thank you this saved my day! |
@abugleev thanks it worked with the whitelistkeys . |
In v12.0.0 (soon-to-be-released), we are introducing the concept of Test Isolation. There will be two modes of test isolation,
This will prevent DOM and browser state bleed over between tests. To persist DOM and browser state between a set of tests, i.e. local storage, you will be able to turn test isolation off for the run or at the suite level. Closing this issue as done and tagging for the v12.0.0 release. |
Released in This comment thread has been locked. If you are still experiencing this issue after upgrading to |
Similar to the mechanism available to whitelist cookies so that these entries will not be cleared between test
The text was updated successfully, but these errors were encountered: