Files
proxycast/docs/aiprompts/playwright-e2e.md
T
2026-04-02 20:36:21 +08:00

22 KiB

Playwright MCP 续测与 E2E

这份文档回答什么

本文件说明 AI Agent 在 Lime 中如何继续做 GUI 交互验证,主要回答:

  • 什么情况下应该进入 Playwright MCP,而不是只跑本地测试
  • 如何复用现有浏览器标签页和页面状态
  • GUI 续测前最少要做哪些准备
  • 出现 bridge 缺口、mock fallback、控制台报错时该怎么判断

它是 GUI 续测手册,不是新的本地 Playwright 测试文件模板。

什么时候先读

遇到以下任一情况时,先读本文件:

  • 用户说“继续测试”“继续复现”“继续用 Playwright MCP 验证”
  • 需要复用当前浏览器标签页和已有页面状态
  • 需要排查浏览器模式下的 DevBridge、mock fallback、控制台报错
  • 已经跑过最小 GUI smoke,接下来要做真实页面交互验证

使用边界

  • 优先使用 Playwright MCP 做交互验证,不优先编写新的本地 Playwright 测试文件
  • 浏览器模式默认首页从 http://127.0.0.1:1420/ 进入
  • 能走真实后端就走真实后端;浏览器模式暂不支持或尚未桥接的能力,允许走 mock
  • verify:gui-smoke 内部的 browser runtime 校验默认走无界面浏览器会话;它只证明主链可启动,不替代后续真实页面交互验证
  • lime-pet 原生桌宠属于独立仓库与原生窗口壳,不纳入当前 WebView Playwright 的直接操控范围;在 Lime 主仓里只验证 companion_* API、状态事件与主窗口唤起链路,桌宠窗口移动、点击命中与原生层动画仍需额外手工 smoke
  • 如果 companion 协议新增了 provider 摘要或桌宠回跳设置等事件,Playwright 续测只覆盖 Lime 主仓内的“状态事件是否触发”“是否跳到 设置 -> AI 服务商”和“主窗口是否被唤起”,不在 WebView 层尝试直接操控原生桌宠 UI
  • 共享网关控制页已下线,托盘也不再展示网关状态或地址;共享网关 /v1/routes 与 selector HTTP 路由也已下线,不再对“启动/停止网关、复制网关地址、路由/curl 示例、selector 路由、托盘运行态文案”做 GUI 续测;server 验证只关注标准 /v1/messages 与 /v1/chat/completions 主链,如需看运行时状态,走开发者页或实验页的诊断面板
  • 项目排版模板与品牌人设扩展旧链路已下线,不再对相关弹窗、模板列表、默认模板、人设扩展表单做 GUI 续测;项目与工作台回归只围绕当前 Claw / workspace / 现役 persona 主链
  • 如果只是模块级代码修改、并不需要真实页面交互,优先跑最小单测或 verify:local

进入前的最低准备

推荐启动命令

npm run tauri:dev:headless

用途:

  • 启动前端 dev server
  • 启动 Tauri headless 调试环境
  • 启动浏览器模式所需的 DevBridge

桥接健康检查

npm run bridge:health -- --timeout-ms 120000

用途:

  • 等待 http://127.0.0.1:3030/health 就绪
  • 避免 Playwright 进入页面时,前端早于 DevBridge 启动而产生 Failed to fetch 噪音

命令 / bridge 相关定向测试

npm run test:bridge
npm run test:contracts

适用时机:

  • 修改了 safeInvoke
  • 修改了 src/lib/tauri-mock/
  • 修改了浏览器模式 bridge/mock 优先级
  • 修改了 Tauri 命令边界

标准续测流程

1. 先确认当前浏览器会话是否可复用

优先顺序:

  1. 调用标签页工具查看当前标签页
  2. 如果已有 Lime 标签页,先查看当前 URL、标题和页面状态
  3. 如果页面已漂移到旧状态,直接重新导航到 http://127.0.0.1:1420/

建议:

  • 继续测试优先复用当前标签页,避免无意义重复建页
  • 如果控制台历史噪音太多,刷新页面重新计数

2. 进入页面后先验证加载状态

推荐动作:

  1. 打开页面后等待“正在加载...”消失
  2. 用页面快照确认首页核心元素已出现
  3. 立刻检查一次控制台 error

通过标准:

  • 首页成功加载
  • 默认首页可交互
  • 初始控制台 error 为 0;如果不是 0,先定位是否为 bridge 缺口

3. 交互时优先使用稳定定位

