在 Cypress 中,在测试前在 localStorage 中设置一个令牌

Posted

技术标签:

【中文标题】在 Cypress 中,在测试前在 localStorage 中设置一个令牌【英文标题】:In Cypress, set a token in localStorage before test 【发布时间】:2018-11-22 01:29:01 【问题描述】:

我想登录并在客户端上设置一个localStorage 令牌(特别是jwt

按照赛普拉斯文档中的建议,我如何使用 cy.request 完成此操作?

【问题讨论】:

【参考方案1】:

这是一个添加命令cy.login() 的示例,您可以在任何赛普拉斯测试中使用该命令,或放入beforeEach 挂钩。

Cypress.Commands.add('login', () =>  
  cy.request(
    method: 'POST',
    url: 'http://localhost:3000/api/users/login',
    body: 
      user: 
        email: 'jake@jake.jake',
        password: 'jakejake',
      
    
  )
  .then((resp) => 
    window.localStorage.setItem('jwt', resp.body.user.token)
  )

)

然后在你的测试中:

beforeEach(() => 
  cy.login()
)

【讨论】:

这可行,但是当我访问应用程序 URL 时,该值会被覆盖。我的应用似乎无法读取创建的本地存储。 设置localStorage前需要导航到你的页面 我还建议使用 cy.window()(参见 Cypress 文档)来获取活动页面的窗口对象:cy.window().then(win => win.localStorage.setItem('jwt', resp.body.user.token)) cy.window().then(win => win.localStorage.setItem('jwt', resp.body.user.token)) 工作正常,谢谢@guillaumepn 完美答案。【参考方案2】:

我在这方面花了这么多时间,最后我可以有把握地得出结论,它永远不会适用于 OAuth 请求。

它可能适用于本地服务器,但在您获取令牌进行身份验证时不起作用。

【讨论】:

大声笑 xD - 没有什么是不可能的 您可以请求在 OAuth 提供者上检索您需要的数据。【参考方案3】:

另外,您还可以使用 cypress-localstorage-commands 包在测试之间持久化 localStorage,这样登录请求只会发出一次:

在 support/commands.js 中:

import "cypress-localstorage-commands";

Cypress.Commands.add('login', () =>  
  cy.request(
    method: 'POST',
    url: 'http://localhost:3000/api/users/login',
    body: 
      user: 
        email: 'jake@jake.jake',
        password: 'jakejake',
      
    
  )
  .its('body')
  .then(body => 
    cy.setLocalStorage("jwt", body.user.token);
  )
);

然后,在你的测试中:

before(() => 
  cy.login();
  cy.saveLocalStorage();
);

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

【讨论】:

只对我使用你指定的包。谢谢 根据 npm 上的文档,您应该清除 before() 中的存储,然后在 beforeEach 中进行恢复并访问,然后 afterEach 保存本地存储。 Note the usage of beforeEach and afterEach for preserving localStorage between all tests. Also clearLocalStorageSnapshot is used in the before statement to avoid possible conflicts with other test files preserving localStorage.【参考方案4】:

我已经使用 bkuceras answer 有一段时间了。最近,我在整个测试过程中测试多个角色/登录时遇到了一个问题。基本上发生的事情是我以管理员身份登录并进行一次测试,然后我以非管理员身份登录并进行第二次测试。第一个测试运行良好并结束(cypress 清除本地存储),但是当第二个测试开始时,仍然有一些 xhr 请求从第一个测试运行。这些 xhr 请求不再看到触发我的应用程序看到 401 未授权错误并清除本地存储的令牌(包括我设置的非管理员令牌)。现在第二次测试失败了,因为本地存储中没有该非管理员令牌。

最终我的解决方案是在测试之前预取令牌,然后在访问的 onBeforeLoad 函数中设置令牌。这可确保令牌在您的访问命令之前不会被任何竞争条件清除。

cy.visit('/app', 
    onBeforeLoad: function (window) 
        window.localStorage.setItem('token', myToken);
    
)

确实这是一个非常独特的边缘案例,但希望它可以帮助某人,因为我花了很多时间寻找这个解决方案。

【讨论】:

可能比大多数解决方案更清洁。您甚至可以将其变成始终设置项目的自定义命令。 虽然不是特定于所提出的问题,但这对我有帮助,因为我正在使用 cy.visit。谢谢!【参考方案5】:

我认为该主题的标题应该更新。 JWT 代币是本次讨论的重点!

主要问题是关于 JWT 令牌,但总的来说,所有现代应用程序都在使用 OIDC Microsoft article - v2-protocols-oidc / ADAL,这是一个非常棘手的情况,仅通过 API 调用生成令牌来获取访问权限。 我发现here 并将使用我的应用程序进行检查。但请确保您在 JS 方面很出色,并且得到了 DevTeam 的良好帮助;)

【讨论】:

以上是关于在 Cypress 中,在测试前在 localStorage 中设置一个令牌的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Cypress 测试中连接到 SFTP 服务器?

如何从 cypress 测试中隐藏电子邮件和密码?

如何在 Cypress 中访问 baseURL 的值

PHPUnit/Cypress 在 Laravel 中测试 2 个数据库

如何在 Windows 上记录我的 Cypress 测试?

前端自动化测试框Cypress入门