Preserve cookies / localStorage session across tests in Cypress

前端 未结 6 661
抹茶落季
抹茶落季 2020-12-30 21:58

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 ever

相关标签:
6条回答
  • 2020-12-30 22:04

    You can add your own login command to Cypress, and use the cypress-localstorage-commands package to persist localStorage between tests.

    In support/commands:

    import "cypress-localstorage-commands";
    
    Cypress.Commands.add('loginAs', (UserEmail, UserPwd) => {
      cy.request({
        method: 'POST',
        url: "/loginWithToken",
        body: {
          user: {
            email: UserEmail,
            password: UserPwd,
          }
        }
      })
        .its('body')
        .then((body) => {
          cy.setLocalStorage("accessToken", body.accessToken);
          cy.setLocalStorage("refreshToken", body.refreshToken);
        });
    });
    

    Inside your tests:

    describe("when user FOO is logged in", ()=> {
      before(() => {
        cy.loginAs("foo@foo.com", "fooPassword");
        cy.saveLocalStorage();
      });
    
      beforeEach(() => {
        cy.visit("/your-private-page");
        cy.restoreLocalStorage();
      });
    
      it('should exist accessToken in localStorage', () => {
        cy.getLocalStorage("accessToken").should("exist");
      });
    
      it('should exist refreshToken in localStorage', () => {
        cy.getLocalStorage("refreshToken").should("exist");
      });
    });
    
    0 讨论(0)
  • 2020-12-30 22:09

    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)
      }
    
    }
    
    0 讨论(0)
  • 2020-12-30 22:10

    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

    0 讨论(0)
  • 2020-12-30 22:13

    Here is the solution that worked for me:

     Cypress.LocalStorage.clear = function (keys, ls, rs) {
        return;
    
     before(() => {
        LocalStorage.clear();
        Login();
      })
    

    Control of cookie clearing is supported by Cypress: https://docs.cypress.io/api/cypress-api/cookies.html

    0 讨论(0)
  • 2020-12-30 22:21

    For keeping a google token cookie, there is a library called cypress-social-login.
    It seems to have other OAuth providers as a milestone.
    It's recommended by the cypress team and can be found on the cypress plugin page.

    https://github.com/lirantal/cypress-social-logins

    This Cypress library makes it possible to perform third-party logins (think oauth) for services such as GitHub, Google or Facebook.

    It does so by delegating the login process to a puppeteer flow that performs the login and returns the cookies for the application under test so they can be set by the calling Cypress flow for the duration of the test.

    0 讨论(0)
  • 2020-12-30 22:27

    I can see suggestions to use whitelist. But it does not seem to work during cypress run. Tried below methods in before() and beforeEach() respectively:

    Cypress.Cookies.defaults({
      whitelist: "token"
    })
    

    and

    Cypress.Cookies.preserveOnce('token');
    

    But none seemed to work. But either method working fine while cypress open i.e. GUI mode. Any ideas where I am coming short?

    0 讨论(0)
提交回复
热议问题