遵循 Playwright 官方最佳实践:

  • 优先用角色、名称、可见文本定位
  • 优先使用 Playwright 自带等待与 web-first 断言
  • 不要依赖固定 sleep 代替状态判断
  • 点击前先确认元素可见、可交互

本仓库中优先使用:

  • button + 中文名称
  • 页面中明确可见的标题文本
  • 快照里的精确元素引用

Lime 推荐续测主路径

首页基础验证

  1. 打开 http://127.0.0.1:1420/
  2. 等待默认首页加载完成
  3. 验证主导航可见,例如“首页”“社媒内容”“设置”
  4. 检查控制台 error 是否为 0

AI 服务商页拆分后验证

  1. 进入 设置 -> AI 服务商
  2. 确认默认落在 服务商设置,左侧能看到 Provider 列表,右侧是当前 Provider 配置
  3. 确认首屏不会默认混入 OEM Offer、套餐或云端模型目录
  4. 点击 云端服务
  5. 确认 OEM 会话、Offer 卡片、默认来源和模型目录改为在该页单独展示
  6. 如当前环境故意破坏了 models/index.json,确认 Provider 模型区会提示“模型真相源异常”,而不是静默显示空态

社媒内容工作流

  1. 点击 社媒内容
  2. 没有项目时点击 新建项目
  3. 已有项目时直接选择目标项目
  4. 点击 新建文稿
  5. 选择 新开帖子(创建新文稿)
  6. 点击 确认生成
  7. 验证页面出现 Theme Workbench 或相关工作台内容
  8. 再次检查控制台 error
  9. 如能查看运行时摘要,继续确认当前 gate 与任务标题恢复自该话题最近一次 execution_runtime.recent_gate_key / recent_run_title
  10. 当前项目管理与工作台侧已下线“项目风格 / 风格策略”旧入口,不再对其做存在性验证;如页面仍出现相关入口,应判定为回流

浏览器工作台站点采集验证

  1. 进入带有 browser assist 的工作区或浏览器运行时面板
  2. 打开 站点采集工作台 或对应调试面板
  3. 先确认推荐区已出现,并至少看到一个推荐适配器卡片
  4. 点击一个推荐项,确认适配器、资料提示和标签页提示同步变化
  5. 触发一次执行失败场景时,确认结果区展示业务级错误码与 report_hint
  6. 如当前页面带有 contentId 上下文,再确认执行成功后默认是“写回当前主稿”,而不是新建资源文档
  7. 如工作台模式开启自动保存,再确认执行成功后保存态文案与打开入口正常
  8. 打开控制台并确认浏览器资料 / 环境预设读取没有落回 web mock,尤其不应出现 [Mock] invoke: list_browser_profiles_cmd 或 [Mock] invoke: list_browser_environment_presets_cmd

Claw 站点技能直跑门禁验证

  1. 在 Claw 首页打开一个站点型技能弹窗
  2. 如果当前没有附着真实浏览器会话,确认弹窗继续展示“需要先准备浏览器 / 重新检测会话”的门禁提示,且 在 Claw 中执行 主按钮处于禁用状态
  3. 点击 去浏览器工作台,确认只发生页面跳转,不会后台偷偷拉起 Chrome
  4. 在浏览器工作台附着到真实浏览器并打开目标站点后,回到 Claw 再次打开同一技能
  5. 确认此时主按钮变为可执行,点击后进入 Claw 工作区
  6. 确认进入 Claw 后会自动发送一条首回合技能任务消息,消息文本包含站点技能启动上下文,而不是由前端挂载副作用偷偷直跑
  7. 如果已有附着会话,确认 Claw 会通过 lime_site_run 执行并把结果写回当前主稿或项目资源
  8. 如果没有附着会话,确认不会再向 Claw 对话流注入“我已完成登录,继续执行”之类的确认卡;阻断必须停留在技能入口层

开发者页站点来源导入验证

  1. 进入 设置 -> 开发者
  2. 在 站点脚本目录联调 区块找到 外部来源 YAML 导入
  3. 粘贴一份仅包含 Lime 支持子集的 YAML 来源,点击 导入到 Lime 标准
  4. 验证摘要区来源切换为 外部导入,且适配器列表出现新导入名称
  5. 再点击 清空站点目录缓存,确认来源恢复为 应用内置,列表回退到 bundled 目录
  6. 导入与清理全过程都不应出现后台自动拉起浏览器、自动唤醒 Chrome 或常驻浏览器控制进程

连接器页验证

  1. 进入 设置 -> 连接器
  2. macOS 下确认首页能看到“我的浏览器”“macOS 连接器”“高级控制”三块主区域;Windows 与其他非 macOS 平台默认不应出现系统连接器卡片
  3. 点击“展开高级控制”,确认 总览 / Profile / 桥接 / 后端 / 调试 页签可切换
  4. 如当前环境允许目录选择,点击“选择目录并安装”或“同步更新扩展”,确认安装目录最终落到固定子目录 Lime Browser Connector
  5. 点击“复制配置”,确认剪贴板内容包含 serverUrl / bridgeKey / profileKey
  6. 确认“连接方式”区块同时展示“浏览器扩展 / CDP 直连”两种说明,并包含 chrome://extensions 与 chrome://inspect/#remote-debugging 的打开或复制入口
  7. 在“动作配置”区块临时关闭一个能力,例如“页面内查找”,确认开关状态立即更新,且后端能力列表同步隐藏对应动作
  8. 如当前环境已有 observer 连接,再确认“断开已连接扩展”能把页面状态回退到等待连接
  9. 如当前环境接通真实后端,再确认“打开 Chrome 扩展页”与“打开远程调试页”可成功唤起对应 Chrome 页面

自动化设置页验证

  1. 进入 设置 -> 系统 -> 自动化
  2. 确认调度状态、任务列表、健康面板能正常加载
  3. 打开控制台,确认浏览器模式接通 DevBridge 时不再出现 get_automation_jobs、get_automation_health 或 get_automation_run_history 的 unknown command 报错
  4. 如当前环境允许创建或编辑任务,再确认提交后列表能刷新,而不是只靠 web mock 静态回显

话题模型恢复验证

  1. 进入同一工作区中的两个话题
  2. 分别切换成不同的 provider/model 组合
  3. 在两个话题之间来回切换
  4. 验证模型选择器恢复的是该话题最近一次 session runtime,而不是陈旧的 localStorage 默认值
  5. 如页面暴露运行时摘要条,再确认 provider/model 文案与选择器一致

话题权限恢复验证

  1. 进入同一工作区中的两个话题
  2. 在话题 A 选择 只读,在话题 B 选择 当前工作区 或 完全访问
  3. 在两个话题之间来回切换,必要时刷新页面后再切回
  4. 验证输入框权限选择器恢复的是该话题最近一次 accessMode,而不是工作区级默认值
  5. 如页面暴露运行时摘要、调试面板或开发日志,继续确认恢复依据是当前话题最近一次 execution_runtime.recent_access_mode
  6. 再立即发送一条消息,确认本轮会沿用该 accessMode 对应的正式权限策略,而不是只在 metadata 里残留旧的 harness.access_mode

话题工具偏好恢复验证

  1. 进入同一工作区中的两个话题
  2. 分别切换 联网 / 深度思考 / 任务模式 / 子代理 开关组合
  3. 在两个话题之间来回切换,必要时新建一个空白话题再切回
  4. 验证工具开关恢复的是该话题最近一次 session runtime,而不是主题级 localStorage 默认值
  5. 如首次切回旧话题时只能命中 fallback,再继续切换一次,确认第二次开始已优先走 runtime 恢复

话题 Team 恢复验证

  1. 进入同一工作区中的两个话题
  2. 在话题 A 里选择一个 builtin Team,在话题 B 里选择另一个 builtin 或 custom Team
  3. 在两个话题之间来回切换,必要时新建一个空白话题再切回
  4. 验证 Team 选择器、摘要区和 Team Workbench 展示恢复的是该话题最近一次 recent_team_selection,而不是主题级 localStorage 的旧值
  5. 对 custom Team 额外确认:切回后 label / description / roles 没丢;如果本轮是从 fallback 回填,继续切换一次确认第二次开始已优先走 runtime 恢复
  6. 如果当前项目已有子代理或父会话上下文,再发送一条新消息,确认 Team Workbench 的 shadow 卡片与当前 Team 恢复一致,不会退回到全局 theme fallback;本轮如涉及 harness.team_memory_shadow,这里就是最小 GUI 续测锚点

子代理 current 字段验证

  1. 准备一个带 Team 或父子会话上下文的工作区,并触发一次子代理创建
  2. 如果当前入口支持显式名称或工作目录,优先带上 name 与绝对 cwd;如果 UI 暂无显式入口,至少复用现有 flow 创建一个 child session,并在详情区观察其展示名与工作目录
  3. 验证 child session / Team Workbench 优先显示显式 name,而不是退回 agent_type、profile label 或 task summary fallback
  4. 如果本轮涉及 teamName,确认 child 会回挂到当前 Team,上下文里能按该名字识别,不会出现重复成员或错挂到其它 Team
  5. 验证 child 的 working_dir 与详情展示反映请求的绝对 cwd;如果请求非法相对路径,前端应看到明确失败,而不是静默回退父目录

上下文压缩链路验证

  1. 准备一个长线程,确保能够稳定接近上下文上限
  2. 在 workspace.settings.auto_compact=true 时发送普通消息,确认需要时会自动压缩,并且时间线出现 自动压缩
  3. 再把同一工作区切到 workspace.settings.auto_compact=false
  4. 分别验证两条链路:
    • 普通发送消息
    • ask-user / elicitation 回填后继续执行
  5. 两条链路都不应再静默自动压缩;如果达到上下文上限,页面应出现“请先手动压缩上下文或新建会话后重试”的可见错误

运行时交接制品验证

  1. 进入带有 HarnessStatusPanel 的对话工作区,并确保当前话题已经拿到 sessionId
  2. 展开 交接制品 区块,点击 导出交接制品
  3. 验证区块内出现:
    • 导出时间
    • 线程状态 / 最新 Turn 状态
    • Todo 统计
    • plan / progress / handoff / review 文件列表
  4. 继续点击单个制品的 预览,确认预览弹窗能打开,并能看到对应绝对路径
  5. 如页面桥接到了真实后端,再点击 打开目录 或单文件 打开,确认不会落回 mock,且工作区内确实生成 .lime/harness/sessions/<session_id>/...
  6. 如果这轮继续开发问题证据包,再把同一条续测链扩展为“先导出 handoff,再导出 evidence pack”,确认两者目录与状态卡不会串线
  7. 如果这轮继续开发 replay 样本导出,再点击 导出 Replay 样本,确认:
    • input / expected / grader / evidence-links 文件列表出现
    • replay 区块能显示 handoff / evidence 的关联根路径
    • 打开目录后工作区内确实生成 .lime/harness/sessions/<session_id>/replay
  8. 如果这轮继续开发 replay -> eval 主链,再点击 复制回归命令,确认:
    • 剪贴板内容同时包含 npm run harness:eval:promote -- ...、npm run harness:eval 与 npm run harness:eval:trend
    • promote 命令里的 session-id / slug / title 已自动带出,不需要手工补参数
    • 该入口只是复制仓库已有主命令,不是 Lime 内部自动 promotion
  9. 如果这轮继续开发外部分析交接,再点击 导出分析交接 与 一键复制给 AI,确认:
    • analysis-brief.md / analysis-context.json 文件列表出现
    • 复制内容直接来自后端 copy_prompt,不需要前端再手写 prompt
    • analysis 区块能显示 handoff / evidence / replay 的关联目录
  10. 如果这轮继续开发人工审核记录,再点击 导出人工审核记录,确认:
    • review-decision.md / review-decision.json 文件列表出现
    • 区块能显示当前状态、审核清单与关联 analysis 文件
    • 打开目录后工作区内确实生成 .lime/harness/sessions/<session_id>/review
  11. 如果这轮继续开发人工审核保存闭环,再点击 填写人工审核结果,至少填写:
    • 决策状态
    • 决策摘要
    • 审核人
    • 风险等级
  12. 保存后确认:
    • 区块里的“当前人工审核结论”立即刷新为最新状态、审核人和摘要
    • review-decision.md / review-decision.json 仍然保持同一目录,不会新开平级目录
    • 如页面桥接到了真实后端,重新点击 导出人工审核记录 后,已保存结论不会被刷回 pending_review

话题内容上下文恢复验证

  1. 进入带 contentId 的工作台话题并完成至少一次发送
  2. 留在同一话题下再次发送,保持目标主稿不变
  3. 验证本轮仍写回当前主稿,没有误新建资源文档或切到其他内容
  4. 如能查看调试面板或运行时摘要,继续确认恢复依据是当前话题最近一次 execution_runtime.recent_content_id,而不是页面一次性参数或陈旧缓存
  5. 再切到另一个 contentId 后立即发送一次,确认同步窗口内仍能命中新主稿,而不是被旧 runtime 误覆盖

话题主题上下文恢复验证

  1. 进入普通对话话题完成一次发送,再切到 Theme Workbench 话题完成一次发送
  2. 在两个话题之间来回切换,必要时新建一个空白话题再切回
  3. 验证 UI 恢复的是该话题最近一次主题上下文,而不是页面一次性参数或主题级缓存
  4. 如能查看调试面板或运行时摘要,继续确认依据是当前话题最近一次 execution_runtime.recent_theme / recent_session_mode
  5. 再从普通对话切到新的 theme_workbench 后立即发送一次,确认同步窗口内仍命中新 theme / session mode,而不是被旧 runtime 误覆盖

Theme Workbench 运行阶段恢复验证

  1. 进入同一个 Theme Workbench 话题,至少完成一次 write_mode 或 publish_confirm 阶段发送
  2. 留在同一话题下再次发送,保持当前 gate 和任务标题不变
  3. 验证本轮仍衔接当前 gate / 任务标题,而不是掉回旧阶段或空标题
  4. 如能查看调试面板或运行时摘要,继续确认恢复依据是当前话题最近一次 execution_runtime.recent_gate_key / recent_run_title
  5. 再切到新的 gate 或新的运行标题后立即发送一次,确认同步窗口内仍命中新 gate / run title,而不是被旧 runtime 误覆盖

服务型技能自动化交付链

  1. 从首页进入服务型技能卡片
  2. 选择一个 scheduled / managed 的本地服务型技能
  3. 打开“创建自动化任务”,提交后进入对应工作区
  4. 确认同一次操作里:
    • 自动化任务已创建
    • 工作区已打开
    • 对应内容仍落在同一个 contentId
  5. 如能查看运行记录或调试面板,继续确认自动化 agent_turn payload 含 content_id 与 request_metadata.artifact

素材页验证

  1. 从社媒内容项目进入 素材
  2. 验证素材列表可加载
  3. 验证素材计数、列表项或空状态正常显示
  4. 如当前环境能查看调试面板或 DevBridge 日志,优先确认素材页读取的是 gallery_material_* 命令,而不是旧 poster_material_* 命名
  5. 检查控制台无新增 error

每一步至少记录什么

执行 Playwright MCP 续测时,至少记录以下事实:

  • 当前页面 URL
  • 当前关键可见文本
  • 是否走到了真实 bridge
  • 是否触发了 mock fallback
  • 控制台 error 数量
  • 如失败,明确失败命令名或失败交互点

推荐结论格式:

  • 页面是否可打开
  • 业务流是否走通
  • 控制台是否归零
  • 新暴露的命令缺口是什么
  • 该缺口更适合补真实 bridge 还是补 mock

常见故障与处理

1. Cannot read properties of undefined (reading 'invoke')

通常表示:

  • 浏览器里加载了真实 Tauri API 包
  • 没有走 web mock / HTTP bridge 链路

优先排查:

  • 是否使用了浏览器模式专用启动方式
  • Vite 是否正确走了 web alias
  • 当前页面是否需要强制刷新以拿到最新前端代码

2. [DevBridge] 未知命令

说明:

  • 前端已调用某命令
  • 浏览器 bridge 分发器没有实现

处理顺序:

  1. 先判断该命令是否应走真实后端
  2. 如果该能力在浏览器模式下不是关键阻塞项,可加入 mock 优先集合
  3. 如果该命令属于核心业务路径,优先补 bridge 分发

3. Failed to fetch

常见原因:

  • DevBridge 没启动
  • 3030 端口不可用
  • 前端先于 bridge 就绪开始调用

处理建议:

  • 确认 tauri:dev:headless 已启动
  • 检查 bridge 健康接口
  • 刷新页面后复测,排除启动时序问题

4. UI 已可用但控制台仍报错

说明:

  • 页面可能依赖 fallback mock 继续运行
  • 但仍有命令先打到了 bridge 并报 unknown command

处理建议:

  • 如果该命令属于浏览器模式可接受的降级能力,加入 mock 优先列表
  • 如果该命令属于当前主路径必须能力,补真实 bridge
  • 对浏览器资料 / 环境预设这类已桥接命令,优先排查真实 DevBridge 或默认种子,不要再把它们加回 mock 优先集合

何时补 mock,何时补真实 bridge

优先补真实 bridge

适用于:

  • 当前主路径必须命令
  • 明确已有后端实现
  • 返回结构简单稳定
  • 不涉及复杂流式事件或强原生依赖

优先补 mock

适用于:

  • 浏览器模式不支持的原生能力
  • 非主路径功能
  • 高频噪音命令,但不影响主流程完成
  • 流式 / 系统级能力,短期内 bridge 成本高于收益

结果判定标准

一次“继续测试”完成后,至少满足以下之一:

  1. 主路径走通且控制台 error 归零
  2. 主路径走通,且剩余错误已被明确归类为非阻塞项
  3. 已定位新的 bridge 缺口,并给出下一步最小修复点

交接要求

如果本轮没有完全收口,结论里必须留下:

  • 当前停留页面
  • 已完成的业务步骤
  • 最新暴露的命令缺口
  • 推荐下一步先补 mock 还是先补 bridge
  • 下一轮建议的 Playwright 复测路径

相关文档

  • docs/aiprompts/quality-workflow.md
  • docs/aiprompts/commands.md
  • docs/aiprompts/governance.md