28 KiB
mnote 测试参考
⚡ 浏览器测试快速启动(AI agent 专用)
执行浏览器验证前,先确认此节,避免浪费时间。
1. 检查服务是否已运行
ss -ltnp 'sport = :3000'
# 有输出 = 服务已运行,跳到步骤 3
# 无输出 = 服务未运行,继续步骤 2
2. 启动服务(后台模式)
nohup npm run dev:hot > /tmp/mnote-dev.log 2>&1 &
echo $!
# 等待 5-10 秒后检查日志
sleep 8 && grep -E 'gateway 已启动|Running' /tmp/mnote-dev.log
关键点:
- 启动命令是
npm run dev:hot(唯一热启动入口) dev:hot默认启用MNOTE_WEB_ALLOW_DEV_FIXTURES=1- 使用 cargo-watch 自动重编译
- 端口固定为 3000
3. 浏览器验证步骤(Paseo)
# 1. 新建标签页
paseo_browser_new_tab url=http://localhost:3000/auth
# 2. 等待页面加载
paseo_browser_wait url=localhost:3000 timeoutMs=15000
# 3. 截图(如果返回 "tab not painted",等 3 秒重试)
paseo_browser_screenshot
# 4. 标准登录(7-76:无「测试账号快速登录」按钮)
# 在 snapshot 中定位账号/密码输入框与「登录」提交按钮后填表提交;
# 或脚本侧:require('./lib/browser-auth-login').loginViaAuthForm(page)
# 5. 等待进入工作区
paseo_browser_wait url=localhost:3000 text=工作区
# 6. 截图
paseo_browser_screenshot
4. 测试账号(7-76 方案 A:admin / user / AI 主体分离)
| 用途 | 用户名 | 邮箱 | 密码(本地/dev) | control-plane role |
admin 能力 |
|---|---|---|---|---|---|
| Ops admin | mnote-admin |
mnote.admin@example.com |
MnoteAdmin123! |
admin |
是(/admin/*、access-policy、代签) |
| AI 主体 | mnote-e2e |
mnote.e2e@example.com |
MnoteE2E123! |
ai_service |
否 |
| 个人用户示例 | liaibo |
(本地) | (本地) | user |
否 |
- 登录方式:标准表单 /
POST /api/auth/scripts/lib/browser-auth-login.js- 产品/AI 主体:
loginViaAuthForm/loginViaAuthApi(默认 e2e) - 管理面 seed:
loginAsAdminViaAuthForm/withAdminBrowserSession
- 产品/AI 主体:
- 不要依赖快速登录按钮;不要把
mnote-e2e放进MNOTE_ADMIN_USER_IDS或access-policy.admins。
5. 常见问题
| 问题 | 原因 | 解决 |
|---|---|---|
| ERR_CONNECTION_REFUSED | 服务器未启动 | 先运行 npm run dev:hot |
| tab not painted | 页面未渲染完成 | 等待 3 秒后重试截图 |
| Paseo 终端无输出 | 前台进程阻塞 | 用 nohup ... & 后台启动 |
6. AI 密码本读密 / 登录态(12-2 · 不依赖 3000)
读密与 login/session 走本地 core + capability token,不要为 resolve/login/session 启 mnote-web。
cd rust
cargo build -q -p mnote-vault
# 一次签发(写入 ~/.config/mnote/vault-tokens/default.token;默认 scope 含 login,session)
./target/debug/mnote-vault issue-token --agent smoke --ttl 1d
./target/debug/mnote-vault doctor
# 可选常驻 UDS($XDG_RUNTIME_DIR/mnote-vaultd.sock 或 MNOTE_VAULT_SOCK)
./target/debug/mnote-vault serve &
./target/debug/mnote-vault list # sock 优先,不可达则内嵌 core
./target/debug/mnote-vault resolve --id <cred_id> --field password
./target/debug/mnote-vault resolve --id <id> --field password --local # 强制内嵌
./target/debug/mnote-vault resolve --id <id> --field password --remote # 强制 UDS
# session 回写 + login 复用(无外站 HTTP)
./target/debug/mnote-vault session --id <id> --cookie-header 'mnote_session=smoke; other=1' --local
./target/debug/mnote-vault login --id <id> --local # 期望 reused=true / mode=session
cargo test -p mnote-vault-core --lib
cargo test -p mnote-web --lib routes::vault::resolve_strategy_tests
cargo test -p mnote-web --lib routes::vault -- --nocapture 2>&1 | rg -n "login_reuses|ok"
- Crate:
mnote-vault-core、mnote-vault(bin,含serve+ login/session)、mnote-webAI list/get/resolve/login/session thin-wrap core - 设计:
design/12-vault/process/12-2-vaultd-local-token-agent-read-path-v1.md - Skill / 策略:
$mnote-vault、/home/lix/.agent-infra/vault-policy.md - Web UI / CRUD workbench 仍可走 3000;list/get/resolve/login/session 稳态禁止以 auth-e2e 为前置
这份文档面向 /mnt/Data1T/mnote/scripts 目录下的现有测试脚本,目标不是重新设计测试体系,而是把当前已经在用的 smoke、回归脚本、截图取证和人工复核方式整理成一套可执行参考。
当前结论先说在前面:
scripts/里的主力仍然是Playwright smoke + Node 断言。- 对
mnote来说,最有价值的不是把所有测试都换成“浏览器插件式控制”,而是把已有 smoke 的结果变得更可看、更易复核。 /doko适合作为 smoke 之后的“真实页面直观复核层”,不是用来替代 smoke。- 2026-05-20 起,默认主入口固定按
http://127.0.0.1:3000理解;历史记录里的3001只代表当时临时 mnote-web 实例,不再作为默认验收入口。 - 历史 smoke 分为
current与retired/debug两类维护;退役脚本不应进入默认回归,除非脚本自身要求显式环境变量。 - 2026-05-27 起,默认 smoke 基线只覆盖
3000 Rust SSR + leptos-tiptap + local-first主路径;Convex export、Convex 兼容、Next、3104、BlockNote 默认路径脚本不再放在默认候选里。 - 依赖
/api/dev/seed的 browser smoke 默认使用npm run dev:hot;dev:hot默认启用MNOTE_WEB_ALLOW_DEV_FIXTURES=1,生产启动仍默认关闭。修改 Node 启动脚本或环境变量后必须重启dev:hot主进程,不能只等待 cargo-watch 重载 Rust。
0. 当前 smoke 状态清单
这一节用于避免历史脚本被误当作当前架构主链验收。
0.0 2026-05-26 默认基线
建议日常 smoke 先跑这一组,确保当前主入口、认证、文档 island、Page Aggregate、local-first 和关键 runtime surface 没断:
node scripts/task114-rust-web-gateway-entry-smoke.js
node scripts/task159-auth-entry-smoke.js
node scripts/task164-desktop-hot-local-folder-main-entry-smoke.js
node scripts/task166-local-first-managed-workspace-no-convex-smoke.js
node scripts/task167-local-markdown-title-body-options-no-convex-smoke.js
node scripts/task490-runtime-surfaces-smoke.js
其中 task490-runtime-surfaces-smoke.js 是轻量浏览器 smoke,验证页面设置、浮动 Pi Lab 入口、旧 OpenHub/opencode 前端不再打开、slash menu、block handle menu 能在当前 leptos-tiptap 文档页工作;它不要求真实模型返回,也不替代更重的 Pi Lab/Page AI 或编辑器菜单专项脚本。
0.1 当前主链优先脚本
- 入口与认证:
task114-rust-web-gateway-entry-smoke.js、task159-auth-entry-smoke.js、task097-homepage-entry-smoke.js - Rust SSR 文档页 / Page Aggregate:local-first 默认优先
task167-local-markdown-title-body-options-no-convex-smoke.js;Page Aggregate browser conversion / compat fallback 改动补跑task522-page-aggregate-compat-fallback-contract.js;cloud/control-plane 文档可补跑task110-page-title-single-truth-smoke.js、task-page-aggregate-body-sync-smoke.js、task-page-aggregate-options-sync-smoke.js、task-page-aggregate-refresh-persistence-smoke.js - leptos-tiptap runtime surface:
task490-runtime-surfaces-smoke.js;需要验证保存回读可补跑task121-rust-web-editor-island-hydration-smoke.js,但它仍使用/api/tree/commands create准备文档,不作为无 Convex 默认基线;需要验证浮层互斥和更多菜单状态时再跑task158-e30-menu-state-smoke.js - local-first 本地工作区:
task164-desktop-hot-local-folder-main-entry-smoke.js、task166-local-first-managed-workspace-no-convex-smoke.js、task167-local-markdown-title-body-options-no-convex-smoke.js、task436-local-markdown-open-document-external-change-smoke.js、task443-local-markdown-asset-upload-smoke.js、task451-local-markdown-conflict-resolution-ui-smoke.js、task452-local-search-index-browser-smoke.js、task453-local-folder-page-ai-changed-files-smoke.js;WorkspacePath / ObjectIdentity runtime 消费统一改动补跑task524-workspace-object-identity-matrix-smoke.js。task452只覆盖普通本地搜索、settings API、tag/backlink API 和旧 local-index UI 不复活;资料库问答、PDF/Office/image source ingestion 与引用回跳改跑 LightRAG / provider-neutral knowledge-rag 脚本。 - LightRAG / Knowledge RAG 资料库:LightRAG 是默认 provider。资料源、摄取、source scope 与 watcher 改动优先跑
task532-knowledge-rag-docx-ingestion-smoke.js、task533-knowledge-rag-source-watcher-sync-smoke.js、task534-knowledge-rag-source-management-scope-smoke.js、task538-knowledge-rag-source-scope-api-smoke.js;引用和 Page AI final answer 改动补跑task529-knowledge-rag-citation-resource-tab-smoke.js、task530-knowledge-rag-page-ai-final-answer-smoke.js;真实 Pi + LightRAG 服务可用时补跑task-pi-lab-real-lightrag-smoke.js。旧 OpenHub 专项资料库 smoke 已软归档到recycle/20260712-pi-ts-openhub-retirement/;旧task526-local-folder-ocr-api-smoke.js/ OCR sidecar 链路已退役并软归档;/api/search/documents不作为 LightRAG、LiteParse、OCR sidecar 或 evidence.sqlite 的资料库问答 fallback。 - local Markdown conflict regression:
task510-local-markdown-conflict-regression-group.js串联真实冲突、连续上传、新建页面、外部恢复、多 tab CAS 与上传 409 孤儿策略;可用MNOTE_CONFLICT_REGRESSION_TASKS=a.js,b.js做定点子集。 - tree realtime / live cache:
task446-tree-rename-dual-browser-live-smoke.js、task447-tree-move-order-dual-browser-live-smoke.js、task448-tree-resync-recovery-dual-browser-smoke.js、task449-tree-sse-reconnect-snapshot-recovery-smoke.js - 资源对象与 mindmap:
task455-local-folder-mindmap-clean-smoke.js、task456-resource-object-shell-sync-smoke.js、task166-mindmap-phase6-block-smoke.js、task167-mindmap-kmind-parity-smoke.js、task168-mindmap-put-validator-smoke.js;Page AI mindmap skill / 资源生成改动补跑task503-mindmap-skill-capability-smoke.js,真实 mindmap resource tab / Page AI target 改动补跑task525-page-ai-mindmap-resource-target-smoke.js - Page AI / agent history / ChatOnly:
task502-page-ai-agent-selector-context-smoke.js覆盖 Page AI agent/context/target picker、skills source 和 run payload;raw local resource target 改动补跑task520-page-ai-raw-resource-target-smoke.js;task504-page-ai-history-agent-filter-smoke.js覆盖 Page AI 历史按 agent 过滤;ChatOnly / provider session 绑定改动优先跑task512-chatonly-doubao-sync-smoke.js,跨 provider 同步补跑task513-chatonly-provider-sync-smoke.js。task763/task765是 OpenCode debug fallback 专项脚本,不属于默认回归,待 debug route 彻底移除时一并退役。 - Dev hot / OnlyOffice live bridge:Sidebar dev hot reload 入口改动补跑
task514-sidebar-dev-hot-reload-gating-smoke.js;OnlyOffice live bridge session / scope / HTTP 工具边界改动补跑task515-onlyoffice-live-scope-http-smoke.js;bridge session/token/queue/current/close 和docKey/pageOrigin元数据改动补跑task516-onlyoffice-bridge-multisession-browser-smoke.js;bridge plugin index /Asc.plugindirect loop / plugin 元数据透传改动补跑task517-onlyoffice-bridge-plugin-direct-smoke.js;真实 ONLYOFFICE iframe / DocumentServer session、同文档双 tab、resource scope 和非 dry-run 写入落点改动补跑task518-onlyoffice-real-iframe-session-scope-smoke.js;Page AI 真实 UI 选择 Office target 并冻结 live bridge session 改动补跑task523-page-ai-onlyoffice-real-target-session-smoke.js - local resource lifecycle API:
task437-local-folder-asset-trash-lifecycle-smoke.js,现在只验证local-file:*delete / restore / purge,不再依赖普通.txt是否出现在 UI 文件树。
0.2 需要退役或拆分的历史脚本
task444-convex-workspace-export-local-fixture-smoke.js、task455-convex-export-plan-rollback-smoke.js与export-convex-workspace-to-local.js:Convex export 迁移验证已退出默认 smoke,已归档到recycle/scripts/retired-convex-export-smokes-20260526/。- 注意编号复用:
scripts/task444-filetree-create-mindmap-title-cache-smoke.js与scripts/task455-local-folder-mindmap-clean-smoke.js仍是当前本地 filetree / mindmap 脚本;退役的是带convex-export名称的 task444 / task455。 - 旧 Convex 兼容 smoke 已软删除到
recycle/20260527-legacy-cleanup/convex/scripts/,包括task163、task174、task175、task427、task428、task429、task430、task431、task432、task433、task434。 task179-tree-create-delete-no-reload-smoke.js:覆盖/treedebug shell。/tree已是显式 debug/internal 边界,脚本默认阻断;只有设置MNOTE_ALLOW_DEBUG_TREE_SMOKE=1时才可执行。task123-rust-web-tree-live-stream-consumer-smoke.js:只证明/api/tree/eventsSSE fallback 仍可用。当前 realtime 主链是 WebSocket push + SSE fallback;验证主链时优先使用 446 / 447 / 448,只有排查 fallback 时再跑 123。- 历史非 LightRAG 默认 provider 脚本(
task544、task769、task772、task777、task781、task783、task784、task785、task787、task788、task789、task790、task79x)已退役并软归档到recycle/scripts/下对应归档目录(及历史 recycle);不进入 LightRAG 默认回归。 - Hermes/ACP/Reasonix 页面 AI 主流程 smoke 已退役;只保留
task-hermes-page-ai-retirement-guard.js防止旧 runtime 复活。task762-page-ai-board-first-smoke.js也已退役。 - 旧
task019、task021、task022这类早期 UI regression 脚本已软删除到recycle/scripts/retired-ui-regressions/,只作为历史对照;后续默认不要用于当前 Rust SSR / local-first 主路径验收。 task494-filetree-lazy-loading-dedup-smoke.js、task498-starred-page-tree-scope-and-local-edit-smoke.js、task499-sidebar-tree-view-state-smoke.js:2026-07-21 诊断为 fixture/契约过时(非 Playwright 安装问题),已迁到recycle/scripts/obsolete-tree-smokes-20260721/。全局 Playwright 栈:~/.agent-infra/playwright-stack(见该目录use-in-project.md)。树移动排序优先task447-tree-move-order-dual-browser-live-smoke.js或 Hermes tree QA。
0.3 其他 current 候选脚本
这些脚本不是最小默认基线,但仍属于当前 Rust SSR / leptos-tiptap / local-first 维护面,按改动范围选择性运行:
task426-mnote-web-main-no-reload-smoke.jstask109-leptos-island-multipage-save-smoke.jstask122-rust-web-create-page-ui-smoke.jstask125-rust-web-search-server-first-smoke.jstask165-rust-web-dual-pane-smoke.jstask458-local-create-page-no-conflict-smoke.jstask459-local-markdown-attachment-tab-smoke.jstask484-local-folder-page-body-refresh-readback-smoke.jstask486-local-markdown-save-error-editor-preserves-content-smoke.jstask487-local-folder-tree-live-consumer-smoke.js
1. 当前测试分层
按目录里的现状,脚本大致分成四层。
1.1 入口与网关层
这一层主要验证路由、网关、owner、认证入口、基础响应是否正确,特点是快、稳定、适合作为最早执行的守门测试。
代表脚本:
task097-homepage-entry-smoke.jstask114-rust-web-gateway-entry-smoke.jstask159-auth-entry-smoke.js
适用场景:
- 刚切流 Rust Web
- 改了入口路由、鉴权、兼容代理
- 需要先判断“服务有没有活着、入口是不是对的”
1.2 页面交互 smoke 层
这一层是当前最核心的 UI 验证方式:启动页面、登录测试账号、进入真实文档页或工作区,然后通过 Playwright 操作页面并做断言。
代表脚本:
task110-page-title-single-truth-smoke.jstask112-tree-rust-family-regression-smoke.jstask120-rust-web-tree-integration-smoke.jstask122-rust-web-create-page-ui-smoke.jstask164-page-options-visible-effect-smoke.jstask490-runtime-surfaces-smoke.jstask165-rust-web-dual-pane-smoke.jstask164-desktop-hot-local-folder-main-entry-smoke.jstask166-local-first-managed-workspace-no-convex-smoke.jstask455-local-folder-mindmap-clean-smoke.js
这一层已经覆盖了当前主线里最重要的部分:
- tree / sidebar / create page
- document shell / island hydration
- 页面设置、双栏、AI、local folder
- Rust Web 主路径
1.3 Wolai 对标与视觉取证层
这一层不是单纯判断“是否通过”,而是要保留截图、矩阵、对比结论,方便和 Wolai 体验做真实核对。
代表脚本:
task119-rust-web-wolai-visual-regression-smoke.js- 已跟踪的对标基线:
task118-rust-web-wolai-ui-parity-smoke.js、task119-rust-web-wolai-visual-regression-smoke.js task128、task129到task137、task160、task162是 gitignored 的本地历史取证脚本,不属于默认回归。- 页面 AI 旧
/api/ai-agent/run视觉 smoke 已移入本机 gitignoredrecycle/scripts/retired-ai-agent-run-smokes/;当前页面 AI 验证优先使用 Pi Lab / opencode / Page AI smoke 与task-page-block-ai-tools-smoke.js。Hermes 相关 smoke 只作为 legacy guard / 历史对照。
这一层最重要的原则不是“文案命中”,而是:
- 必须有截图
- 必须能说明视口
- 必须能说明对比对象
- 最终仍需要人工看图
1.4 共享 helper 与登录/临时文档支撑层
这部分决定了 smoke 是否能稳定复用。
关键文件:
tree-shell-smoke-helpers.jstask114-rust-web-gateway-entry-smoke.js
目前 helper 已经沉淀了几个稳定约定:
- 默认前端入口:
MNOTE_UI_BASE_URL,缺省http://127.0.0.1:3000 - 默认测试账号:
- 邮箱:
mnote.e2e@example.com - 密码:
MnoteE2E123! - UI:标准登录表单(
#account+#password+[data-auth-submit]) - 共享 helper:
scripts/lib/browser-auth-login.js、tree-shell-smoke-helpers.js
- 邮箱:
- 通过 API 或 UI 兜底完成认证(7-76 P0 起无快速登录按钮)
- 为 smoke 自动创建、重命名、清理临时页面
后续新脚本优先复用这些 helper,不要在每个任务里再复制一套登录和清理逻辑。
Dev seed 启动契约
- 需要
setupWorkspaceAccess、seedAiPolicy、seedAiRuntime等测试数据准备能力时,先确认服务由npm run dev:hot启动。 npm run dev:hot默认开启 dev fixtures;可用MNOTE_WEB_ALLOW_DEV_FIXTURES=0 npm run dev:hot显式关闭。- 生产启动不自动开放
/api/dev/seed;本地仅dev:hot默认开启 fixtures。 - smoke 遇到
dev_seed_disabled时不得标记为“功能未验证后跳过”;应先按上述契约重启服务,再重新执行完整 smoke。
2. 当前推荐测试顺序
对本项目,推荐不要一上来就跑最重的 UI 对标脚本,而是按下面顺序推进。
2.1 第一步:入口守门
先跑入口和网关类 smoke,确认不是服务没起或路由错了。
建议优先:
node scripts/task114-rust-web-gateway-entry-smoke.js
node scripts/task159-auth-entry-smoke.js
node scripts/task097-homepage-entry-smoke.js
适用时机:
- 本地服务刚启动
- 刚切换分支
- 改了认证、入口、gateway、compat
2.2 第二步:主路径交互 smoke
入口没问题后,再跑和当前改动最相关的页面交互脚本。
例如:
- tree / sidebar 改动:
task112、task120、task122 - document shell / island:
task110、task121 - local-first:优先使用
task164-desktop-hot-local-folder-main-entry-smoke.js、task166-local-first-managed-workspace-no-convex-smoke.js、task167-local-markdown-title-body-options-no-convex-smoke.js、task455-local-folder-mindmap-clean-smoke.js - 页面设置:
task164-page-options-visible-effect-smoke.js - 双栏:
task165 - AI:优先使用 Pi Lab / Page AI 当前主线 smoke、
task-page-block-ai-tools-smoke.js和task-hermes-page-ai-retirement-guard.js这类 legacy guard;其余 Hermes 页面 AI 主流程 smoke 已退役。Page AI history / skills / ChatOnly 相关改动补跑task503-mindmap-skill-capability-smoke.js、task504-page-ai-history-agent-filter-smoke.js、task512-chatonly-doubao-sync-smoke.js、task513-chatonly-provider-sync-smoke.js;OnlyOffice live bridge 改动补跑task515-onlyoffice-live-scope-http-smoke.js、task516-onlyoffice-bridge-multisession-browser-smoke.js、task517-onlyoffice-bridge-plugin-direct-smoke.js、task518-onlyoffice-real-iframe-session-scope-smoke.js,其中task516/517覆盖 bridge session lifecycle 与docKey/pageOrigin元数据;Page AI 真实 target picker / Office live session 改动补跑task523-page-ai-onlyoffice-real-target-session-smoke.js;task155、task156、task161等旧/api/ai-agent/runsmoke 只保留在本机 gitignoredrecycle/scripts/retired-ai-agent-run-smokes/做历史对照
原则:
- 只跑和当前改动相关的脚本
- 不要无差别全量跑
- 先窄后宽
2.3 第三步:截图证据复核
如果脚本本身已经输出:
screenshotscreenshotDirmeasurematrixPathresultPath
那这些产物不应只当“附带文件”,而应作为测试结果的一部分。
推荐做法:
- 成功时也保留关键截图
- 失败时至少保留失败前最后一张截图
- 重要 UI 任务保留整组截图目录
2.4 第四步:/doko 真实页面复核
当 smoke 已经告诉你“逻辑大体通过”,但你仍想确认页面是否真的像人看到的一样时,再补 /doko。
/doko 更适合回答这类问题:
- 首屏布局是不是顺眼
- Sidebar 层级、图标、文案是否真可读
- 页面设置弹层是否真的展开到位
- 登录后工作区是否像预期渲染
/doko 不擅长替代:
- 稳定断言
- 自动点击链路
- 大量重复回归
所以推荐组合是:
smoke 先筛出通过/失败 -> 看截图 -> 必要时再用 /doko 复核真实页面
3. 为什么当前不建议把主线转成“浏览器插件测试”
当前讨论过 codex cli + 浏览器插件 的方向,但对 mnote 现阶段的主要收益并不明显。
原因有三点:
- 你当前真正缺的是“页面直观证据”,不是“替换掉 Playwright”
scripts/里的 smoke 已经能覆盖多数关键交互,只是证据层不够统一- 浏览器插件路线更适合复用真实 Chrome 当前标签页和真实登录环境,不是当前项目测试的首要瓶颈
因此,现阶段更推荐:
- 保留 Playwright smoke 作为自动化骨架
- 补足截图、trace、结果摘要
- 用
/doko做人工视角复核
4. 新增或修改 smoke 的写法建议
这里不是要求统一重构旧脚本,而是约束新增脚本尽量沿着同一条路走。
4.1 优先复用 helper
优先从下面两个文件拿能力:
tree-shell-smoke-helpers.jstask114-rust-web-gateway-entry-smoke.js
尤其是:
- 登录
- 创建临时文档
- 清理临时文档
fetchWithTimeoutfindFreePortwaitForGateway
4.2 让脚本输出结构化结果
推荐脚本结束时输出 JSON,至少包含:
{
"ok": true,
"baseUrl": "http://127.0.0.1:3000",
"task": "taskxxx-name",
"screenshot": "/abs/path/to/file.png",
"screenshotDir": "/abs/path/to/dir"
}
如果没有截图,也应该至少输出:
okbaseUrltask- 关键对象 id(如
documentId、workspaceId)
4.3 对 UI 任务默认保留截图
满足下面任一条件时,建议默认保留截图:
- 首屏入口变化
- Sidebar / tree 结构变化
- modal / popover / dropdown 变化
- editor block 行为变化
- Wolai 对标
推荐命名方式延续现有风格:
01-before-*02-after-*03-after-reload-*
这样后续人工复核时不需要重新猜步骤。
4.4 失败信息要面向定位
断言报错要直接描述“哪个状态不对”,不要只写泛化失败。
推荐:
开启宽版后 htmlWide 应为 true,实际 false标准登录后仍停留在 /auth本地首屏未捕获工作区特征
不推荐:
smoke failedassert error
5. 针对当前 mnote 的推荐组合
如果后续只是做日常开发验证,推荐这样选:
5.1 快速检查
适合日常改完立刻看:
node scripts/task114-rust-web-gateway-entry-smoke.js
node scripts/task159-auth-entry-smoke.js
5.2 主路径回归
按当前改动挑 1 到 3 个最相关脚本,例如:
node scripts/task120-rust-web-tree-integration-smoke.js
node scripts/task122-rust-web-create-page-ui-smoke.js
node scripts/task164-page-options-visible-effect-smoke.js
5.3 视觉复核
如果任务明显涉及视觉或交互形态:
- 先看 smoke 产出的截图
- 再用
/doko打开真实页面复核
5.4 Wolai 对标任务
对标任务不要只看断言结果,至少补:
- 本地 smoke
- Wolai 基线截图
- 本地截图
- 必要时 comparison matrix
6. 对后续演进的建议
这部分不是要求本轮立刻实现,而是后续维护时优先考虑。
6.1 在现有 smoke 上统一证据产物
优先级最高的增强不是“换工具”,而是统一输出:
tmp/.../screenshotstmp/.../trace.ziptmp/.../result.json
这样 smoke 从“脚本 pass/fail”升级成“脚本 + 可看证据”。
6.2 把 /doko 固化成复核步骤
适合写进任务流程的话术是:
- 先跑 smoke
- 再看截图
- 仍有疑问时用
/doko看真实渲染
不要让 /doko 承担自动化断言职责。
6.3 新脚本优先沿当前命名方式继续
目前 taskNNN-...-smoke.js 已经形成了可追踪的任务链,后续建议继续沿用,避免引入第二套命名体系。
如果后续要继续推进,最值得做的不是重写测试体系,而是:
- 给最常用的 smoke 补统一截图/trace 产物
- 再补一份“如何读取 smoke 结果”的轻量脚本或汇总器
这样能直接解决当前最真实的痛点:A + C,也就是“结果更直观、测试更像真的看过页面”。
7. 脚本纪律:不得直写 control-plane 数据库
所有测试和 smoke 脚本不得直接通过 sqlite3 CLI、node:sqlite、better-sqlite3 或任何本地 SQLite 库写 control-plane DB。需要写入测试数据时,必须走以下批准路径:
7.1 通过 API seed(推荐)
使用 scripts/lib/control-plane-dev-seed.js 提供的 helper,通过 POST /api/dev/seed 写入:
const { setupWorkspaceAccess, seedAiRuntime } = require("./lib/control-plane-dev-seed");
await setupWorkspaceAccess(requestContext, baseUrl, { ... });
该 helper 调用的是 Rust /api/dev/seed 端点,不直写数据库。
初始环境(测试账号 + workspace)也可通过 control-plane-admin init --backend ... 准备,见 docs/operations/control-plane-turso.md。
7.2 通过统一环境变量构建
使用 scripts/lib/control-plane-test-env.js 的 buildControlPlaneTestEnv() 获取正确的控制面环境变量:
const { buildControlPlaneTestEnv } = require("./lib/control-plane-test-env");
const controlPlaneEnv = buildControlPlaneTestEnv(dataRoot, process.env);
// 然后传给 spawn(cargo, args, { env: { ...controlPlaneEnv } })
7.3 例外
scripts/lib/control-plane-dev-seed.js和scripts/lib/control-plane-test-env.js本身是批准 helper。scripts/mnote-web-hot.js、scripts/dev-hot.js、scripts/prod-build-start.js作为启动基础设施,设置环境变量路径是必要的。rust/crates/下的 Rust 代码通过ControlPlaneStoretrait 访问数据库是正常路径。scripts/task-control-plane-admin-libsql-roundtrip-smoke.js使用cargo run --bin control-plane-admin,走 Rust admin CLI。sqlitefallback、admin CLI、legacy evidence/local_search 不在脚本纪律约束范围内。- 已退役 AI host 自身 SQLite 不绑定本轮 control-plane Turso 切换;历史迁移说明保留在 recycle 归档中。
7.4 违规后果
- 直接
sqlite3写 control-plane DB 会导致多个进程同时写同一个 SQLite 文件,增加 WAL 损坏和并发写入冲突的风险。 - 直接写库的脚本在切换到 Turso/libSQL 后端后将无法运行。
- 违反此纪律的脚本将被要求改用上述批准路径。
具体约束条目见 AGENTS.md 中"脚本纪律"一节。