Nighttime Possum Meandering

    cypress-localstorage-commands
    TypeScript icon, indicating that this package has built-in type declarations

    2.2.1 • Public • Published

    Build status Coverage Status Quality Gate Mutation testing status

    Renovate Last commit Last release

    NPM downloads License

    Cypress localStorage commands

    Extends Cypress' cy commands with localStorage methods. Allows preserving localStorage between tests and spec files, and disabling localStorage.

    The problems

    • You want to preserve localStorage between Cypress tests.
    • You want to preserve localStorage between Cypress spec files.
    • 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 and spec files. 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

    Installing commands

    cypress-localstorage-commands extends Cypress' cy commands.

    At the top of your Cypress' support file (usually cypress/support/e2e.js for e2e testing type):

    import "cypress-localstorage-commands";

    Read Cypress configuration docs for further info.

    Installing commands in Cypress <10.0

    Add this line to your project's cypress/support/index.js:

    import "cypress-localstorage-commands"

    Installing Node events

    In order to support preserving localStorage across Cypress spec files, the plugin's Node events must be installed also. Otherwise, localStorage will be preserved only across tests in the same spec file.

    In the cypress.config.js file:

    module.exports = {
      e2e: {
        setupNodeEvents(on, config) {
          require("cypress-localstorage-commands/plugin")(on, config);
          return config;
        },
      },
    };
    Installing Node events in Cypress <10.0

    In the cypress/plugins/index.js file:

    module.exports = (on, config) => {
      require("cypress-localstorage-commands/plugin")(on, config);
      return config;
    };

    Usage

    Commands

    cy.saveLocalStorage([snapshotName])

    Saves current localStorage values into an internal "snapshot".

    • snapshotName (String): Optionally, a snapshotName can be provided, and then data from localStorage will be saved into a snapshot with that name. So, multiple snapshots can be stored.

    cy.restoreLocalStorage([snapshotName])

    Restores localStorage to previously "snapshot" saved values. __

    • snapshotName (String): Optional. If provided, the localStorage will be restored using data from that specific snapshot.

    cy.clearLocalStorageSnapshot([snapshotName])

    Clears localStorage "snapshot" values, so previously saved values are cleaned.

    • snapshotName (String): Optional. If provided, only data from that specific snapshot will be cleared.

    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.

    When the plugin's Node events are installed, the cy.restoreLocalStorage() command will be able to restore the localStorage snapshots saved in other spec files. Otherwise, snapshots are completely cleared between spec files.

    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 spec 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");
        });
      });
    });

    Named snapshots

    Next example shows how named snapshots can be used to storage different states of localStorage and restore one or another depending of the test:

    describe("Accept cookies button", () => {
      const COOKIES_BUTTON = "#accept-cookies";
    
      before(() => {
        cy.clearLocalStorageSnapshot();
      });
    
      it("should be visible", () => {
        cy.visit("/");
        cy.get(COOKIES_BUTTON).should("be.visible");
        cy.saveLocalStorage("cookies-not-accepted");
      });
    
      it("should not exist after clicked", () => {
        cy.get(COOKIES_BUTTON).click();
        cy.get(COOKIES_BUTTON).should("not.exist");
        cy.saveLocalStorage("cookies-accepted");
      });
    
      it("should be visible when cookies are not accepted", () => {
        cy.restoreLocalStorage("cookies-not-accepted");
        cy.visit("/");
        cy.get(COOKIES_BUTTON).should("be.visible");
      });
    
      it("should not exist when cookies are accepted", () => {
        cy.restoreLocalStorage("cookies-accepted");
        cy.visit("/");
        cy.get(COOKIES_BUTTON).should("not.exist");
      });
    });

    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";
    
    //... should not be visible after clicked
    
    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");
    });
    
    // ...should not be visible after reloading

    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:

    /// <reference types="cypress-localstorage-commands" />

    Contributing

    Contributors are welcome. Please read the contributing guidelines and code of conduct.

    License

    MIT, see LICENSE for details.

    Install

    npm i cypress-localstorage-commands

    DownloadsWeekly Downloads

    271,445

    Version

    2.2.1

    License

    MIT

    Unpacked Size

    26.7 kB

    Total Files

    11

    Last publish

    Collaborators

    • javierbrea