赛普拉斯 XHR 存根忽略 ajax 使用 fetch 执行的请求
Cypress XHR stubbing ignores ajax requests performed with fetch
重要信息
这里最初的问题不是直接关于在赛普拉斯中缺乏对 the fetch api 的支持,而是我最初在这里发布的问题的原因。我已经编辑了问题的标题并在此处添加了这个序言。下面这一段是题目原文内容:
原问题
Cypress 文档中充满了示例,您可以在其中为特定的 Web 请求设置别名,然后您可以指示 Cypress 等待它。例如,this one:
cy.route('POST', '/login').as('postLogin')
cy.get('input[name=username]').type('jane.lae')
cy.get('input[name=password]').type('password123{enter}')
// we should always explicitly wait for
// the response for this POST to come back
// so our tests are not potentially flaky or brittle
cy.wait('@postLogin')
问题是我正在尝试在我的应用程序测试中使用这种确切的技术,但我需要等待不是针对托管应用程序的同一服务器发出的请求。因此,我假设我可以输入后端端点的完整 URL,这样 cy.route
就不会添加 baseUrl
,这是托管前端应用程序的主机。
// The following URL points to a backend rails app
// The frontend app I'm testing with cypress is at http://localhost:8080
cy.route('POST', 'http:/localhost:3000/session').as('postLogin')
// ... fill login form
cy.wait('@postLogin')
// The test never reaches this point
但是,当我 运行 我的测试时,我超时了,因为 cypress 从未意识到请求已执行,它会继续等待直到超时。结果是,当我在 cypress 运行ning 的浏览器中检查左侧栏上的测试脚本时,路由具有我设置的显式主机,不仅是路径,而且测试仍在等待此请求发生,它说它永远不会发生。当我检查浏览器开发工具的网络选项卡时,我可以看到请求发生了。我可以在终端中看到我的后端应用程序 运行ning,它确实被登录请求击中了。此外,我可以在我的前端应用程序 运行ning in cypress 浏览器 session 中看到,用户已成功登录并且应用程序在请求后被重定向到预期页面。
问题是:我可以让 cypress 知道 cross-origin 请求,以便它可以等待它们吗?如果是,怎么做?
更新:
存根路由也不会被 cypress 捕获,我不能等待它们,也不能阻止它们发生,因为存根请求是预期的。
原来这与跨源请求有关。我开始意识到这一点,方法是让应用假设后端在同一个域中,并在不在模拟路由中指定主机的情况下编写测试。我有同样的行为。然后我意识到 Cypress 应该在浏览器左侧栏的 运行 测试脚本中显示任何 XHR 请求。它没有将此请求显示为 "XHR" 或 "XHR STUB",即使请求正在发生。所以我意识到我不是在使用浏览器的 XHR 接口来发出 ajax 请求,而是在赛普拉斯的 github 回购协议中 fetch instead. And after some searching I found that this is an issue with Cypress, that assumes all ajax requests are done via XHR. I found an issue 关于这个,到今天仍然没有解决:(
这是 a comment in the issue mentioned above 我暂时使用的解决方法:
// Add this to cypress/support/commands.js
Cypress.on("window:before:load", win => {
win.fetch = null;
});
重要信息
这里最初的问题不是直接关于在赛普拉斯中缺乏对 the fetch api 的支持,而是我最初在这里发布的问题的原因。我已经编辑了问题的标题并在此处添加了这个序言。下面这一段是题目原文内容:
原问题
Cypress 文档中充满了示例,您可以在其中为特定的 Web 请求设置别名,然后您可以指示 Cypress 等待它。例如,this one:
cy.route('POST', '/login').as('postLogin')
cy.get('input[name=username]').type('jane.lae')
cy.get('input[name=password]').type('password123{enter}')
// we should always explicitly wait for
// the response for this POST to come back
// so our tests are not potentially flaky or brittle
cy.wait('@postLogin')
问题是我正在尝试在我的应用程序测试中使用这种确切的技术,但我需要等待不是针对托管应用程序的同一服务器发出的请求。因此,我假设我可以输入后端端点的完整 URL,这样 cy.route
就不会添加 baseUrl
,这是托管前端应用程序的主机。
// The following URL points to a backend rails app
// The frontend app I'm testing with cypress is at http://localhost:8080
cy.route('POST', 'http:/localhost:3000/session').as('postLogin')
// ... fill login form
cy.wait('@postLogin')
// The test never reaches this point
但是,当我 运行 我的测试时,我超时了,因为 cypress 从未意识到请求已执行,它会继续等待直到超时。结果是,当我在 cypress 运行ning 的浏览器中检查左侧栏上的测试脚本时,路由具有我设置的显式主机,不仅是路径,而且测试仍在等待此请求发生,它说它永远不会发生。当我检查浏览器开发工具的网络选项卡时,我可以看到请求发生了。我可以在终端中看到我的后端应用程序 运行ning,它确实被登录请求击中了。此外,我可以在我的前端应用程序 运行ning in cypress 浏览器 session 中看到,用户已成功登录并且应用程序在请求后被重定向到预期页面。
问题是:我可以让 cypress 知道 cross-origin 请求,以便它可以等待它们吗?如果是,怎么做?
更新:
存根路由也不会被 cypress 捕获,我不能等待它们,也不能阻止它们发生,因为存根请求是预期的。
原来这与跨源请求有关。我开始意识到这一点,方法是让应用假设后端在同一个域中,并在不在模拟路由中指定主机的情况下编写测试。我有同样的行为。然后我意识到 Cypress 应该在浏览器左侧栏的 运行 测试脚本中显示任何 XHR 请求。它没有将此请求显示为 "XHR" 或 "XHR STUB",即使请求正在发生。所以我意识到我不是在使用浏览器的 XHR 接口来发出 ajax 请求,而是在赛普拉斯的 github 回购协议中 fetch instead. And after some searching I found that this is an issue with Cypress, that assumes all ajax requests are done via XHR. I found an issue 关于这个,到今天仍然没有解决:(
这是 a comment in the issue mentioned above 我暂时使用的解决方法:
// Add this to cypress/support/commands.js
Cypress.on("window:before:load", win => {
win.fetch = null;
});