
BrowserSkill 回归用例体系用 manifest 与合成 fixture 固化真实浏览器几何回归缺陷【免费下载链接】BrowserSkillLet AI agents use your real, logged-in browser without interrupting your work. CLI extension for browser automation across any shell-capable AI agent.项目地址: https://gitcode.com/GitHub_Trending/br/BrowserSkill回归用例是自动化测试体系中最难沉淀的一环真实用户反馈的缺陷往往依赖特定的页面结构、嵌套 iframe、滚动状态与缩放组合一旦缺少可复现的最小样例修复便无从验证。BrowserSkill 在evals/browser/cases/regression/目录下建立了一套“一个用户反馈坏例 一个独立目录”的回归用例组织规范配套 scaffold 脚手架命令、case manifest 声明式断言和合成 fixture并以内置的真实 Chrome 几何测试与 CLI smoke 双重验证回归是否彻底修复。本文以该目录为骨架深入剖析回归用例的目录规范、清单结构与运行方式并以snapshot-coordinatesDOMSnapshot 布局单位回归和oopif-scrollbarsOOPIF 占用滚动条回归两个真实案例展示 BrowserSkill 如何把 iframe 几何与坐标投影类缺陷固化为一套可重复执行的验证资产。一、回归用例目录的职责与组织规范regression/README.md 开篇即定义了该目录的核心职责每一个用户反馈的坏例badcase都应拥有自己独立的目录目录内包含三件套manifest*.case.json描述用例的声明式清单包括提示词、覆盖操作、断言与 smoke 步骤合成 fixture*.fixture.mjs一段由服务端动态渲染的最小复现页面专门构造触发缺陷的 DOM 结构README描述症状symptom、最小复现minimal reproduction、期望行为expected behavior、源码参考source reference与修复方式fix。这种“一坏例一目录”的隔离策略保证了每个回归缺陷都能独立复现、独立调试、独立评审而不会相互污染。同时README 明确划出了敏感信息红线Never commit credentials, cookies, HAR files, production HTML, private screenshots, or proprietary assets.即回归用例中严禁提交凭证、Cookie、HAR 抓包文件、生产环境 HTML、私有截图或专有资产。这一点对浏览器自动化项目尤为重要——fixture 必须全部由合成数据构造绝不携带真实用户会话信息。从实际用例看oopif-scrollbars.case.json 与 snapshot-coordinates.case.json 均通过合成 HTML 与回环主机名构造跨源拓扑完全符合这一要求。二、从零创建回归用例scaffold 脚手架命令目录规范要求每个用例必须同时具备 manifest、fixture 与 README手工创建容易遗漏字段或写错目录结构。为此仓库提供了 scaffold 命令一键生成起点pnpm eval:browser scaffold case-id --title ... --source issue-or-prcase-id用例 ID必须为小写 kebab-case如oopif-scrollbars由 scaffold-case.mjs 中的ID_PATTERN /^[a-z0-9](?:-[a-z0-9])*$/强制校验--title用例标题--source来源标注通常填 issue 或 PR 引用用于追踪缺陷出处。从 scaffold-case.mjs 的源码可以看到脚手架的产物结构它在cases/suite/id下创建目录生成一个默认 manifest包含$schema、schemaVersion: 1、id、title、order、suite、tags、fixture.startPath、中英文prompts、coverage、assertions与smoke.steps并生成对应的 fixture 模板标记默认为CASE-ID大写、连字符转下划线。若目录已存在脚手架会直接报错避免覆盖既有用例。三、case manifest 清单结构剖析case manifest 是回归用例的“声明式核心”。其字段约束由 case-loader.mjs 中的validateCaseManifest完整实现允许的顶层字段包括$schema、schemaVersion、id、title、order、suite、tags、seed、source、fixture、prompts、coverage、assertions、smoke其余未知字段会被直接判为错误。关键字段的语义与约束如下字段含义校验要点schemaVersion清单结构版本必须等于1id用例唯一标识小写 kebab-case且全局不允许重复fixture.startPathfixture 的起始 URL 路径必须以/开头与 fixture 中注册的 route 对应prompts驱动 Agent 的提示词必须同时提供en与zh-CN两种语言coverage覆盖的操作清单必须来自已知操作集合如session.start、session.stop、page.navigate、inspect.observe不允许重复assertions三层断言分site页面/站点侧、responseAgent 回复侧、adapter适配器/会话侧三类smoke最小冒烟步骤smoke.steps必须为数组动作需在受支持的工作流动作集合内其中assertions的三层设计值得展开site 断言验证页面侧状态每个断言需要type如geometry.ready、geometry.scrollbars、可选的where过滤器与minCount正整数。例如 oopif-scrollbars 用例要求data.root为真的geometry.ready事件至少出现 1 次且data.vertical与data.horizontal同时为真的geometry.scrollbars事件至少出现 2 次response 断言验证 Agent 最终回复文本通过includes检查是否包含标记字符串如OOPIF-SCROLLBARS、GEOMETRY-195adapter 断言验证适配器行为通过key如sessionStopped确认浏览器会话已被正确关闭。在 case-loader.mjs 中加载后的 manifest 还会被normalizeCase归一化将fixture.startPath提升为startPath、三类断言与 smoke 步骤分别挂载为siteAssertions、responseAssertions、adapterAssertions、smokeSteps并以Object.freeze冻结保证后续执行阶段不会意外篡改清单。所有.case.json按 suite、order、id 排序后统一返回任何清单的 JSON 解析失败、字段缺失或 ID 重复都会导致整个加载过程抛错从源头拦截“带病”用例进入执行流程。四、实战案例一snapshot-coordinatesDOMSnapshot 布局单位回归 #1954.1 症状与根因snapshot-coordinates/README.md 记录了该回归的来源为 PR #195核心问题是DOMSnapshot 的 bounds 与文档滚动偏移量保留的是 Blink 布局单位layout units而不是 CSS 像素。在设备缩放device scale或浏览器缩放zoom下若直接将它们当作 CSS 像素处理位置与尺寸都会在进入 iframe 投影projection或视口裁剪clipping之前就发生偏差——也就是说坐标系换算的第一公里就走错了方向。4.2 fixture 设计snapshot-coordinates.fixture.mjs 构造了一个刻意复杂的页面拓扑一个滚动过的根页面body宽 2000px、高 2400px加载后scrollTo(80, 240)一个同进程same-processiframe#same自身也发生滚动scrollTo(40, 100)一个OOPIF#cross通过把 URL hostname 在127.0.0.1与localhost之间互换来强制跨进程每个 iframe 内再嵌套一层#nestediframe各 owner 均带有border: 6px、padding: 8px与transform: scale(1.25)nested 为scale(0.8)同时引入边框、内边距与 CSS 变换三个干扰因素。fixture 脚本在双requestAnimationFrame后置位data.geometryReady并上报geometry.ready事件确保断言只在其布局完全稳定后执行。注意其 URL 默认会为 OOPIF 设置scrollbarsnone这是为了把“布局单位换算”问题与既有的“OOPIF 滚动条宽度投影”问题隔离开——后者由专门的 oopif-scrollbars 用例覆盖。若想在同一 fixture 中恢复经典滚动条形态可附加classic-scrollbars查询参数。4.3 数值回归测试几何数值断言运行在真实 Chrome 之上命令如下BSK_GEOMETRY_CHROME/path/to/chrome pnpm --filter browser-skill/extension exec vitest run \ src/tools/__tests__/snapshot-coordinates.browser.test.ts该测试源码见 snapshot-coordinates.browser.test.ts通过describe.skipIf(!process.env.BSK_GEOMETRY_CHROME)实现按需启用普通单元测试运行时不设置BSK_GEOMETRY_CHROME用例自动跳过只有显式传入本地 Chrome 可执行文件路径时才真正执行且不需要下载浏览器或引入新的包依赖。测试用it.each覆盖5 种设备缩放/浏览器缩放组合{deviceScale: 1, zoom: 1}、{deviceScale: 0.8, zoom: 1}、{deviceScale: 1, zoom: 1.25}、{deviceScale: 2, zoom: 1}、{deviceScale: 2, zoom: 0.8}并将snapshot-coordinates与oopif-scrollbars两个 fixture 组合成参数化矩阵。其验证逻辑关键点在于独立 oracle测试内嵌一段独立 DOM 表达式用getBoundingClientRect()计算各[data-geometry-probe]探针的 border box以及各 iframe owner 的坐标与 scalescale rect.width / frame.offsetWidth再用独立的clip函数做视口裁剪——期望值完全由 DOM 原生几何推导不依赖生产代码的换算逻辑避免“用待测实现验证待测实现”精度阈值生产 capture 得到的本地矩形与顶层矩形与独立 DOM border box 相比允许的布局舍入误差最多 2 个 CSS 像素读取次数同时校验每个目标只读取一次布局指标layout metrics防止性能退化拓扑自检测试会显式验证请求的浏览器 zoom 与 OOPIF 拓扑是否真正生效若环境不支持则会直接失败而不是静默地测试了一个错误的配置。测试自行启动并清理独立的 headless Chrome profile保证每次运行环境一致。若想手动查看其使用方式fixture 依赖的浏览器启动封装位于 snapshot-coordinates/chrome.mjs。4.4 smoke 的边界除了数值回归该用例还提供 CLI 冒烟入口BSK_AUTO_UPDATEoff pnpm eval:browser smoke --case snapshot-coordinates --bsk ./target/debug/bsk但 README 特别强调smoke 并不能证明坐标精度——CLI 的观察结果不会暴露原始矩形数据。smoke 只负责验证 fixture 就绪与可观察语义标记GEOMETRY-195被正确报告、会话正常关闭数值断言必须由上述几何测试承担。这种“分层验证”的定位划分正是该回归体系的可取之处。五、实战案例二oopif-scrollbarsOOPIF 占用滚动条回归5.1 症状与根因oopif-scrollbars/README.md 描述的缺陷更加微妙iframe 的 content quad内容四边形包含其子视口滚动条所占的空间而 CDP 的Page.getLayoutMetrics().cssLayoutViewport却排除这部分空间。若把后者直接映射到整个 quad 上位置与尺寸就会被拉伸。正确的处理原则是缩放比例必须由完整的 target-local 视口含滚动条空间决定而可见视口仍须在每个 OOPIF 边界处裁剪内容并约束 target-local 动作点。也就是说scale 用“总空间”算clip 用“可见区域”切二者缺一不可。5.2 fixture 与查询参数oopif-scrollbars.fixture.mjs 为此构造了跨两个嵌套 OOPIF 的回环主机名交替拓扑根页面通过127.0.0.1/localhost互换 hostname 加载外层跨源 frame外层 frame 再以同样的方式加载内层 frame形成两层 OOPIF。页面结构包含滚动不同页面不同scrollTo偏移边框border: 6px、内边距padding: 8px缩放过的 iframe owner外层scale(1.2)、内层scale(0.8)一个部分被裁剪的按钮#edgeposition: fixed; right: -20px; bottom: -15px一个完全被裁剪的按钮#outside位于视口calc(100% 2px)之外自定义滚动条占用不同宽高::-webkit-scrollbar宽 17px、高 11px。fixture 通过scrollbars查询参数控制滚动条形态参数值含义both默认垂直 水平滚动条均占位vertical仅垂直滚动条占位水平隐藏horizontal仅水平滚动条占位垂直隐藏none双轴均不显示滚动条脚本在加载后上报geometry.scrollbars通过innerWidth document.documentElement.clientWidth等比较判定实际滚动条是否占位与geometry.ready并监听[data-geometry-probe]按钮的点击事件把点击结果回传给browserEval——这正是真实点击验证的数据通道。5.3 浏览器测试与 smokeoopif-scrollbars 与 snapshot-coordinates共用同一个浏览器 runnersnapshot-coordinates.browser.test.ts。在 5 种缩放/缩放组合之外还额外以deviceScale: 1, zoom: 1遍历vertical、horizontal、none三种单轴/无滚动条形态。该测试覆盖的能力包括验证真实的 OOPIF 目标与滚动条占用尺寸用独立 DOM 矩形与裁剪逻辑对比 snapshot 与 live 几何派发真实 root-target 点击并验证事件确实落到了预期的 frame/按钮如#edge部分裁剪仍可点击、#outside应被拒绝拒绝完全被裁剪的控件并校验同一目标的 snapshot 测量复用覆盖滚动条在垂直/水平/双向占位时的几何一致性。runner 会创建并清理隔离的浏览器 profile且与数值测试同样采用 opt-in 机制未设置BSK_GEOMETRY_CHROME时在普通单元运行中自动跳过。CLI 冒烟入口为BSK_AUTO_UPDATEoff pnpm eval:browser smoke --case oopif-scrollbars --bsk ./target/debug/bsk冒烟断言仅验证两个嵌套 frame 均有占用滚动条、OOPIF-SCROLLBARS标记被观察到、会话被关闭数值几何与真实点击断言由上面的浏览器测试承担smoke 单独运行不能替代数值回归。六、运行几何回归测试的环境与前提综合两个用例运行这套几何回归需要满足以下条件缺一不可Node.js 22数值回归测试的运行环境要求本地 Chrome 可执行文件通过BSK_GEOMETRY_CHROME/path/to/chrome指定。路径必须真实可用因为测试会显式校验 zoom 与 OOPIF 拓扑不支持的环境会直接失败而非悄悄跳过包管理器 pnpm命令以pnpm --filter browser-skill/extension exec vitest run ...形式在扩展包内执行测试CLI smoke 需要已构建的二进制--bsk ./target/debug/bsk指向 Rust 侧构建产物debug 构建即可且以BSK_AUTO_UPDATEoff关闭自动更新保证冒烟过程可复现。几何模块的底层实现可参考 apps/extension/src/tools/frame-geometry.ts节点几何解析与 apps/extension/src/browser-driver/frame-graph.tsCDP frame 图管理。数值测试正是以这些模块为被测对象用独立 oracle 校验其输出。七、回归用例体系的最佳实践小结从regression/README.md与两个真实用例可以提炼出这套体系沉淀下来的几条关键准则一个坏例一个目录manifest、fixture、README 三件套齐备缺陷可独立复现与评审合成数据拒绝真实资产凭证、Cookie、HAR、生产 HTML、私有截图一律禁止入库fixture 全部自建跨源拓扑用回环主机名交替实现声明式清单 三层断言site页面事件、responseAgent 回复标记、adapter会话关闭分别验证不同层次smoke提供最小工作流冒烟数值断言与 smoke 分层smoke 只证明“能跑通、能观察到”坐标精度必须由真实 Chrome 几何测试证明——这是避免“看起来绿了其实坏了”的关键问题隔离与组合覆盖snapshot-coordinates 默认关掉 OOPIF 滚动条scrollbarsnone以隔离布局单位换算问题滚动条投影问题交由classic-scrollbars与独立的 oopif-scrollbars 用例覆盖同时用参数化矩阵把 5 种缩放组合 × 2 个 fixture × 单轴/无滚动条形态一次性铺开opt-in 运行真实浏览器测试仅在显式设置BSK_GEOMETRY_CHROME时启用普通 CI/单元运行不被拖慢又不至于让回归静默漏测。对于浏览器自动化类项目几何与坐标换算是最容易在“真实浏览器”与“理论模型”之间产生偏差的领域。BrowserSkill 通过这套回归用例体系把用户反馈的坏例固化为可复现、可断言的工程资产——既有声明式清单支撑自动化评估又有真实 Chrome 数值测试兜底坐标精度为后续 Agent 在复杂多 iframe 页面中的精准交互提供了可验证的回归防线。【免费下载链接】BrowserSkillLet AI agents use your real, logged-in browser without interrupting your work. CLI extension for browser automation across any shell-capable AI agent.项目地址: https://gitcode.com/GitHub_Trending/br/BrowserSkill创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考