【发布时间】:2018-05-22 15:09:48
【问题描述】:
我想保存/持久化/保留由 cy.request() 设置的 cookie 或 localStorage 令牌,这样我就不必使用自定义命令登录每个测试。这应该适用于存储在客户端 localStorage 中的 jwt(json Web 令牌)之类的令牌。
【问题讨论】:
我想保存/持久化/保留由 cy.request() 设置的 cookie 或 localStorage 令牌,这样我就不必使用自定义命令登录每个测试。这应该适用于存储在客户端 localStorage 中的 jwt(json Web 令牌)之类的令牌。
【问题讨论】:
要更新此线程,已经有更好的解决方案可用于保存 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
【讨论】:
来自赛普拉斯docs
对于持久性 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({
preserve: "session_id"
})
注意:在 Cypress v5.0 之前,配置键是“白名单”,而不是“保留”。
用于持久化 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)
}
}
【讨论】:
preserve 而不是 whitelist
您可以将自己的登录命令添加到 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");
});
});
【讨论】:
这是对我有用的解决方案:
Cypress.LocalStorage.clear = function (keys, ls, rs) {
return;
before(() => {
LocalStorage.clear();
Login();
})
Cypress 支持 cookie 清除控制:https://docs.cypress.io/api/cypress-api/cookies.html
【讨论】:
我不确定本地存储,但对于 cookie,我最终做了以下操作以在测试之间存储所有 cookie一次。
beforeEach(function () {
cy.getCookies().then(cookies => {
const namesOfCookies = cookies.map(c => c.name)
Cypress.Cookies.preserveOnce(...namesOfCookies)
})
})
根据文档,Cypress.Cookies.defaults 将维护此后每次测试运行的更改。在我看来,这并不理想,因为这会增加测试套件的耦合度。
我在这个赛普拉斯问题中添加了更强大的响应:https://github.com/cypress-io/cypress/issues/959#issuecomment-828077512
我知道这是一个老问题,但我想以任何一种方式分享我的解决方案,以防有人需要。
【讨论】:
为了保存一个 google token cookie,有一个库叫做
柏树社交登录。
似乎有其他 OAuth 提供者作为里程碑。
它是 cypress 团队推荐的,可以在 cypress 插件页面上找到。
https://github.com/lirantal/cypress-social-logins
此赛普拉斯库使执行第三方登录成为可能 (想想 oauth)用于 GitHub、Google 或 Facebook 等服务。
它通过将登录过程委托给 puppeteer 流程来实现 执行登录并返回应用程序的 cookie 测试,以便它们可以在持续时间内由调用赛普拉斯流程设置 测试。
【讨论】:
我可以看到使用白名单的建议。但它似乎在cypress run 期间不起作用。
分别在 before() 和 beforeEach() 中尝试了以下方法:
Cypress.Cookies.defaults({
whitelist: "token"
})
和
Cypress.Cookies.preserveOnce('token');
但似乎没有一个工作。但是在 cypress open 即 GUI 模式下,这两种方法都可以正常工作。我有什么不足的地方吗?
【讨论】: