结构化的 spec 输出

Hover 的 spec 不是一堆点击操作的平铺堆砌。确定性翻译器会把一次验证过的会话塑造成一套小型架构——本身就易读,并且随着你保存更多流程能持续生长。

翻译器输出什么

  • test.step(...) 阶段。 每个逻辑步骤(打开表单、填写凭据、验证结果)都被包裹进一个命名的 test.step,于是 Playwright 的 HTML 报告读起来是一个个阶段,而不是一串平铺的动作列表。
  • 可见性守护的交互。 每个动作都被包裹起来,先断言元素可见——UI 漂移会在约 3 秒内以一条命名断言失败,而不是等一个 30 秒的可操作性超时。
  • 弹窗 / 新标签页配对。 一个打开支付弹窗或 OAuth 标签页的点击,会连同 Playwright 所需的 Promise.all([context.waitForEvent('page'), …]) 配对一起 crystallize,后续步骤会被重新定向到新页面——replay 时不会有竞态。
  • 一份结构化 sidecar。<slug>.spec.ts 旁边,Hover 会写一份 .hover/sidecars/<slug>.json——结构化的 SpecStep[] 加上本次运行观察到的信号。它是 优化 pass 读取的机器可读记录,同时让 spec 文件本身保持干净。关于 .hover/ 下还有什么,参见 你的应用的测试知识

从重复流程生成 Page Object

当同一个前缀(一次登录、一个设置向导)在多个已保存的 spec 中反复出现时,Hover 可以把它抽取成一个共享的 Page Object 外加一个 Playwright fixture,让 selector 集中在一个文件里,而不是散落在五个文件中。新的 spec 使用这个 fixture 并调用对应方法(await loginPage.login(...)),而不是把步骤内联重复。

__vibe_tests__/
├── pages/LoginPage.ts      # 被抽取出来的 Page Object
├── fixtures.ts             # 以 fixture 形式暴露它
└── login-and-checkout.spec.ts

Hover 会替你把这些共享流程从现有 spec 中抽取出来。

依然是纯 Playwright

这里的一切都是标准的 @playwright/test——Page Object、fixture 和 test.step 都是 Playwright 自带的原语。spec 在 CI 里用 npx playwright test 运行,回路中没有 agent,也没有 Hover 运行时。