我正在测试一个集成 Gmail、Slack、Dropbox 等的 Web 应用程序。我正在尝试使用 Cypress.io 编写端到端测试,以验证身份验证流程是否正常工作。 Cypress 限制我在应用程序域之外导航,并给我一个跨源错误。赛普拉斯文档表示,测试不应涉及在应用程序之外进行导航。但测试我的应用程序的全部目的是确保这些外部身份验证流程正常运行。
文档还说你可以添加 “chromeWebSecurity”:假 到 cypress.json 文件来绕过此限制。我已经这样做了,但仍然遇到跨源错误(这是我问题的核心。我最好能绕过这个限制)。
我尝试了 cypress 的单点登录示例。 https://github.com/cypress-io/cypress-example-recipes#logging-in---单点登录 我无法让它工作,而且代码比我认为必要的多得多。
我已经在github上评论了这个帖子,但还没有回复。
完整错误消息:
Error: CypressError: Cypress detected a cross origin error happened
on page load:
> Blocked a frame with origin "https://www.example.com" from
accessing
a cross-origin frame.
Before the page load, you were bound to the origin policy:
> https://example.com
A cross origin error happens when your application navigates to a new
superdomain which does not match the origin policy above.
This typically happens in one of three ways:
1. You clicked an <a> that routed you outside of your application
2. You submitted a form and your server redirected you outside of your
application
3. You used a javascript redirect to a page outside of your application
Cypress does not allow you to change superdomains within a single test.
You may need to restructure some of your test code to avoid this
problem.
Alternatively you can also disable Chrome Web Security which will turn
off this restriction by setting { chromeWebSecurity: false } in your
'cypress.json' file.
https://on.cypress.io/cross-origin-violation
在我的“cypress.json”文件中设置
{ "chromeWebSecurity": false }
对我有用
您应该存根处理该问题的函数,并断言请求包含必要的键值对。如果没有有关此测试目的的更多信息,很难给出具体建议。听起来你想要一个“间谍”(测试替身类型)。
这里是间谍文档:https://docs.cypress.io/guides/guides/stubs-spies-and-clocks.html#Stubs
您将需要使用一个库来处理 gmail 的读取。
cy.task
可用于从外部库调用 JavaScript。这篇 Medium 文章很好地介绍了如何做到这一点。
中型文章:https://medium.com/@levz0r/how-to-poll-a-gmail-inbox-in-cypress-io-a4286cfdb888
在测试中使用 GMail UI 以避免测试不稳定(所有 UI 测试都有不稳定),以及 Gmail 应用程序可能需要更新测试的 UI 更改。与 UI 相比,gmail-tester 使用的后端方法不太可能随着时间的推移而改变。您还可以避免 CORS 错误。
如果必须,请将
chromeWebSecurity: false
添加到 cypress.json
配置文件中。请务必将其添加到花括号内。该文件中应该只有一组大括号。
注意: 不能简单地使用
cy.visit(<diffSuperDomain>)
;有一个未解决的问题。显然,在 cypress 中这是一个非常困难的改变。
一种潜在的解决方法是每次测试仅使用一个超级域。如果您将
chromeWebSecurity:
设置为 false
并且每个测试只有一个域(it
块),它应该可以工作。小心,因为它会让你面临级联失败,因为一个测试将依赖于下一个测试。希望他们尽快解决这个问题。
https://docs.cypress.io/guides/guides/web-security.html#Disabling-Web-Security
自 Cypress 12 起,您的测试可以使用
origin
命令在多个域中运行。来自官方博客的示例(但固定格式):
it('navigates', () => {
cy.visit('/')
cy.get('h1').contains('My Homepage')
cy.origin('www.acme.com', () => {
cy.visit('/history/founder')
cy.get('h1').contains('About our Founder, Marvin Acme') // 👍
})
})
在该博客条目中还提供了如何使用它在另一个域进行身份验证的示例。我在 Chrome 和 Firefox 上使用 Keycloak 效果很好。
注意:事实上,这是在 Cypress 9.6 中引入的,但从 Cypress 12 开始,您不再需要在
"experimentalSessionAndOrigin": true
中设置 cypress.json
。 Cypress 12 中也删除了此配置选项。
针对这些常见情况,有一些简单的解决方法: 不要单击测试中导航到应用程序外部的
<a>
链接。无论如何,这可能不值得测试。您应该问自己:点击并转到另一个应用程序有什么意义?您可能只关心 href 属性是否符合您的期望。所以对此做出断言。您可以在我们的“选项卡处理和链接”示例配方中看到更多关于测试锚链接的策略。
您正在测试使用单点登录 (SSO) 的页面。在这种情况下,您的 Web 服务器可能会在超级域之间重定向您,因此您会收到此错误消息。您可以通过使用
cy.request()
自己手动处理会话来解决此重定向问题。
如果您发现自己陷入困境并且无法解决这些问题,您可以在 cypress.json 文件中进行设置。但在这样做之前,你应该真正理解并阅读这里的推理。
// cypress.json
{
"chromeWebSecurity": false
}