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

时间:2018-05-22 15:09:48

标签: cypress

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

8 个答案:

答案 0 :(得分:9)

来自赛普拉斯docs

持久性Cookie :默认情况下,赛普拉斯会在每次测试前自动清除所有Cookie,以防止状态崩溃。

您可以使用赛普拉斯.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"
})

对于持久化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)
  }

}

答案 1 :(得分:4)

要更新此线程,已经有一个更好的保存cookie的解决方案(@bkucera提供);但是现在有一个解决方法,可以在测试之间保存和还原本地存储(如果需要)。我最近遇到了这个问题;并发现此解决方案有效。

此解决方案是通过使用帮助程序命令并在测试中使用它们,

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

然后在测试中

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

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

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

答案 2 :(得分:0)

以下是解决您像我这样的问题的有用链接: Preserve cookies through multiple tests

我的代码如下:

const login = () => {
    cy.visit('http://0.0.0.0:8080/#/login');
    cy.get('#username').type('username');
    cy.get('#password').type('1234password$');
    cy.get('#login-button').click();
}

describe('UI', () => {
  // beforeEach(login);
    beforeEach(() => {
        login();
        Cypress.Cookies.preserveOnce('session_id', 'remember_token');
  });

});

希望可以帮助您。

答案 3 :(得分:0)

以下是对我有用的解决方案:

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

赛普拉斯支持控制cookie清除:https://docs.cypress.io/api/cypress-api/cookies.html

答案 4 :(得分:0)

您可以向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);
    });
});

测试内部:

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

答案 5 :(得分:0)

为了保留Google令牌cookie,有一个名为 cypress-social-login
似乎还有其他OAuth提供者是一个里程碑。
这是赛普拉斯团队的推荐,可以在赛普拉斯插件页面上找到。

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

此赛普拉斯库使执行第三方登录成为可能 (请考虑使用oauth),例如GitHub,Google或Facebook。

通过将登录过程委托给伪造者流程来完成, 执行登录并返回该应用程序的cookie 测试,以便可以在持续时间内通过调用赛普拉斯流对其进行设置 测试。

答案 6 :(得分:0)

我可以看到有关使用白名单的建议。但是它似乎在cypress run期间不起作用。 分别在before()和beforeEach()中尝试以下方法:

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

Cypress.Cookies.preserveOnce('token');

但是似乎没有一个起作用。但是在cypress open(即GUI模式)下,两种方法都可以正常工作。有什么想法我会做空吗?

答案 7 :(得分:0)

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

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

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

我在这个 Cypress 问题中添加了更强大的响应:https://github.com/cypress-io/cypress/issues/959#issuecomment-828077512

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