highlight.io 的 Cypress 端到端测试实战:本地运行、用例编写与 CI 集成
发布时间:2026/9/25 2:12:26来源:尧图网络
可观测性后端【免费下载链接】highlighthighlight.io: The open source, full-stack monitoring platform. Error monitoring, session replay, logging, distributed tracing, and more.项目地址https://gitcode.com/gh_mirrors/hi/highlight点击查看免费下载本篇技术指南聚焦 highlight.io 开源全栈监控平台中基于 Cypress 的浏览器端端到端测试体系覆盖本地运行命令、--spec用例隔离、测试目录与配置解析、登录/录制/CDN/SSO 四类典型用例的实现细节以及 CI 工作流集成方式。读完本文你将能够在本仓库中熟练运行、编写并维护一套验证 SDK 前端录制与后端上报链路的 Cypress 测试。快速开始一条命令跑起本地 Cypresshighlight.io 仓库在根目录 package.json 中预置了 Cypress 的 npm scripts对应关系如下Script底层命令用途yarn cy:runcypress run无头模式运行全部测试适合 CIyarn cy:run:chromecypress run --headed --browser chrome带界面、指定 Chrome 浏览器运行适合本地调试仓库明确建议本地调试优先使用yarn cy:run:chrome。--headed让 Cypress 打开真实浏览器窗口测试执行过程中你可以直观看到页面交互、网络请求面板与断言执行节奏配合 DevTools 断点排查远比无头模式高效。运行前提是本地已启动依赖服务。参照 CI 中的启动链路见下文需要先通过 docker/start-infra.sh 拉起 PostgreSQL、ClickHouse、Kafka 等基础设施再启动后端与前端 dev 服务使 cypress.config.js 中配置的baseUrl: http://localhost:3000可访问。用--spec隔离测试当只需要验证某个功能点、或某个用例反复失败需要快速复现时用--spec参数把 Cypress 限定到具体文件避免整包跑一遍浪费时间# 只跑登录用例 yarn cy:run:chrome --spec cypress/e2e/login.cy.js # 只跑客户端录制用例 yarn cy:run:chrome --spec cypress/e2e/client.cy.js--spec不仅支持单文件还支持逗号分隔与通配符。仓库 CI 中就用到了排除语法详见CI 集成一节例如cypress/e2e/*.cy.js,!cypress/e2e/sso.cy.js表示跑全部.cy.js文件但跳过 SSO 用例。测试套件目录结构仓库的 Cypress 测试集中在 cypress/ 目录下由四部分构成cypress/ ├── config 配置cypress.config.js仓库根目录 ├── e2e/ # 测试用例 │ ├── client.cy.js # 客户端录制与事件上报验证 │ ├── login.cy.js # 登录流程与遥测上报验证 │ ├── sso.cy.js # SSO 登录跨域验证 │ ├── umd.cy.js # 四种 UMD 加载方式验证 │ └── util.js # 压缩负载解压工具 ├── pages/ # 被测静态页面 │ ├── jsdelivr.html # 从 jsDelivr 加载 highlight.run │ ├── local.html # 加载本地构建产物 │ ├── unpkg.html # 从 unpkg 加载 │ └── unpkg-remote.html ├── support/ │ ├── commands.js # 自定义命令当前为模板 │ └── e2e.js # 全局加载 commands └── fixtures/ # 测试数据如 example.json其中 e2e/util.js 是测试专用的解压工具用fflate的decompressSync将前端PushPayloadCompressed请求中的 base64 压缩数据还原为 JSON供后续断言使用import { decompressSync, strFromU8 } from fflate export const decompressPushPayload (data) { const buff Uint8Array.from(atob(data), (c) c.charCodeAt(0)) return JSON.parse(strFromU8(decompressSync(buff))) }这印证了 highlight.io 前端上报会先压缩再传输而测试层负责解压还原以验证业务字段。Cypress 配置解析仓库根目录的 cypress.config.js 配置非常精简但每一行都有明确考量const { defineConfig } require(cypress) module.exports defineConfig({ e2e: { baseUrl: http://localhost:3000, pageLoadTimeout: 1200000, video: false, setupNodeEvents(on, config) { // implement node event listeners here }, }, })baseUrl被测前端地址。cy.visit(/1/buttons)之类的相对路径会基于该地址拼接无需写全 URL。pageLoadTimeout: 1200000页面加载超时被拉到 20 分钟。这是针对本仓库特殊场景的调优——如 client.cy.js 注释所说明的客户端测试可能最先执行需要等待 Vite 把 dev bundle 编译就绪等待时间可能较长因此相关用例还叠加了{ timeout: 90 * 1000 }的 90 秒等待上限。video: false关闭录制避免 CI 上产生大量视频文件。CI 中仅在失败时把cypress/videos作为 artifact 上传。setupNodeEventsNode 事件钩子占位可在此接入on(before:browser:launch)、on(task)等扩展。baseUrl同时被测试代码复用例如 client.cy.js 通过Cypress.config(baseUrl)动态拼接 fetch 探测地址避免硬编码。核心测试用例剖析--spec隔离的四种用例正好覆盖了 highlight.io 前端 SDK 最重要的四条链路逐一拆解如下。登录用例拦截 GraphQL 与 OTel 上报login.cy.js 验证输入账号密码完成登录后客户端遥测是否按预期上报。其核心手法是用cy.intercept按 operationName 动态命名 GraphQL 请求别名cy.intercept(POST, /public, (req) { req.alias req.body.operationName }) cy.intercept(POST, /v1/traces, (req) { req.alias oteltraces }) cy.intercept(POST, /v1/metrics, (req) { req.alias otelmetrics })/public是后端公共 GraphQL 入口req.alias req.body.operationName让每条 GraphQL 请求都以操作名为别名如initializeSession、PushPayloadCompressed之后便可用cy.wait(initializeSession)精确等待对应请求。登录后依次断言三类上报cy.wait(otelmetrics) .its(request.body.resourceMetrics.0.scopeMetrics.0.metrics.0) .should(have.property, name) cy.wait(oteltraces) .its(request.body.resourceSpans.0.scopeSpans.0.spans.0) .should(have.property, name) cy.wait(initializeSession) .its(request.body.variables) .should(have.property, session_secure_id) cy.wait(PushPayloadCompressed)可见测试不仅验证登录成功还验证了 OTel Metrics/Traces 上报与 Session 初始化、会话数据压缩上报链路与 highlight.io 同时接收 OTLP 与自有协议的架构互相印证。客户端录制用例验证 fetch 录制与自定义事件client.cy.js 是内容最丰富的用例验证 highlight 客户端 SDK 是否完整录制浏览器行为fetch 请求录制通过win.eval在页面上下文发起多个fetchGET/POST 组合随后解压PushPayloadCompressed的 data断言resources数组中的 Resource Timing 字段集合例如connectStartAbs、domainLookupEndAbs、transferSize、initiatorType等 19 个字段必须全部存在。会话 URL调用H.getSessionURL()并断言返回格式——前缀必须是https://app.highlight.io/1/sessions/且会话 ID 部分长度为 28排除了空会话的情况。会话详情调用H.getSessionDetails()断言url与getSessionURL()一致且时间戳参数ts在 0 到 5 之间。自定义事件调用H.track(MyTrackEvent, {foo: bar})随后在解压后的事件流中查找type 5的自定义事件分别校验Track与Performance两类事件——Track 必须携带event: MyTrackEvent和foo: barPerformance 则要求jsHeapSizeLimit、usedJSHeapSize、fps、relativeTimestamp均为有限数值。该用例充分体现了 highlight.io 端到端验证的深度不止页面能打开而是精确校验录制负载的内部结构。多 CDN UMD 加载用例umd.cy.js 用数据驱动方式覆盖 highlight 客户端的四种分发来源const cdns [unpkg, unpkg-remote, jsdelivr, local] cdns.map((source) { it(public graph requests are recorded when highlight set up from ${source}, { baseUrl: null }, () { cy.visit(./cypress/pages/${source}.html, {}) // ... }) })注意它通过{ baseUrl: null }覆盖配置中的baseUrl改为访问仓库内相对路径的静态页面对应 cypress/pages/local.html 等文件。以 local.html 为例它通过http://localhost:8877/dist/index.umd.cjs加载本地构建的 UMD 包并以backendUrl: http://localhost:8082/public、otlpEndpoint: http://localhost:4318指向本地后端验证无论从哪个 CDN 加载 SDK会话数据都能正常上报到/public。SSO 登录用例跨域断言sso.cy.js 验证 SSO 登录流程输入vadimhighlight.io邮箱后密码框[namepassword]不应出现提交后通过cy.origin(accounts.google.com, ...)进入 Google 登录域断言跳转发生随后切换vadimhighlight.run邮箱再验证一次。cy.origin是 Cypress 处理跨域跳转的标准手段也解释了为什么 CI 中要单独排除该用例——它依赖外部 Google 服务不适合在隔离网络环境中运行。CI 集成从 e2e.yml 看完整链路原文档提到通过e2e-test.yml配置 CI实际仓库中对应文件为 .github/workflows/e2e.yml包含三个 Job。其中e2e-cypress是 Cypress 主链路关键步骤依次为环境准备checkout含 submodules、Node LTSyarn 缓存、Go版本取自 backend/go.mod、Python 3.10 poetry、Doppler CLI。拉起基础设施执行docker/start-infra.sh启动 compose 集群导入 PostgreSQL 初始化 SQL后台启动后端随后yarn build:frontend构建前端并分别以 dev 模式启动highlight-run/apollo、highlight-run/client、highlight.runSDK最后用vite preview --port 3000提供被测前端。就绪探测yarn dlx wait-on -l -s 3 http://127.0.0.1:3000/index.html http://127.0.0.1:8082/health同时等待前端页面与后端健康检查通过避免竞态。执行测试yarn cy:run --spec cypress/e2e/*.cy.js,!cypress/e2e/sso.cy.js在 CI 中使用无头的cy:run而非带界面的cy:run:chrome并用--spec通配符跑全部用例但排除 SSO。联动验证Cypress 跑完后继续执行poetry run pytest -k cypress .e2e/tests 下的 Python 功能测试验证 Cypress 产生的 session 数据在后端落库正确——这是浏览器端验证 服务端数据核验的双层闭环。失败诊断任一步骤失败时工作流会 dump 启动日志、compose 容器日志并备份 PostgreSQL 与 ClickHouse 数据含 sessions 表为 artifact同时上传cypress/videos录像方便定位问题。未捕获 JS 错误默认失败绝不静默原文档特别强调Unexpected JS errors should fail tests——这是 Cypress 的默认行为。这意味着测试页面中被测应用抛出的任何未捕获异常都会直接导致当前用例失败而不是被 Cypress 忽略后继续跑出绿色但失真的结果。这一点对 highlight.io 尤为重要被测对象本身就是错误监控与 Session Replay 平台如果页面抛出的错误被测试静默吞掉就无法验证真实用户遇到问题时 SDK 是否能正确捕获并上报。默认失败策略保证只要被测应用出现未捕获 JS 错误用例即红CI 立即告警促使开发者在提交前就修掉前端异常。如需在特定场景主动放行可通过cy.on(uncaught:exception)按需处理例如第三方脚本的无关错误但仓库测试并未采用——保持默认严格行为与错误监控产品必须对异常零容忍的定位一致。调试技巧与最佳实践综合本仓库的实际用法总结以下可复用的实践本地调试用 Chrome --headedyarn cy:run:chrome能看到真实执行过程结合--spec把范围缩到最小配合 Cypress 的时间旅行回放定位断言失败点。用 operationName 动态别名拦截 GraphQL登录用例中req.alias req.body.operationName的模式可推广到任何按操作区分的 GraphQL 后端比手动逐个命名别名更可维护。超时参数按真实启动耗时设置前端 dev 模式首次编译可能超过一分钟本仓库将pageLoadTimeout提到 1200000ms并在关键等待处显式传{ timeout: 90 * 1000 }避免偶发慢启动导致的误报。断言上报负载的内部结构不要停留在请求发出了像 client.cy.js 那样解压压缩负载、校验字段集合与数值才能真正守护 SDK 的数据契约。跨域用例单独隔离依赖外部服务的用例SSO/Google应独立文件并在 CI 中用--spec排除或单独 Job 运行避免污染主链路。失败即留证CI 在失败时自动上传日志、数据库 dump 与视频本地排查时也可主动开启video: true复现。通过本地快速迭代 CI 全量回归 服务端数据核验的组合highlight.io 用 Cypress 保障了前端 SDK 从加载、会话初始化、录制上报到登录鉴权的全链路质量这套模式同样适用于任何以浏览器行为采集为核心产品的测试体系建设。赞分享可观测性后端【免费下载链接】highlighthighlight.io: The open source, full-stack monitoring platform. Error monitoring, session replay, logging, distributed tracing, and more.项目地址https://gitcode.com/gh_mirrors/hi/highlight点击查看免费下载相关推荐Kubernetes 端到端E2E测试实战指南从 kubetest 运行到测试用例编写与 CI 集成Kubernetes 端到端E2E测试实战指南从 kubetest 运行到测试用例编写与 CI 集成 端到端E2E测试是 Kubernetes 社区验开源治理文档研发协作Traefik Proxy Helm Chart监控与可观测性PrometheusGrafana完美集成指南Traefik Proxy Helm Chart监控与可观测性PrometheusGrafana完美集成指南 Traefik Proxy是一款现代化的云原生RisingWave Iceberg E2E 测试指南本地运行、测试用例编写与 CI 集成RisingWave Iceberg E2E 测试指南本地运行、测试用例编写与 CI 集成 本文围绕 RisingWave 仓库中 e2e_test/iceb数据库流处理后端数据工程上一篇【亲测免费】 推荐开源项目rtl8188eu - 解决RTL8188EU无线网卡驱动问题下一篇终极指南IbPy Python API 让你轻松接入Interactive Brokers交易系统创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网