在赛普拉斯的测试中保留cookie/localStorage会话

bku*_*era 6 cypress

我想保存/持久化/保存由cy.request()设置的cookie或localStorage令牌,这样我就不必使用自定义命令登录每个测试.这应该适用于存储在客户端localStorage中的jwt(json web tokens)之类的令牌.

bku*_*era 15

来自赛普拉斯的文档

对于持久性cookie:默认情况下,赛普拉斯会在每次测试之前自动清除所有cookie,以防止状态累积.

您可以使用Cypress.Cookies api将特定cookie列入白名单,以便在测试中保留:

// now any cookie with the name 'session_id' will
// not be cleared before each test runs
Cypress.Cookies.defaults({
  whitelist: "session_id"
})
Run Code Online (Sandbox Code Playgroud)

对于持久化localStorage:它不是内置于ATM中,但您现在可以手动实现它,因为清除本地存储的方法公开为Cypress.LocalStorage.clear.

您可以备份此方法并根据发送的密钥覆盖它.

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

}
Run Code Online (Sandbox Code Playgroud)

  • 我很抱歉新手:那么我应该在哪里包含这个方法呢?在 command.js 文件中?我该如何用它来表示添加特定的键?谢谢 (3认同)
  • 注意:对于 cookie,现在似乎是“preserve”而不是“whitelist” (2认同)

Kon*_*man 11

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]);
  });
});
Run Code Online (Sandbox Code Playgroud)

Then in test,

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

afterEach(() => {
  cy.saveLocalStorage();
});
Run Code Online (Sandbox Code Playgroud)

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


Leo*_*yan 6

这是对我有用的解决方案:

 Cypress.LocalStorage.clear = function (keys, ls, rs) {
    return;
Run Code Online (Sandbox Code Playgroud)
 before(() => {
    LocalStorage.clear();
    Login();
  })
Run Code Online (Sandbox Code Playgroud)

Cypress 支持 cookie 清除控制:https://docs.cypress.io/api/cypress-api/cookies.html


Jav*_*rea 6

您可以将自己的登录命令添加到 Cypress,并使用cypress-localstorage-commands包在测试之间保留 localStorage。

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);
    });
});
Run Code Online (Sandbox Code Playgroud)

在您的测试中:

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");
  });
});
Run Code Online (Sandbox Code Playgroud)


pga*_*mou 6

我不确定本地存储,但对于 cookie,我最终执行了以下操作以在测试之间存储所有 cookie一次

beforeEach(function () {
  cy.getCookies().then(cookies => {
    const namesOfCookies = cookies.map(c => c.name)
    Cypress.Cookies.preserveOnce(...namesOfCookies)
  })
})
Run Code Online (Sandbox Code Playgroud)

根据文档,Cypress.Cookies.defaults此后将维护每次测试运行的更改。在我看来,这并不理想,因为这会增加测试套件的耦合。

我在此赛普拉斯问题中添加了更强有力的响应:https://github.com/cypress-io/cypress/issues/959#issuecomment-828077512

我知道这是一个老问题,但想以任何方式分享我的解决方案,以防有人需要它。