项目简介
Cypress 是一个专为现代 Web 构建的前端测试工具,支持端到端、组件和集成测试。它提供实时重载、时间旅行调试和自动等待功能,简化测试流程并生成可靠结果。
README 预览
\n \n \n \n \n \n \n \n\n\n Documentation |\n Changelog |\n Roadmap\n\n\n\n The web has evolved. Finally, testing has too.\n\n\n\n Fast, easy and reliable testing for anything that runs in a browser.\n\n\n Join us, we're hiring.\n\n\n\n \n \n \n \n \n \n \n \n \n\n\n## What is Cypress?\n\n\n \n \n \n\n\n## Installing\n\n[](https://badge.fury.io/js/cypress)\n\nInstall Cypress for Mac, Linux, or Windows, then [get started](https://on.cypress.io/install).\n\n```bash\nnpm install cypress --save-dev\n```\nor\n```bash\nyarn add cypress --dev\n```\nor\n```bash\npnpm add cypress --save-dev\n```\n\n\n\n## Contributing\n\n[](https://cloud.cypress.io/projects/ypt4pf/runs)\n[](https://circleci.com/gh/cypress-io/cypress/tree/develop) - `develop` branch\n\nPlease see our [Contributing Guideline](./CONTRIBUTING.md) which explains repo organization, linting, testing, and other steps.\n\n## License\n\n[](https://github.com/cypress-io/cypress/blob/develop/LICENSE)\n\nThis project is licensed under the terms of the [MIT license](/LICENSE).\n\n## Badges\n\nConfigure a badge for your project's README to show your test status or test count in the [Cypress Cloud](https://www.cypress.io/cloud).\n\n[](https://cloud.cypress.io/projects/ypt4pf/runs)\n\n[](https://cloud.cypress.io/projects/ypt4pf/runs)\n\nOr let the world know your project is using Cypress with the badge below.\n\n[](https://www.cypress.io/)\n\n```\n[](https://www.cypress.io/)\n```\n
常见问题 (5)
故障排除如何修复 Cypress 16 的 clientCertificates 导致 Chrome 在 open 模式下弹出证书选择器或在 run 模式下挂起的问题?
在 Cypress 16 中,Chrome 默认使用原生 HTTP/2 网络路径,该路径不会为 mTLS 提供 clientCertificates。通过在 cypress.config.ts 中设置 forceHttp1: true 来强制使用旧版 HTTP/1 网络协议栈:
import { defineConfig } from 'cypress'
export default defineConfig({
forceHttp1: true,
clientCertificates: [
{\n url: 'https://test.com',
ca: [],
certs: [
{\n cert: 'certs/client.crt',
key: 'certs/client.key',
},
],
},
],
})
或者,使用 CLI 标志运行 Cypress:
cypress run --browser chrome --force-http1
Firefox 和其他非 Chromium 浏览器将继续使用旧版网络协议栈。如果此变通方法不可行,请降级到 Cypress 15.21.1。永久性修复正在相关的 Cypress PR 中进行跟踪,该 PR 用于在浏览器网络路径上提供客户端证书。
故障排除如何修复在 Chrome 中,Cypress 16 的 `cy.wait()` 对带有 302 重定向的 `fetch` POST 请求返回 undefined 响应的问题?
这是 Cypress 16.1.0 的一个原生网络/CDP Fetch 缺陷,影响在服务器返回 302 时以 redirect: 'follow' 发起的同源 fetch() POST 请求。拦截会在响应阶段等待 Fetch.requestPaused 事件,但始终收不到,30 秒后失败并报错 Timed out waiting for CDP Fetch response pause;尽管浏览器成功跟随了重定向,interception.response 仍为 undefined。
解决方法:在 cypress.config.js 中启用 forceHttp1,以使用 Cypress 15 所采用的旧版代理路径:
const { defineConfig } = require('cypress')
module.exports = defineConfig({
forceHttp1: true,
})
对于 ESM 配置:
import { defineConfig } from 'cypress'
export default defineConfig({
forceHttp1: true,
})
更改配置后请重启 Cypress。启用此选项后,cy.wait('@alias') 无需 30 秒延迟即可正常解析,并按预期返回 POST 跳点的 302 状态码和 Location 响应头。普通 GET 请求不受影响;该问题仅出现在 Cypress 16 的 Chrome 原生网络路径上发生重定向的 fetch POST 请求中。
故障排除如何修复在 `cy.request()` 轮换会话 cookie 后 Cypress 发送旧 cookie 的问题?
这是 Cypress 15.20.0+ 的一个回归问题:cy.request() 会更新浏览器中的 cookie,但不会更新 Cypress 服务端的 cookie jar,因此下一次 AUT frame 的文档导航会发送之前的过期 cookie。XHR/fetch 请求不受影响。
变通方法:将登录请求包裹在 cy.session() 中,该方法会清除/重置 cookie jar:
beforeEach(() => {
cy.session('login', () => {
cy.request('POST', '/login')
})
cy.visit('/account')
})
或者,降级到 Cypress 15.19.x。永久修复方案是升级到包含 PR "fix: keep the cookie jar in sync when cookies are set outside the proxy." 的版本。
故障排除如何修复使用 cy.server() 时出现的 CypressError: sinon.js was not found in the remote iframe's window 错误?
当 Cypress 没有通过 cy.visit() 直接加载当前页面时会发生这种情况,通常是在点击了普通链接之后。在对 XHR 进行打桩(stub)之前,请先使用 Cypress 加载目标 URL:
cy.visit('/your-page')
cy.server().route('POST', /users\.json/, {})
如果 POST 发生在页面加载期间,请在访问页面之前定义路由:
cy.server()
cy.route('POST', /users\.json/, {})
cy.visit('/your-page')
不要依赖在上一个测试中通过点击普通 <a> 链接执行的导航;要么直接调用 cy.visit(targetUrl),要么在使用 cy.server() 之前通过 Cypress 重新加载页面。跨域页面无法通过这种方式进行打桩。
在现代版本的 Cypress 中,请将 cy.server()/cy.route() 替换为:
cy.intercept('POST', '**/users.json', {})
cy.visit('/your-page')故障排除如何修复在 Cypress 中于 .within() 内使用 cy.contains() 时出现的 "TypeError: Cannot read properties of undefined (reading 'selector')" 错误?
这是一个 Cypress 的 bug(在 15.18.1 中复现):在 .within() 内部,每次重试时都会重新查询 subject,如果它在 cy.contains() 的第一次尝试时解析为空集合,getOptions.withinSubject 就会一直保持为 undefined。随后错误消息构建器 getPhrase() 在访问 undefined 的 el.selector 时崩溃,而该错误会中止重试——于是测试在几毫秒内就失败了,而不是等待 defaultCommandTimeout(典型触发场景:列表在重新获取数据/加载状态期间短暂卸载)。解决方法:将 cy.contains() 替换为 cy.get() 加上文本断言,因为 .within() 内部的 cy.get() 可以正常重试:
// 不稳定 —— 抛出 TypeError 而不是重试
cy.get('#group').within(() => {
cy.contains('new');
});
// 可靠 —— 一直重试,直到 subject 重新挂载并包含该文本
cy.get('#group').within(() => {
cy.get('p').should('contain.text', 'new');
});或者,在执行
contains 之前加一道保护,确保 subject 在其第一次尝试时已经存在:cy.get('#group').within(() => {
cy.get('p').should('exist'); // 等待加载状态结束
cy.contains('new');
});永久修复:等补丁合入后升级 Cypress——拟议的修复方案会让
getPhrase 在 withinSubject 为 undefined 时回退到 selector(或一个通用短语),这样 cy.contains() 就能像 cy.get() 一样持续重试。