19 KiB
Test Plan — CDP 自动化全链路测试 (Round 5)
日期: 2026-07-09 环境: backend (:3000) + frontend Vite (:3036) + FakeMessagePlatform (:9100) + CDP browser (:9222) 登录: admin@gochat.local / changeme 前置条件: FakeMessagePlatform 已实现(Plan 文档 Task 1-13 全部完成),Round 4 的 28 页功能测试已通过,WebSocket 认证修复已验证。
背景
Round 4 验证了 28 页功能页面 + WebSocket 认证修复 + 实时消息推送。但以下场景因未对接消息收发平台而未被实际验证:
- 外部渠道 → GoChat:客户通过外部平台发消息,webhook 接收并创建会话
- GoChat → 外部渠道:客服回复后消息通过 provider 发回外部平台
- 多客服同时在线的消息分配
- 客服上下线状态切换对消息路由的影响
- 聊天窗口关闭/重开的对话连续性
- 打字状态指示跨渠道传递
本轮引入 FakeMessagePlatform 作为可编程的假消息平台,覆盖上述全部场景。同时保留 Round 4 的 28 页回归测试。
测试规则(继承 Round 4,无放松)
Rule 1: Console warnings ARE errors
console.warn/ Vue warnings / i18n fallback / deprecation notices 全部记录为 finding- 允许的 pre-existing warnings(不变):onClose deprecated、WootInput deprecated、Lit dev mode、Vue Router "Discarded invalid param(s)"、SW registration SecurityError
- 任何不在 allowlist 中的新 warning IS a bug
Rule 2: Network infinite request loop detection
- 每页加载并 settle 后,监控网络 10 秒
- 标记任何在无用户交互下被调用超过 3 次的端点
- 特别关注 /cable 重连循环、轮询模式、4xx/5xx 端点重试
cache_keys端点多次调用是 false-positive(各组件独立获取,settle 后停止)
Rule 3: Click-only navigation — NO URL input
- 所有页面切换通过 UI 点击(sidebar links、sub-menus、tabs、buttons)
- 唯一例外:初始登录页
/app/login - 折叠的 Settings sub-links 用 JS
.click()on<a>元素(算 UI click) window.location.href = '...'禁止用于页面导航
Rule 4: Transition error capture
- 离开页面前 capture console buffer,到达下一页后 capture
- 过渡期间出现的 error/warning 是 transition-error finding
Rule 5: CRUD interaction where applicable
- 不只是"页面加载"——在支持 CRUD 的页面至少执行一次 create/edit 操作
- 验证操作成功 + 无新 console errors + 无 infinite refetch loop
Pre-Test Setup
Step 0a: 启动全部服务
# Terminal 1: GoChat 后端 (:3000)
cd /home/yanghao05/Projects/gochat && pnpm dev:backend
# Terminal 2: Frontend Vite (:3036)
cd /home/yanghao05/Projects/gochat && pnpm dev:frontend
# Terminal 3: FakeMessagePlatform (:9100)
cd /home/yanghao05/Projects/gochat && pnpm fake:start
curl http://127.0.0.1:3000/health→ 200curl http://127.0.0.1:3036/→ 200curl http://127.0.0.1:9100/health→{"status":"ok","service":"fake-message-platform"}
Step 0b: DB schema integrity check(Round 2 BUG-7 教训)
for ep in conversations/unread_counts notifications custom_attribute_definitions/ agent_bots "custom_filters/?filter_type=conversation" "custom_filters/?filter_type=contact"; do
code=$(curl -s -o /dev/null -w '%{http_code}' -H 'X-Account-Id: 1' "http://127.0.0.1:3000/api/v1/accounts/1/$ep")
echo "$ep → $code"
done
全部返回 200(或 401 未认证),不可 500。任何 500 = 停下修 schema。
Step 0c: CDP browser + console hooks
- Chrome :9222 alive —
curl http://127.0.0.1:9222/json/version - 打开
http://127.0.0.1:3036/app/login - 注入 console hooks(
window.__consoleErrors/__consoleWarnings/__resetConsole) - 验证返回
'ok'
Step 0d: Login
- 填写 admin@gochat.local / changeme,点击登录
- 验证重定向到 dashboard
- Capture console — post-login 干净
- 验证 cookie
cw_d_session_info包含access-token
Step 0e: 创建 Fake 渠道 Inbox
通过前端 UI 创建(验证 Task 7-9 的前端兼容性):
- Sidebar → 设置 → 收件箱 → 点击"创建新收件箱"
- 渠道选择列表中找到"Fake 测试平台"卡片,点击
- 填写表单:
- 频道名称:
Fake Test Inbox - Identifier:
fake_test_1 - Webhook URL:
http://127.0.0.1:9100/receive - Token:
fake_test_token
- 频道名称:
- 点击"创建 Fake 频道"
- 验证跳转到 agent 分配页面
- 添加 admin 到此 inbox
- 验证 inbox 出现在收件箱列表中
通过 API 验证:
curl -s -H "X-Account-Id: 1" -H "Authorization: Bearer <JWT>" \
http://127.0.0.1:3000/api/v1/accounts/1/inboxes | jq '.[] | select(.channel_type=="fake")'
Step 0f: 验证 FakeMessagePlatform ↔ GoChat 连通性
# 从 FakeMessagePlatform 发一条测试消息到 GoChat
curl -X POST http://127.0.0.1:9100/api/send \
-H 'Content-Type: application/json' \
-d '{"inbox_identifier":"fake_test_1","sender_id":"smoke_test","sender_name":"连通性测试","content":"ping"}'
# 预期:GoChat 收到 webhook,创建 contact + conversation + message
# 验证 GoChat 日志中出现 "Fake webhook received" + "message persisted"
# 验证 FakeMessagePlatform 状态
curl http://127.0.0.1:9100/api/status
# 预期:sent >= 1
如果连通性测试失败,停下排查——后续所有测试依赖这条链路。
Phase 1: WebSocket /cable 验证(回归 Round 4)
- 登录后等 5s,检查后端日志
ws: connection established - 后端日志无
ws: authentication failed - 浏览器 console 无 WebSocket errors、无 /cable 401
- 网络 15s:/cable 连接一次并保持,不重复重连
- Presence indicator 显示状态(online/busy/offline)
- 直接 WS 测试:连
ws://127.0.0.1:3036/cable?access-token=<JWT>,收到{"type":"welcome"}+ 5s ping
Phase 2: 28 页功能回归测试(click navigation)
继承 Round 4 的 28 页矩阵。本轮重点验证回归——Round 4 发现的 bug 是否修复、是否回退。每页执行完整 per-page checklist(reset buffer → click → settle → console → network 10s → CRUD → backend logs → transition capture)。
| # | 页面 | 点击路径 | CRUD 测试 | 回归关注 |
|---|---|---|---|---|
| 1 | Dashboard | (post-login) | 验证会话列表 + 在线状态 | — |
| 2 | 会话详情 | 点击会话 | 发消息,验证即时送达 | — |
| 3 | 联系人 | Sidebar: 联系人 | 编辑联系人,保存 | — |
| 4 | 报告 Overview | Sidebar: 报告 → Overview | 日期选择器变化 | — |
| 5 | 报告 会话 | 报告 sub-tab: 会话 | 筛选变化 | — |
| 6 | 报告 客服 | 报告 sub-tab: 客服 | 验证表格 | — |
| 7 | 报告 标签 | 报告 sub-tab: 标签 | 验证加载 | — |
| 8 | 报告 收件箱 | 报告 sub-tab: 收件箱 | 验证加载 | — |
| 9 | 报告 团队 | 报告 sub-tab: 团队 | 验证加载 | — |
| 10 | 报告 CSAT | 报告 sub-tab: 客户满意度 | 验证加载 | — |
| 11 | 报告 SLA | 报告 sub-tab: SLA | 验证 SLA 指标 | — |
| 12 | 报告 机器人 | 报告 sub-tab: 机器人 | 验证加载 | BUG-A 回归:从 Reports 页面内点"机器人" sidebar link 是否跳转 |
| 13 | 活动 | Sidebar: 活动 | 验证页面加载 | BUG-1 回归:路由是否正常 |
| 14 | 帮助中心 | Sidebar: 帮助中心 | 点击 portal,验证文章 | — |
| 15 | 设置 账户设置 | Settings → 账户设置 | 更新字段,保存 | — |
| 16 | 设置 客服代理 | Settings sub: 客服代理 | 验证列表 + 搜索 | — |
| 17 | 设置 团队 | Settings sub: 团队 | 打开创建团队向导 | — |
| 18 | 设置 收件箱 | Settings sub: 收件箱 | 点击 inbox config,加载全部 tab | BUG-C 回归:预聊天表单 tab |
| 19 | 设置 标签 | Settings sub: 标签 | 创建标签 | BUG-3 回归:intlify empty key warning |
| 20 | 设置 自定义属性 | Settings sub: 自定义属性 | 切换 tab | — |
| 21 | 设置 自动化 | Settings sub: 自动化 | 验证列表 | — |
| 22 | 设置 机器人 | Settings sub: 机器人 | 验证列表 | BUG-2 回归:sidebar click nav |
| 23 | 设置 宏 | Settings sub: 宏 | 验证列表 | — |
| 24 | 设置 预设回复 | Settings sub: 预设回复 | 创建预设回复 | — |
| 25 | 设置 集成方式 | Settings sub: 集成方式 | 点击配置一个 | — |
| 26 | 设置 会话工作流 | Settings sub: 会话工作流 | Toggle switch | — |
| 27 | 设置 客服分配 | Settings sub: 客服分配 | 验证表单 | — |
| 28 | 个人资料 | Avatar dropdown → profile | 更新资料,保存 | — |
回归判定标准
| Bug | Round 4 状态 | Round 5 判定 |
|---|---|---|
| BUG-1 (P2) Activity 路由缺失 | FIXED | 点击"活动" → campaigns 页面加载 → FIXED |
| BUG-2 (P3) Bots sidebar 导航 | FIXED | Settings → 机器人 → 导航到 agent-bots → FIXED |
| BUG-3 (P4) intlify empty key | PERSISTING | 创建标签时无 [intlify] Not found '' → FIXED;仍有 → PERSISTING |
| BUG-A (P3) Bot Reports 侧栏导航 | NEW | 从 Reports 页面点"机器人" → 跳转到 /reports/bot → FIXED;不跳转 → PERSISTING |
| BUG-C (P2) 预聊天表单 null | FIXED | inbox settings → 预聊天表单 tab → 无 Vue warn → FIXED |
Phase 3: FakeMessagePlatform 全链路消息测试(本轮新增核心)
这是 Round 5 的核心差异——通过 FakeMessagePlatform 驱动真实的外部渠道消息流。
3.1 客户发消息 → GoChat 创建会话
- 通过 FakeMessagePlatform 发送消息:
curl -X POST http://127.0.0.1:9100/api/send \ -H 'Content-Type: application/json' \ -d '{"inbox_identifier":"fake_test_1","sender_id":"customer_001","sender_name":"测试客户A","content":"你好,我需要帮助"}' - 前端 Dashboard 看到新会话出现(Fake Test Inbox 渠道)
- 会话列表显示客户名"测试客户A"和消息预览"你好,我需要帮助"
- 点击会话,消息出现在聊天窗口
- 后端日志:
Fake webhook received+message persisted - Console 无新错误
3.2 客服回复 → FakeMessagePlatform 收到出站消息
- 在前端会话详情页,客服输入回复"您好,有什么可以帮您?",Ctrl+Enter 发送
- 消息即时出现在聊天窗口(WS 实时推送)
- FakeMessagePlatform 收到出站消息:
预期:返回包含
curl http://127.0.0.1:9100/api/messages?inbox_identifier=fake_test_1"content":"您好,有什么可以帮您?"的消息 - 消息 sender.type 为 "agent"
- Console 无新错误
3.3 客户回复 → 消息追加到同一会话
- 通过 FakeMessagePlatform 回复:
curl -X POST http://127.0.0.1:9100/api/reply \ -H 'Content-Type: application/json' \ -d '{"inbox_identifier":"fake_test_1","sender_id":"customer_001","content":"我的订单有问题","reply_to_id":"<agent_msg_source_id>"}' - 前端会话详情页:新消息追加到聊天窗口底部(不创建新会话)
- 消息 sender 为客户"测试客户A"
- Console 无新错误
3.4 多客户并发会话
- 同时发送两个不同客户的消息:
curl -X POST http://127.0.0.1:9100/api/send \ -H 'Content-Type: application/json' \ -d '{"inbox_identifier":"fake_test_1","sender_id":"customer_002","sender_name":"测试客户B","content":"退款咨询"}' & curl -X POST http://127.0.0.1:9100/api/send \ -H 'Content-Type: application/json' \ -d '{"inbox_identifier":"fake_test_1","sender_id":"customer_003","sender_name":"测试客户C","content":"技术支持"}' & - 前端会话列表出现 3 个独立会话(A/B/C)
- 每个会话的消息内容正确对应
- Console 无新错误
3.5 打字状态指示
- 触发客户打字状态:
curl -X POST http://127.0.0.1:9100/api/typing \ -H 'Content-Type: application/json' \ -d '{"inbox_identifier":"fake_test_1","sender_id":"customer_001","typing":true}' - 前端会话详情页显示"正在输入..."指示器(如果 UI 支持)
- 停止打字:
curl -X POST http://127.0.0.1:9100/api/typing \ -H 'Content-Type: application/json' \ -d '{"inbox_identifier":"fake_test_1","sender_id":"customer_001","typing":false}' - 指示器消失
- Console 无新错误
3.6 聊天窗口关闭(session end)
- 关闭客户会话:
curl -X POST http://127.0.0.1:9100/api/close \ -H 'Content-Type: application/json' \ -d '{"inbox_identifier":"fake_test_1","conversation_id":"<external_conv_id>","sender_id":"customer_001"}' - GoChat 收到 session.end 事件,创建 "[session ended]" 消息
- 前端会话显示系统消息或状态变化
- Console 无新错误
- 同一客户再次发消息 → 创建新会话(如果 inbox 配置 lock_to_single_conversation=false)
3.7 消息附件
- 发送带附件的消息:
curl -X POST http://127.0.0.1:9100/api/send \ -H 'Content-Type: application/json' \ -d '{"inbox_identifier":"fake_test_1","sender_id":"customer_001","sender_name":"测试客户A","content":"请看这张截图","content_type":"image","attachments":[{"url":"http://example.com/screenshot.png","content_type":"image/png","filename":"screenshot.png","file_size":102400}]}' - 前端会话详情页显示附件预览(图片缩略图或文件链接)
- Console 无新错误
Phase 4: 多客服消息分配测试(本轮新增)
4.1 单客服在线 — 所有消息分配给该客服
- 确保 Fake Test Inbox 启用 auto_assignment
- 确保只有一个客服(admin)在线
- FakeMessagePlatform 模拟客服上线:
curl -X POST http://127.0.0.1:9100/api/agent/online \ -H 'Content-Type: application/json' \ -d '{"agent_id":"1","agent_name":"Admin"}' - 发送新客户消息 → 验证会话自动分配给 admin
- 前端会话列表中该会话 assignee 为 admin
4.2 多客服在线 — 轮询分配
- 创建第二个客服用户(通过 Settings → 客服代理)
- 将第二个客服添加到 Fake Test Inbox
- 两个客服同时在线
- 连续发送 3 条不同客户的消息
- 验证会话按 round-robin 或 least_busy 策略分配给不同客服
- 前端各客服的会话列表显示分配给自己的会话
4.3 客服下线 — 消息不分配给离线客服
- 第二个客服下线:
curl -X POST http://127.0.0.1:9100/api/agent/offline \ -H 'Content-Type: application/json' \ -d '{"agent_id":"2"}' - 发送新客户消息 → 验证会话只分配给在线的 admin
- 不分配给已下线的客服
4.4 全部客服下线 — 消息进入未分配队列
- admin 也下线
- 发送新客户消息 → 验证会话创建但 assignee 为空(未分配)
- 客服上线后 → 验证是否自动补分配(取决于 assignment policy 配置)
Phase 5: 实时 WebSocket 功能验证(含跨渠道)
5.1 基础实时推送(回归 Round 4)
- 打开会话,发消息 → 即时出现
- 后端日志:
message.createdevent dispatched - Presence indicator 显示正确状态
- 网络 30s:/cable 稳定,无 401,无重连风暴
- 直接 WS 测试:welcome + 5s ping
5.2 跨标签页实时推送(回归 Round 4)
- Tab 2 同账号登录,reload dashboard
- Tab 1 发消息 → Tab 2 会话列表预览更新 + 会话详情消息出现
- 无需手动刷新
5.3 FakeMessagePlatform 触发的实时推送(新增)
- Tab 1 打开 customer_001 的会话
- 通过 FakeMessagePlatform 发送 customer_001 的新消息
- Tab 1 聊天窗口即时显示新消息(WS 推送,非轮询)
- Tab 2 如果也打开同一会话 → 同样即时显示
- 后端日志:
Fake webhook received→message persisted→ws: message command(WS 推送)
Phase 6: 收集与报告
Issue severity(继承 Round 4)
| Sev | 定义 |
|---|---|
| P0 | 功能损坏,阻断核心工作流,或无限循环导致资源耗尽 |
| P1 | 核心功能损坏但有 workaround;或重复 console errors 降低 UX |
| P2 | 非核心功能损坏,或 warnings 指向真实代码问题 |
| P3 | 轻微 cosmetic/edge-case,无功能影响 |
| P4 | 纯噪声(dev-mode warnings、deprecation 无用户影响) |
报告文件
写入 docs/qa/2026-07-09-qa-report-round5.md。
必须包含的章节:
- Summary — 总页数/通过/失败数 + FakeMessagePlatform 集成测试结果概要
- 服务启动验证 — backend/frontend/fake-platform 三个服务的健康检查结果
- Fake Inbox 创建验证 — 前端 UI 创建 fake 渠道 inbox 的过程和结果
- WebSocket 验证 — /cable 状态、welcome/ping、无 401
- 28 页回归测试结果表 — 页面、点击路径、通过/失败、findings
- FakeMessagePlatform 全链路测试结果(Phase 3 每个子项)
- 多客服消息分配测试结果(Phase 4 每个子项)
- 实时 WebSocket 功能验证(Phase 5 每个子项)
- Findings — 每个 issue:severity、复现步骤(click path + curl command)、预期 vs 实际、console errors、screenshot path、根因方向、影响文件
- Known issues 回归验证 — BUG-1/2/3/A/C 的 Round 5 状态
- 后端错误观察 — 500s、panics、WS auth failures
- 测试备注 — 测试了什么、跳过了什么、blockers
截图
每个 finding 截图:
browser_vision(question="Capture the issue: <description>", annotate=false)
在 CLI 模式下陈述截图的绝对路径(不使用 MEDIA: tag)。
文档清理
按 known-bugs.md 的 cleanup policy:
- 将 Round 4 的
docs/qa/2026-07-09-qa-report-round4.md和docs/qa/2026-07-09-test-plan-round4.md删除 - 将 Round 5 报告中的新发现合并到
references/known-bugs.md - 更新 known-bugs.md 的 "Consolidated from QA rounds 1–5" 行
- 保留 Round 5 的报告和测试计划作为当前版本
验证 Checklist
- 三个服务(backend :3000 + frontend :3036 + fake :9100)全部启动并健康
- DB schema integrity check:6 个历史端点全部 200(非 500)
- Console hooks 注入成功
- Login 成功,cookie 包含 access-token
- Fake 渠道 Inbox 通过前端 UI 成功创建
- FakeMessagePlatform → GoChat 连通性测试通过
- /cable WebSocket 连接稳定(welcome + ping + 无 401)
- 28 页全部通过 click navigation 测试(或标注 exception)
- 每页:reset buffer → navigate → settle → console → network 10s → CRUD → logs → transition
- Phase 3 全链路消息测试:发消息/回复/多客户/打字/关窗口/附件 全部验证
- Phase 4 多客服分配:单客服/多客服轮询/下线/全下线 全部验证
- Phase 5 实时推送:基础/跨标签页/FakePlatform 触发 全部验证
- 报告写入
docs/qa/2026-07-09-qa-report-round5.md - 每个 finding 有:severity、复现步骤(click path + curl)、console errors、screenshot path、根因
- Known bugs 回归验证:BUG-1/2/3/A/C 状态更新
- 旧轮报告清理(Round 4 report + test plan 删除)
- known-bugs.md 更新(新发现 + 状态变更 + "rounds 1–5")