Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preserve cookies / localStorage session across tests in Cypress

I want to save/persist/preserve a cookie or localStorage token that is set by a cy.request(), so that I don't have to use a custom command to login on every test. This should work for tokens like jwt (json web tokens) that are stored in the client's localStorage.

like image 438
bkucera Avatar asked May 22 '18 15:05

bkucera


People also ask

How do you preserve localStorage between Cypress tests?

Preserving local storage between testsUse cy. saveLocalStorage() to save a snapshot of current localStorage at the end of one test, and use the cy. restoreLocalStorage() command to restore it at the beginning of another one. The usage of beforeEach and afterEach is recommended for this purpose.

How does Cypress Preserve multiple cookies?

You can use Cypress. Cookies. preserveOnce() to preserve cookies through multiple tests.

Does Cypress clear local storage between tests?

Clear data in localStorage for current domain and subdomain. Cypress automatically runs this command before each test to prevent state from being shared across tests. You shouldn't need to use this command unless you're using it to clear localStorage inside a single test.


2 Answers

To update this thread, there is already a better solution available for preserving cookies (by @bkucera); but now there is a workaround available now to save and restore local storage between the tests (in case needed). I recently faced this issue; and found this solution working.

This solution is by using helper commands and consuming them inside the tests,

Inside - cypress/support/<some_command>.js

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]);   }); }); 

Then in test,

beforeEach(() => {   cy.restoreLocalStorage(); });  afterEach(() => {   cy.saveLocalStorage(); }); 

Reference: https://github.com/cypress-io/cypress/issues/461#issuecomment-392070888

like image 66
Kondasamy Jayaraman Avatar answered Sep 18 '22 21:09

Kondasamy Jayaraman


From the Cypress docs

For persisting cookies: By default, Cypress automatically clears all cookies before each test to prevent state from building up.

You can configure specific cookies to be preserved across tests using the Cypress.Cookies api:

// now any cookie with the name 'session_id' will // not be cleared before each test runs Cypress.Cookies.defaults({   preserve: "session_id" }) 

NOTE: Before Cypress v5.0 the configuration key is "whitelist", not "preserve".

For persisting localStorage: It's not built in ATM, but you can achieve it manually right now because the method thats clear local storage is publicly exposed as Cypress.LocalStorage.clear.

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)   }  } 
like image 43
bkucera Avatar answered Sep 20 '22 21:09

bkucera