Cypress localStorage commands
Extends Cypress' cy commands with localStorage methods. Allows preserving localStorage between tests and disabling localStorage.
The problems
- You want to preserve localStorage between Cypress tests.
- You want to disable localStorage to check error handling.
This solution
This solution allows you to use all browser localStorage methods through Cypress commands, and preserve it between tests. It also allows to simulate that localStorage is disabled in the browser.
Installation
This module is distributed via npm which is bundled with node and should be installed as one of your project's devDependencies:
npm i --save-dev cypress-localstorage-commands
Usage
cypress-localstorage-commands
extends Cypress' cy command.
Add this line to your project's cypress/support/commands.js
:
import "cypress-localstorage-commands"
You can now use all next commands:
Commands
cy.saveLocalStorage()
Saves current localStorage values into an internal "snapshot".
cy.restoreLocalStorage()
Restores localStorage to previously "snapshot" saved values.
cy.clearLocalStorageSnapshot()
Clears localStorage "snapshot" values, so previously saved values are cleaned.
cy.getLocalStorage(item)
Gets localStorage item. Equivalent to localStorage.getItem
in browser.
item
(String): Item to get from localStorage
.
cy.setLocalStorage(item, value)
Sets localStorage item. Equivalent to localStorage.setItem
in browser.
item
(String): Item to set value.value
(String): Value to be set.
cy.removeLocalStorage(item)
Removes localStorage item. Equivalent to localStorage.removeItem
in browser.
item
(String): Item to be removed.
cy.disableLocalStorage(options)
Disables localStorage. It produces localStorage methods to throw errors.
options
(Object): Options to use when disabling localStorage
.
withError
(Error): If provided, invocations to localStorage
methods will throw this error.
Preserving local storage between tests
Use 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.
Examples
Cookies button example
Next example shows how this package can be used to test a "cookies button" (which theorically sets a flag into localStorage
and can be clicked only once)
describe("Accept cookies button", () => {
const COOKIES_BUTTON = "#accept-cookies";
before(() => {
cy.clearLocalStorageSnapshot();
});
beforeEach(() => {
cy.restoreLocalStorage();
cy.visit("/");
});
afterEach(() => {
cy.saveLocalStorage();
});
it("should be visible", () => {
cy.get(COOKIES_BUTTON).should("be.visible");
});
it("should not be visible after clicked", () => {
cy.get(COOKIES_BUTTON).click();
cy.get(COOKIES_BUTTON).should("not.be.visible");
});
it("should not be visible after reloading", () => {
cy.get(COOKIES_BUTTON).should("not.be.visible");
});
});
Note the usage of beforeEach
and afterEach
for preserving localStorage
between all tests. Also cy.clearLocalStorageSnapshot
is used in the before
statement to avoid possible conflicts with other test files preserving localStorage.
localStorage assertions
Based on the previous example, assertions could be added to check values of localStorage
:
describe("localStorage cookies-accepted item", () => {
beforeEach(() => {
cy.restoreLocalStorage();
cy.visit("/");
});
afterEach(() => {
cy.saveLocalStorage();
});
it("should be null first time page is visited", () => {
cy.getLocalStorage("cookies-accepted").should("equal", null);
});
it("should be true after clicking cookies button", () => {
cy.get("#accept-cookies").click();
cy.getLocalStorage("cookies-accepted").should("equal", "true");
});
it("should be true after reloading", () => {
cy.getLocalStorage("cookies-accepted").then(cookiesAccepted => {
expect(cookiesAccepted).to.equal("true");
});
});
});
Disabling localStorage
Use cy.disableLocalStorage()
to simulate that localStorage
is disabled, producing that any invocation to localStorage.setItem
, localStorage.getItem
, localStorage.removeItem
or localStorage.clear
will throw an error. As MDN docs recommend, "developers should make sure to always catch possible exceptions from setItem()". This command allows to test that possible exceptions are handled correctly.
Note that:
- Only pages loaded after calling this command will have
localStorage
disabled, so always use cy.reload
or cy.visit
after executing it. - The
localStorage
only remains disabled for all pages loaded during the current test. If you want to disable it for multiple tests, execute it in all of them, or in a beforeEach
statement. - If any of the other plugin commands (except
clearLocalStorageSnapshot
) is executed while localStorage
is disabled, it will do nothing but producing a Cypress log as: "localStorage.setItem is disabled"
Examples
Disabling localStorage in a single test
Based on previous "Accept cookies button" example, next tests could be added:
const LOCALSTORAGE_DISABLED_WARNING = "#localstorage-disabled-warning";
const LOCALSTORAGE_ERROR = "#localstorage-error";
it("should still be visible when reloading if localStorage is disabled", () => {
cy.disableLocalStorage();
cy.reload();
cy.get(COOKIES_BUTTON).should("be.visible");
});
it("should display warning if localStorage is disabled", () => {
cy.disableLocalStorage();
cy.reload();
cy.get(LOCALSTORAGE_DISABLED_WARNING).should("be.visible");
});
it("should display localStorage error message", () => {
cy.disableLocalStorage();
cy.reload();
cy.get(LOCALSTORAGE_ERROR).should("have.text", "Error");
});
Disabling localStorage in multiple tests
describe("when localStorage is disabled", () => {
beforeEach(() => {
cy.disableLocalStorage({
withError: new Error("Disabled by cypress-localstorage-commands"),
});
cy.visit("/");
});
it("should display localStorage warning", () => {
cy.get("#localstorage-disabled-warning").should("be.visible");
});
it("should display localStorage error message", () => {
cy.get("#localstorage-error").should("have.text", "Disabled by cypress-localstorage-commands");
});
it("should display accept-cookies button disabled", () => {
cy.get("#accept-cookies").should("be.disabled");
});
});
Usage with TypeScript
For those writing TypesScript tests in Cypress, this package includes TypeScript declarations.
Add "cypress-localstorage-commands" to the types
property of the tsconfig.json
file:
{
"compilerOptions": {
"types": ["cypress", "cypress-localstorage-commands"]
}
}
Or reference the package in the files using it:
Contributing
Contributors are welcome.
Please read the contributing guidelines and code of conduct.
License
MIT, see LICENSE for details.