先说结论:我造这个工具,不是因为「让 AI 点网页」很酷,而是因为测试沉淀不下来这件事很痛。
脚本写得出来,但过几个月回头看,仓库里躺着一堆 test-login-2.spec.ts、fix-tmp.spec.ts,没人说得清哪条还在用、哪条早就失效、哪条当初为什么那么写。脚本是代码,而我们要的其实是资产:能看懂、能复用、能交接、改版之后还活着。
这篇把「为什么这么设计」摊开讲,包括代价,也包括几个被打脸之后才补上的地方。
在 README 里我给项目写下的定位是三句话:
这三条一定,后面几乎每个选择都变成了推论:只要「AI 每次都得参与」,你就没有确定性;只要「什么都交给云」,你就把内网环境和数据主权交出去了。
1)确定性回放,而不是每次让模型点一遍。
换来:保存下来的步骤由 Playwright 原样执行,日常回归不调模型、Token 消耗为 0,失败可复现、结果可对比。
代价:脚本自身的稳定性成了天花板 —— 定位器写歪了,回放一定红,没人替你兜(这也是我后来做「测试友好 rule」的原因)。
2)断言失败不做 AI 自愈。
定位器失效可以自愈(元素挪了位置照样点得到,可一键采纳回写),但断言失败一律保留证据。理由很硬:给动作换定位是修工具,给断言换目标就是把缺陷改成通过。
代价:失败要人来判断是脚本问题还是产品问题,工具不下结论。
3)登录只录一次。
录制一次登录态(Cookie + localStorage)供生成与回放复用,不必每条用例都从登录开始跑。
代价:登录态有生命周期,过期要重录;多账号要维护多份配置。
4)复杂组件用「语义动作」,而不是硬点。
Ant Design / Element(element-ui · element-plus)/ Vant / MUI 的下拉、日期、级联这些控件,交给插件做语义动作(选值、设日期、勾选),插件按组件库变体分发 —— 专治「点了但没选上」这种假成功。
代价:插件和预设要维护,项目要关联预设插件才会注入。这确实是一篇讲组件插件的文章能写一整篇的原因。
5)本地桌面端 + SQLite,不做 SaaS。
换来:数据不出本机、能连内网系统、零部署、装完就能跑(安装包内置 Node,浏览器用系统 Chrome)。
代价:协作只能靠导出 .testcase 文件交换,所以我后来把「用例即文件」这条路铺得很实。
6)语义化定位器 + 优先级阶梯。
定位从 data-testid → role → label → placeholder → text → alt → title → css → xpath 这套顺序里挑,抗改版能力完全不一样。
代价:这套优先级要生效,业务代码得先给锚点。所以配套做了让 agent 顺手留 testid 的规则文件 —— 测试友好不是测试单方面的事。

7)用例是可导出的文件,不是锁在库里的记录。
.testcase 能导出、能进 Git、能被编程 agent 按技能包直接生成;含上传动作的用例还能连文件一起打包跨项目带走。
代价:要维护 schema、技能包和导入校验 —— 枚举拼错直接 400,这种「严格」是刻意留的。

8)先确认计划,再执行。
不乱点:先出一份预拆分计划(测试意图、前置条件、数据约束、验收目标与必验项),确认后才在真实浏览器里逐步执行。
代价:多一步交互。但换回来的是「该测什么」这个判断权还在工程师手上。

1)模型真的会打转。 生成过程里出现过同工具同参数反复调用的现象,于是补了空转保护:同工具同参数第 4 次警告、第 6 次挂起求助、累计 9 次终止;还有周期性重复的环绕检测(周期 2–4 反复 3 轮判定)。细节上必须区分 —— 只观察不改状态的动作不计入,否则模型多看几次页面就被误杀;「求助」也不能重置累计,否则能无限续跑。
2)上下文膨胀是必然的。 截图、页面快照、接口响应全堆在对话里,几轮就爆。于是有了状态槽 + 版本替代(新快照/新截图到来时,同槽旧消息原地降级成一行占位)、工作记忆的字符预算、以及省略内容按需回读。
3)唯一数据「填了 A、断言引用 B」是真实灾难。 生成阶段真的出现过:输入写了 test829401,断言期望值算出来是 test442434 —— 两串数字永远不可能相等,用例必红,而且看起来像产品缺陷。现在这是硬规则:同一次运行里同名变量保持一致,填写与断言引用同一个变量。
4)不是所有动作都能靠 AI 兜底。 上传、滚动、断言被明确排除在通用自愈之外 —— 上传和滚动的语义一改,验收证据就不成立。所以技能文档里专门写了一节「上传、滚动与作用域」,不允许 agent 自由发挥。
5)平台差异是真坑。 最新版本修的正是这个:Windows 上 Hyper-V / WSL2 / Docker 会随机保留一段 TCP 端口,默认的 4123 一旦落在保留段里后端就起不来,而界面只显示一句笼统的「Failed to fetch」。现在改成启动时从 4123 往后探测可用端口(最多 100 个),后端起不来时直接给原因和日志位置。

2026-09-07 第一次提交 → 2026-09-24 发布 v0.1.7,73 次提交、7 个版本。版本内容基本是被现实推着走的顺序:v0.1.3 加应用内更新器;v0.1.6 桌面端导出改系统原生「另存为」、生成日志按界面语言渲染;v0.1.7 修 Windows 保留端口导致的启动失败。
这些都不算「功能」,但它们是工具能不能被长期用下去的分水岭。

raw 动作当前跳过,想塞自定义代码进步骤里不生效;我把三条边界划得挺硬(不做通用助手、不做云平台、AI 只进两个环节),代价也认了。想问问同行:
评论区聊聊,也欢迎直接来项目里提 issue。
参考: