ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Cypress Studio 本地开发指南:基于 CYPRESS_LOCAL_STUDIO_PATH 的本地联调、类型同步与 Cypress-in-Cypress 测试

Cypress Studio 本地开发指南:基于 CYPRESS_LOCAL_STUDIO_PATH 的本地联调、类型同步与 Cypress-in-Cypress 测试 Cypress Studio 本地开发指南基于 CYPRESS_LOCAL_STUDIO_PATH 的本地联调、类型同步与 Cypress-in-Cypress 测试【免费下载链接】cypressFast, easy and reliable testing for anything that runs in a browser.项目地址: https://gitcode.com/GitHub_Trending/cy/cypressCypress 的 Studio 是随 Cypress Cloud 一起交付的云功能生产环境中其 bundle 在运行时从 Cloud 拉取而非内置于本地发行版。本篇指南基于仓库内的 guides/studio-development.md 完整梳理 Studio 的本地开发工作流如何把cypress-services仓库中本地构建的 Studio bundle 接入cypress仓库运行、如何通过yarn gulp downloadStudioTypes同步 Studio 提供的 TypeScript 类型以及如何用 Cypress-in-CypressCIC加云请求 mock 的方式对 Studio 做端到端测试。读完你可以独立完成 Studio 的本地联调并理解服务端StudioLifecycleManager在本地模式下跳过的校验与热重载机制。Studio 的交付模型Cloud 运行时下发 bundle理解本地开发流程的前提是理解 Studio 的交付模型。在生产环境中Studio bundle 不是打包进 Cypress 发行版的而是应用启动时从 Cypress Cloud 获取的。对应到源码这一流程由 StudioLifecycleManager 驱动先调用postStudioSession向 Cloud 申请一个 Studio 会话拿到studioUrl与protocolUrl见 StudioLifecycleManager.ts#L195-L198用ensureStudioBundle按 URL 中的 hash 下载并缓存 bundle随后读取 bundle 内server/index.js并通过 SHA-256 与 manifest 中的期望值比对来校验完整性StudioLifecycleManager.ts#L241-L256把脚本交给 StudioManager 的setup()加载为 Studio server并准备 Protocol 管理器供 AI 能力使用StudioLifecycleManager.ts#L258-L308。正因为 bundle 来自 Cloud本地开发时就需要一个开关让服务端改用本地构建的 Studio——这正是CYPRESS_LOCAL_STUDIO_PATH的作用。本地联调流程运行在本地构建的 Studio 上第一步准备 cypress-services 中的本地 Studio 构建Studio 的产品代码不在这个仓库而在cypress-services仓库中克隆该仓库需要 Cypress 组织成员权限。准备工作如下克隆cypress-services仓库在仓库根目录执行yarn在app/packages/studio目录执行yarn watch开启构建监听如果你同时要针对本地运行的cypress-services后端开发先在cypress-services根目录执行yarn dev。yarn watch的产物目录即cypress-services/app/packages/studio/dist/development它是下一步环境变量要指向的路径。第二步设置环境变量环境变量取值说明CYPRESS_INTERNAL_ENV指定 Cloud 环境staging、production或指向本地cypress-services实例的developmentCYPRESS_LOCAL_STUDIO_PATH指向本地 Studio 构建目录即cypress-services/app/packages/studio/dist/development一旦设置将覆盖override来自 Cloud 的 bundle需要注意CYPRESS_INTERNAL_ENV是保留变量CLI 在启动时会校验其取值合法性非法值会直接报出 “The environment variable with the reserved name CYPRESS_INTERNAL_ENV is set” 错误而非staging/production之外的合法取值也会打印警告提示校验逻辑见 cli/lib/cli.ts#L444-L462行为快照见 cli/test/lib/snapshots/cli.spec.ts.snap。在 gulp 侧该变量未设置时默认按production处理scripts/gulp/tasks/gulpCloudDeliveredTypes.ts#L1。第三步在 cypress 仓库中启动并进入 Studio在cypress仓库执行yarn和yarn cypress:open在应用中登录 Cypress Cloud使用一个已启用 Studio 的项目例如 Cypress (staging) 或 Cypress Internal Org 下为该项目开启了studio-ai特性的项目打开一个包含 E2E 测试的项目从某条测试上使用 “Add Commands to Test” 进入 Studio。本地模式的行为差异源码视角CYPRESS_LOCAL_STUDIO_PATH设置后服务端行为有几处关键差异都可在源码中验证跳过 bundle 下载与完整性校验。createStudioManager中若该变量已设置则直接取studioPath process.env.CYPRESS_LOCAL_STUDIO_PATH、studioHash local、manifest {}不再走postStudioSession/ensureStudioBundle分支StudioLifecycleManager.ts#L203-L233StudioManager.setup()里传给 Studio server 的verifyHash回调也会直接返回true注释明确写道 “If we are running locally, we dont need to verify the signature”studio.ts#L41-L51。热重载本地 Studio 代码。setupWatcher会用 chokidar 监听CYPRESS_LOCAL_STUDIO_PATH/server/index.js的变化一旦检测到修改awaitWriteFinish: true先destroy()旧的 StudioManager再用相同参数重建并打印Studio manager reloadedStudioLifecycleManager.ts#L347-L400。这就是指南所说 “无需重启应用即可修改本地 Studio 代码”的机制同时本地模式下 studio-ready 监听器不会被清空以便重载后再次回调StudioLifecycleManager.ts#L335-L340。绕过错误上报。指南原文说明设置CYPRESS_LOCAL_STUDIO_PATH或直接从本地克隆运行应用时错误上报error reporting会被绕过错误改为输出到浏览器或 Node 控制台方便本地调试时直接看到堆栈。同步 Studio 类型到代码库Studio bundle 同时提供了app与server两个方向的类型定义Cypress 代码库需要把它们纳入来做类型检查。指南给出的命令是yarn gulp downloadStudioTypes若希望类型来自本地cypress-services仓库而不是 Cloud则加上环境变量CYPRESS_LOCAL_STUDIO_PATHpath-to-cypress-services/app/packages/studio/dist/development-directory yarn gulp downloadStudioTypes从实现看scripts/gulp/tasks/gulpCloudDeliveredTypes.ts#L100-L112该任务的行为是未设置CYPRESS_LOCAL_STUDIO_PATH时调用postStudioSession使用固定演示项目ypt4pf拿到studioUrl再通过ensureStudioBundle把 bundle 下载到系统临时目录tmpdir/cypress/studio/hashhash 从 URL 末段解析见 getBundlePath设置了该变量时跳过网络请求直接从本地目录拷贝类型文件类型文件映射createTypeMappingsbundle 内源文件拷贝目标app/types.tspackages/app/src/studio/studio-app-types.tsserver/types.tspackages/types/src/studio/studio-server-types.ts同一文件中的downloadPromptTypes任务采用完全相同的机制服务于cy-prompt对应环境变量CYPRESS_LOCAL_CY_PROMPT_PATH映射三个类型文件到packages/app、packages/driver、packages/types下的 prompt 目录可见这是 Cloud 下发 bundle 的类型同步的通用做法gulpCloudDeliveredTypes.ts#L114-L126。测试 Studio单元/组件测试支持云 Studio 且位于cypressmonorepo 中的代码例如上文提到的StudioLifecycleManager、StudioManager其单元与组件测试和仓库其余代码保持一致的风格与运行方式具体细节可参考本仓库的 CONTRIBUTING.md。位于cypress-servicesmonorepo 的 Studio 代码则有自己的伴随单元/组件测试随代码存放于该仓库内。Cypress-in-CypresslaunchStudio 辅助函数用 Cypress 测试 Studio 的入口辅助函数位于 packages/app/cypress/e2e/studio/helper.ts。其中launchStudio按文档描述完成四步实现见 helper.ts#L27-L66加载项目——默认是studiofixture 项目projectName studio导航到目标 spec——默认specName.cy.js进入 Studio可以是已有测试点击 runnable 上的launch-studio按钮也可以通过createNewTestFromSuite/createNewTestFromSpecHeader参数从套件或 spec 头部 “新建测试” 进入等待 Studio 模式下的测试运行结束。默认参数之外helper 还提供cliArgs、shouldLogin、afterLaunch钩子以及loadProjectAndRunSpec、inputNewTestName、incrementCounter等配套函数典型用法见 packages/app/cypress/e2e/studio/studio-ui.cy.ts。这些 CIC 测试默认消费的是Cloud 提供的 Studio bundle。studiofixture 项目使用 canary 性质的 projectId从而能拿到最新的 Cloud Studio 构建——当前该项目的 cypress.config.js 中projectId为n69px6与下文 mock URL 中的前缀一致。如果你希望 CIC 测试改用本地 Studio 构建把process.env.CYPRESS_LOCAL_STUDIO_PATH设为本地 studio 构建目录即可Studio 的启用开关位于 packages/frontend-shared/cypress/e2e/e2ePluginSetup.ts。Mock 云交互cy.mockNodeCloudRequest要真正触发 Studio AI需要 Cloud 侧的可用性接口。测试中通过 mock Node 端发出的 Cloud 请求来模拟例如声明 “该项目的 testgen 已启用”cy.mockNodeCloudRequest({ url: /studio/testgen/n69px6/enabled, method: get, body: { enabled: true }, })该命令定义在 packages/frontend-shared/cypress/support/e2e.ts#L657最终走到 e2e 插件任务的__internal_mockNodeCloudRequest它用 nock 拦截https://cloud.cypress.io的对应 method URL 请求并返回 200 与指定 bodye2ePluginSetup.ts#L489-L501。Mock AI 输出固定 generate 结果为保证每次运行 AI 调用结果一致测试同样模拟生成接口const aiOutput cy.get(\button\).should(\have.text\, \Increment\) cy.mockNodeCloudRequest({ url: /studio/testgen/n69px6/generate, method: post, body: { recommendations: [{ content: aiOutput }] }, })需要强调文档中给出的结论上面两个 helper 拦截的是Node 侧的请求因此这些 CIC 测试仍然真实覆盖了浏览器与 Node 之间的接口只是把 “Node → Cloud” 这一段替换成了确定性的桩。Mock Protocol 全量快照cy.mockStudioFullSnapshot还有一个特殊问题在 Cypress-in-Cypress 的内层 Cypress 中真实的 ProtocolCDP 协议无法正常工作。从源码看__internal_openProject会把process.env.CYPRESS_LOCAL_PROTOCOL_PATH指向一个空操作的 dummy protocole2ePluginSetup.ts#L438-L440dummy 文件为packages/frontend-shared/cypress/fixtures/dummy-protocol.js。由此需要人工构造一个“将发给 AI 的 CDP 全量快照”来替代真实采集即cy.mockStudioFullSnapshot({ id: 1, nodeType: 1, nodeName: div, localName: div, nodeValue: div, children: [], shadowRoots: [], })其实现是把快照 JSON 写入环境变量CYPRESS_IN_CYPRESS_MOCK_FULL_SNAPSHOTe2ePluginSetup.ts#L481-L488命令挂载点在 packages/frontend-shared/cypress/support/e2e.ts#L656。此外若需要模拟 Cloud 的流式响应当前仅 Studio AI 交互使用 SSE 流插件还提供__internal_mockNodeCloudStreamingRequest它会以text/event-stream内容类型回放event: chunk/event: end事件流e2ePluginSetup.ts#L502-L530。小结目标关键手段源码/配置佐证本地运行 Studio 构建设置CYPRESS_LOCAL_STUDIO_PATH指向dist/developmentyarn cypress:openStudioLifecycleManager.ts#L229-L233跳过 bundle 校验、热重载本地模式下verifyHash恒真、chokidar 监听server/index.jsstudio.ts#L41-L51、StudioLifecycleManager.ts#L379-L399同步 app/server 类型yarn gulp downloadStudioTypes可带CYPRESS_LOCAL_STUDIO_PATH走本地gulpCloudDeliveredTypes.ts#L100-L112CIC 进入 StudiolaunchStudiohelper studiofixture 项目projectIdn69px6helper.ts、cypress.config.js固定 AI 行为cy.mockNodeCloudRequest/cy.mockNodeCloudStreamingRequest/cy.mockStudioFullSnapshote2ePluginSetup.ts#L481-L530以上流程以当前仓库源码为准其中cypress-services仓库相关步骤克隆、yarn watch、yarn dev依赖该私有仓库的实际目录结构若其内部结构有调整CYPRESS_LOCAL_STUDIO_PATH的指向路径需相应修改但cypress仓库侧的消费逻辑路径直连、跳过校验、热重载、类型映射不受影响。【免费下载链接】cypressFast, easy and reliable testing for anything that runs in a browser.项目地址: https://gitcode.com/GitHub_Trending/cy/cypress创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表