Files
gochat/docs/qa/2026-07-15-cdp-user-function-test-plan.md
T
2026-07-27 15:50:18 +08:00

51 KiB
Raw Blame History

CDP 用户功能全量测试计划

创建:2026-07-15
最后更新:2026-07-22
目标:连接已启动的 GoChat 本地服务,用 Chrome DevTools Protocol 按真实用户路径覆盖 dashboard / widget / settings / Captain / Copilot / public surfaces。
当前服务由人工启动,不由测试脚本托管。

0. 当前前提

已启动:

pnpm dev:backend
pnpm dev:frontend
GOCHAT_WEBHOOK_URL=http://127.0.0.1:3000/webhooks/fake/fake_01 FAKE_AUTO_REPLY=true pnpm fake:start

本轮计划默认以上述三条人工启动命令为权威运行基线;后续 CDP 验收、数据补齐清单、以及 fake:ai 设计都以这套本地端口和进程拓扑为前提。

0.1 当前推荐的 CDP 连接方式(Sunday, July 19, 2026)

这轮计划默认优先复用已经打开的 Chrome,会比重新拉起 headed 浏览器更稳,也更符合“接现有人工会话继续点测”的目标。

建议默认使用:

项 值 说明
CDP debug port 127.0.0.1:9222 优先 attach 已存在的 Chrome 会话
version probe http://127.0.0.1:9222/json/version 读取 webSocketDebuggerUrl
当前可复用 CLI /home/rogee/.npm/_npx/15c61037b1978c83/node_modules/chrome-devtools-mcp/build/src/bin/chrome-devtools.js 已在当前 QA 流程中实际使用过

建议连接顺序:

  1. 先请求 http://127.0.0.1:9222/json/version,确认能拿到 webSocketDebuggerUrl。
  2. 成功后直接 attach,不重新登录、不重开新浏览器。
  3. 进入测试前先做一次 snapshot,确认当前 tab、当前账号、当前 account id。
  4. 若 9222 不可用,再退回新开 Chrome,并固定 --remote-debugging-port=9222,避免同一轮报告里混入多套浏览器状态。

连接成功标准:

  • json/version 返回 200;
  • 能对当前 tab 成功 snapshot;
  • 能读取 console / network;
  • 能通过真实点击让页面发生路由变化。

0.2 测试环境异常时的重置策略(Wednesday, July 22, 2026)

这轮点测里已经确认过:测试环境一旦进入“持续重连 / /cable 抖动 / 页面大量 429 / fake 平台残留旧消息”的脏状态,继续硬点只会把环境噪音和真实缺陷混在一起。因此后续执行时,把“允许重置并继续”写成正式策略,而不是临场救火。

重置优先级:

  1. 先重置 fake 平台内存态,不动前后端。
  2. 若 dashboard 已出现连续 429、正在重连... 挡点击、或 /cable 无法恢复,再重启 backend。
  3. frontend 只在 Vite 自身白屏、热更新异常、或静态资源 5xx 时才重启。
  4. 浏览器 tab 状态明显污染时,可以保留现有 Chrome/CDP 会话,但需要重新从 /app/login 走一遍点击链路。

推荐重置动作:

curl -fsS -X POST http://127.0.0.1:9100/api/reset
curl -fsS http://127.0.0.1:3000/health
curl -fsS http://127.0.0.1:9100/health

若 backend 已进入脏状态,直接重新执行:

pnpm dev:backend

若 fake 进程已退出或 webhook 指向失效,重新执行:

GOCHAT_WEBHOOK_URL=http://127.0.0.1:3000/webhooks/fake/fake_01 FAKE_AUTO_REPLY=true pnpm fake:start

重置后的恢复标准:

  • GET /health 返回 200。
  • GET http://127.0.0.1:9100/health 返回 {"status":"ok"}。
  • 登录后 /cable 不再持续 401/403/断开重连。
  • dashboard 底部不再常驻 正在重连... 浮层。
  • 同一页面不再连续出现大批量 429。

报告要求:

  • 一旦发生重置,必须在 QA report 中记下“重置原因 / 重置动作 / 重置后恢复结果”。
  • 重置后恢复通过的页面,要和“真实功能缺陷”分开归类,避免把环境污染误记成产品 bug。

测试入口:

服务 URL 用途
backend http://127.0.0.1:3000 API、webhook、WebSocket
frontend http://127.0.0.1:3036 dashboard / widget 前端
fake channel http://127.0.0.1:9100 外部客户消息、出站消息断言
CDP http://127.0.0.1:<debug-port> 连接现有 Chrome,优先不新开 headed browser

1. 测试目标

  1. 用 CDP 模拟真实用户点击、输入、上传、保存、导航、退出登录。
  2. 每个页面至少验证:可打开、核心数据加载、主要操作可执行、错误态可见、无异常 API/console、刷新后状态仍正确。
  3. 消息链路必须验证:客户入站 → dashboard 实时出现 → 客服回复 → fake 收到出站 → auto reply 回流 → dashboard 无刷新更新。
  4. Chatwoot parity 相关页面以“前端实际请求成功 + UI 可用”为准,不只看路由存在。
  5. AI/Copilot/Captain 测试不依赖真实 LLM Key;先补 fake:ai,让页面功能和后端调用链可自动断言。
  6. 除登录页、widget/public 入口页外,dashboard 内部页面一律通过真实 UI 点击进入,不直接 open 深层内部 URL,避免把路由可达误判成用户可达。

2. CDP 执行协议

每个页面统一记录:

  • page.url
  • document.title
  • #app 是否挂载
  • console error / warning
  • Network.responseReceived 中所有 /api、/platform、/public、/cable、/webhooks 的状态码
  • Runtime.exceptionThrown
  • 关键 DOM 文案或按钮存在性
  • 操作前后截图
  • 操作产生的 API 请求和响应摘要

导航约束:

  • 允许直接打开:/app/login、widget/public 根入口、必要的外部 fake/fake:ai 观察接口。
  • 不允许直接打开:/app/accounts/:id/... 下的深层功能页作为“通过”依据。
  • dashboard 内导航必须由登录后侧边栏、列表项、按钮、tab、面包屑、弹窗入口逐步点击完成。
  • 若页面只能通过手输 URL 才能访问,记录为信息架构或入口缺失问题,而不是直接算页面通过。

失败分级:

等级 标准
P0 登录失败、dashboard 不可用、消息收发断、权限泄露、数据保存丢失
P1 页面主要 CRUD 不可用、关键 API 4xx/5xx、实时事件错误
P2 局部功能不可用、空态错误、表单校验不清晰
P3 文案、布局、轻微 console warning、非阻断体验问题

最小 CDP harness 只需要:

  1. 连接 http://127.0.0.1:<debug-port>/json/version 拿 webSocketDebuggerUrl。
  2. Page.enable、Runtime.enable、Network.enable。
  3. 注入 window.__gochatQa 记录 console、fetch、XHR、resource timing。
  4. 用 Runtime.evaluate 点击和输入;必要时用 Input.dispatchKeyEvent。
  5. 每个页面结束调用 assertNoFailedBackendRequests()。

跳过:新测试框架、复杂 Page Object、视觉 diff。等第一轮人工可读报告稳定后再加。

3. 预检查

检查 命令/动作 通过标准
backend health GET /health 200
frontend mount 打开 http://127.0.0.1:3036/app/login login 页面可见
fake health GET http://127.0.0.1:9100/health status=ok
CDP tooling command -v npx && node --version && npm --version npx 可用,Node/npm 正常
fake 配置 POST /api/config webhook 指向 fake_01,auto reply 开启
登录账号 seed 或 DB 查询 管理员、客服、普通 agent 可登录
WebSocket 登录后监听 /cable 不循环 401/403/重连
route parity 基线 参考 docs/parity/route-parity.md 页面请求不应出现缺失路由

4. 基础测试数据缺口

需要补齐这些数据,否则“全量实际功能测试”会退化成空态浏览:

数据 最低数量 用途
Account 1 主测试租户
Administrator 1 设置、成员、平台配置
Agent 2 分配、团队、在线状态、跨坐席实时
Custom role 用户 1 权限边界
Fake inbox fake_01 1 消息 E2E
Website inbox 1 widget、pre-chat、campaign
API inbox 1 inbox 类型覆盖
Email inbox 1 邮件配置、SMTP/IMAP 页面
Voice/Twilio inbox 1 voice 设置页和降级态
Contact 8+ 列表、搜索、合并、标签、公司
Company 3+ 公司详情、联系人关联
Conversation 12+ open/resolved/pending/snoozed、assignee、team、label、priority
Messages 每会话 3+ incoming/outgoing/private/note/attachment/email
Labels 5 会话/联系人标签、报表
Teams 2 团队分配、团队报表
Canned responses 3 回复框插入、CRUD
Macros 3 宏执行、条件动作
Automation rules 3 create/edit/clone/delete、条件校验
Custom attributes contact/conversation/company 各 2 表单渲染、筛选
SLA policies / applied SLA 2 SLA 报表
CSAT responses 5 CSAT 报表、公开页
Dashboard apps 1 侧边栏 iframe/app surface
Webhook subscriptions 2 集成 webhook CRUD
Help center portal 1 portal、locale、category、article
Campaigns live chat / sms / whatsapp 各 1 campaign 页面
Notifications 5 通知列表、已读
Audit logs 5 audit 页面
Agent capacity policies 2 assignment policy
Captain assistant 1 Captain 页面根对象
Captain document 3 文档列表、上传/同步状态
Captain response/FAQ 5 responses、pending
Captain scenario 2 scenario 页面
Captain custom tool 1 tools 页面
Copilot config 1 fake provider AI 功能不打真实外网

4.1 首轮必须先补的数据(否则会大面积 blocked)

优先级 数据 最低要求 影响范围
P0 Administrator 1 个可登录管理员 所有 settings / Captain / reports
P0 Agent 2 个可登录 agent 分配、协作、在线状态、mentions
P0 Fake inbox fake_01 已绑定 webhook 且可收发 会话主链路、实时消息
P0 Website inbox 1 个带 website_token 的 live chat inbox widget、pre-chat、campaign
P0 基础 conversations/messages 至少 6 个会话、每个 3 条消息 dashboard 列表、详情、筛选、报表
P1 Labels / Teams labels 5 个、teams 2 个 标签、团队过滤、自动化、报表
P1 Contacts / Companies contacts 8+、companies 3+ CRM、搜索、合并、关联
P1 Custom attributes 三类对象各 2 个 筛选器、详情表单、自动化
P1 Canned responses / Macros 各 3 条 回复提效、设置页 CRUD
P1 Automation rules 3 条可编辑规则 自动化列表、编辑、校验
P1 Copilot fake provider 1 套假配置 Copilot/Captain 页面进入与联调
P2 Help center portal 1 portal + category + article portal/public/help center
P2 Campaigns live chat 至少 1 条 campaign 页面、widget 触发
P2 CSAT / SLA 数据 CSAT 5 条、SLA 2 条 报表、公开页、inbox csat
P2 Audit logs / notifications 各 5 条 列表页、跳转、筛选

建议策略:

  1. 能由 UI 自举创建的,优先在首轮 CDP 中顺手创建并复用。
  2. 会阻断主链路的种子数据(管理员、agent、fake/website inbox、基础 conversations)应在执行前一次性准备好。
  3. Captain/Copilot 相关不要等真实第三方 Key,直接用 fake:ai 打通请求与错误态。

4.2 数据准备方式建议

把“缺数据”再分成三类,执行时更省时间:

类别 数据 建议来源 是否需要执行前准备 备注
A Administrator / Agent / Custom role 用户 seed + 后台 Settings 手工补齐 是 登录、权限、分配依赖它们
A Fake inbox fake_01 当前 fake channel + inbox 配置 是 主消息链路阻断项
A Website inbox Settings 新建或 seed 是 widget / campaign / pre-chat 依赖
A 基础 conversations / messages fake channel 批量造数 是 推荐至少覆盖 open / pending / resolved / snoozed
B Contacts / Companies / Labels / Teams 优先走 UI 创建,缺口再补 seed 否 同时可顺手验证 CRUD
B Canned responses / Macros / Automation rules 走 UI 创建 否 适合首轮 CDP 过程中创建并复用
B Custom attributes 走 UI 创建 否 可直接覆盖表单和筛选能力
B Help center portal / locale / article 走 UI 创建 否 既补数据又验证 portal 后台
C CSAT / SLA / Audit logs / Notifications 定向 seed 或接口回灌 视页面而定 纯空态也能先验渲染,但无法完成“全量功能”断言
C Captain documents / responses / scenarios / tools fake:ai + Captain 后台创建 是(若要做 AI 主链路) 没有 fake:ai 时只能做页面渲染检查
C Campaigns(live chat / sms / whatsapp) Settings / Campaign UI 创建 否 需要 website inbox 与 portal 先到位

建议最小准备顺序:

  1. 先准备管理员、2 个 agent、fake_01、website inbox。
  2. 用 fake channel 批量灌入基础会话和消息。
  3. 再通过 UI 顺手创建 labels / teams / macros / canned responses / custom attributes。
  4. AI 相关最后统一切到 fake:ai,避免前面主链路被外部依赖拖住。

4.3 当前仓库已具备的数据准备能力 vs 仍需补齐项

为了避免把“已有 smoke seed 能力”和“真正缺失的数据/能力”混为一谈,这里按当前仓库实际情况再拆一次。

当前仓库里已经存在可直接复用的 smoke seed 基线,入口是:

cd backend
go run ./cmd/gochat seed

按当前 cmd/gochat seed 的实现,已经能稳定准备出这些基础对象:

类别 当前 seed 覆盖情况 备注
Administrator 已覆盖 1 个 默认 admin@gochat.local / changeme,可通过环境变量覆盖
Account 已覆盖 1 个 默认 Test Account
Website inbox 已覆盖 1 个 web_widget inbox,带 website_token
Voice/Twilio-like inbox 已覆盖 1 个 当前是 twilio_sms 型 smoke inbox,适合页面和降级态验证
Contact 已覆盖 1 个 Smoke Customer
Company 已覆盖 1 个 Smoke Company
Conversation 已覆盖 1 个 已绑定 contact / inbox / assignee
Messages 已覆盖 3 条 incoming / outgoing / CSAT template 各 1 条
Help Center portal/category/article 已覆盖 1 套 适合 articles / preview / public help center 基线
CSAT 已覆盖 1 条模板消息 够做基础渲染,不够做分布/列表型报表
SLA policy 已覆盖 1 条 够做基础页面进入
Custom role 已覆盖 1 条 可做权限页基线
Capacity policy 已覆盖 1 条 可做 assignment policy 基线
Captain assistant 已覆盖 1 条 只够列表/详情基线,不够真实 AI 回路
Captain message 已覆盖 1 条 适合 conversation 内 Captain message 渲染
Agent bot 已覆盖 1 条 适合 agent bot 页面基线

基于当前代码和脚本,仍然明确缺失、会影响“全量实际功能测试”的项如下:

优先级 缺失项 为什么缺 直接影响
P0 第二个可登录 agent 当前 smoke seed 只准备管理员,没有双坐席协作基线 分配、在线状态、mentions、团队协作、跨坐席实时
P0 fake_01 对应 inbox 基线 当前 seed 侧重 web_widget smoke inbox,不是 fake channel inbox fake webhook 主链路、会话实时回流、回复 E2E
P0 6+ 条不同状态会话 当前 seed 只有 1 条 open conversation dashboard 列表、筛选、报表、批量操作、状态流转
P0 更丰富的消息类型 当前仅 text + CSAT template private note、attachment、email、AI 消息、系统事件渲染
P1 Teams 2 条以上 当前未见 smoke team 基线 team 过滤、team assign、team report
P1 Labels 5 条以上 当前会话只有字符串标签,不是完整标签数据集 标签设置页、筛选器、报表
P1 Contacts 8+ / Companies 3+ 当前各只有 1 条 CRM 列表、搜索、合并、关联、空态外真实分页
P1 Canned responses / Macros / Automations 当前 seed 未覆盖 设置 CRUD、回复提效、自动化规则
P1 Custom attributes 三类对象各 2 条 当前仅对象上有少量属性值,不是完整属性定义 表单、筛选、详情编辑
P1 Notifications / Audit logs 有内容 当前 seed 未覆盖可见事件流 通知页、审计日志页、跳转链路
P1 Copilot fake provider 当前仓库只有真实配置入口,没有本地 fake provider 基线 Copilot/Captain 成功/失败/超时/429 验证
P2 Email inbox / API inbox 当前 smoke seed 未覆盖 channel create/edit、provider 配置、空态/降级态之外的实际流程
P2 Campaign 样本 当前未覆盖 live chat / sms / whatsapp 实例 campaign 列表、编辑、启停、触发条件
P2 Captain documents / responses / scenarios / tools 当前仅 assistant/message 基线 Captain 子页 CRUD、embedding、playground、tool 调用
P2 多 locale Help Center 数据 当前 seed 基本是单 portal、单 locale locales / categories / settings 多语言验证

建议把数据准备再拆成三条线并行推进:

  1. cmd/gochat seed 继续承担“可登录 + 可进入页面”的 smoke 基线。
  2. channels/fake 负责批量制造真实消息、会话状态变化、typing、agent online/offline。
  3. 新增 fake:ai 后,再把 Copilot / Captain 的成功、失败、超时、429 路径补齐成可回放证据。

4.4 按页面分组看数据阻断关系

为了执行时不把“页面 bug”和“数据没准备好”混为一谈,建议按页面分组提前标记它们依赖的最小数据集:

页面组 最小依赖数据 缺失时会怎么 blocked
登录 / 账号切换 / Profile administrator、至少 1 个 account、至少 1 个可登录 agent 无法进入主应用、无法验证 account switch / profile 保存
Dashboard / Conversations / Mentions / Unattended fake_01 inbox、6+ conversations、3+ message types、2 个 agent 列表空、实时链路无证据、分配/协作不可测
Contacts / Companies 8+ contacts、3+ companies、custom attributes 只能看到空态,搜索/合并/关联无法完成
Reports conversations、labels、teams、CSAT、SLA、audit/event 数据 图表和表格只剩空态,无法验证筛选/导出/维度切换
Settings - Agents / Teams / Labels 2 个 agent、2 个 teams、5 个 labels、1 个 custom role 只能验渲染,无法验成员绑定、权限边界、筛选联动
Settings - Inboxes / Channel create website inbox、fake inbox、api/email/voice 至少部分样本 只能看入口,无法验证编辑页、collaborators、business hours、channel 特有字段
Settings - Automation / Macros / Canned Responses 3 automation、3 macros、3 canned responses 列表可打开但无法验证 CRUD 与执行结果
Help Center 1 portal、1 locale、2 categories、3 articles 只能做最浅页面进入,发布/预览/分类/多语言不完整
Campaigns website inbox、portal、至少 1 live chat campaign 样本 只能看空态,无法验证创建/启停/触发条件
Notifications / Audit logs 5+ notifications、5+ audit logs 只能确认页面壳存在,跳转和已读不可测
Copilot / Captain fake provider、assistant、documents、responses、scenarios、tools 只能验页面渲染,无法做 AI 成功/失败/超时全链路
Widget / public website inbox、public help center、CSAT 样本、真实站内入口 即使内部后台健康,也无法完成 public/user 侧闭环验收

推荐执行时先给每个页面组打一个前置标签:

  • ready:数据和入口都齐,可以做完整功能断言
  • render-only:只能做渲染/空态/入口断言
  • blocked-by-data:缺数据,先补数据再测
  • blocked-by-entrypoint:入口未接通,不应靠手输内部 URL 绕过

5. fake:ai 最小方案

先加一个本地 fake AI 服务,目标是“可测”,不是模拟完整 LLM。

建议命令:

pnpm fake:ai

建议端口:9200。

最小 API:

方法 路径 用途 响应
GET /health 健康检查 { "status": "ok" }
GET /v1/models OpenAI-compatible 模型列表 fake-chat, fake-embedding
POST /v1/chat/completions Copilot / Captain 回复 回显 prompt 摘要,支持固定 delay/error
POST /v1/embeddings 文档 embedding 固定维度向量
POST /api/config 切换模式 ok/error/slow/rate_limit
GET /api/requests 测试断言 最近请求列表,脱敏 Authorization
POST /api/reset 清空状态 { "status": "ok" }

Provider 配置建议:

字段 值
provider openai_compatible
base_url http://127.0.0.1:9200/v1
api_key fake-ai-key
chat model fake-chat
embedding model fake-embedding
embedding dimensions 1536

必须覆盖的 AI 场景:

  1. Copilot 配置页保存 fake provider。
  2. 测试连接成功、失败、超时、429 四种状态。
  3. Captain Playground 输入问题,收到 fake answer。
  4. Captain document embedding 调用 fake embeddings。
  5. Agent 回复框 AI 改写/建议调用 fake chat。
  6. 错误态不泄露 API key。

跳过:真实 OpenAI/Anthropic/DeepSeek 兼容性;等 fake 链路稳定再做外部 provider smoke。

5.1 fake:ai 实现方式建议(直接复用 fake channel 骨架)

为了少造轮子,fake:ai 建议直接按 channels/fake 的组织方式复制一套最小骨架:

项 建议
目录 channels/fake-ai/
启动脚本 根 package.json 增加 fake:ai / fake:ai:dev / fake:ai:test
运行时 tsx src/index.ts
HTTP 框架 继续用 Express,和 fake channel 保持一致
状态存储 先用内存 store,记录最近请求、模式、延迟、错误注入
模式切换 /api/config 支持 ok / error / slow / rate_limit
测试断言 /api/requests 返回最近 chat / embeddings 请求摘要
脱敏 所有请求日志都隐藏 Authorization / api_key

建议脚本:

{
  "fake:ai": "cd channels/fake-ai && tsx src/index.ts",
  "fake:ai:dev": "cd channels/fake-ai && tsx watch src/index.ts",
  "fake:ai:test": "pnpm --dir channels/fake-ai test"
}

这样后续维护会和 fake:start 基本同构,排查成本也低。

补充说明:当前仓库根 package.json 里已经有 fake:start / fake:dev / fake:test,并且 pnpm-workspace.yaml 已纳入 channels/fake;但还没有现成的 channels/fake-ai 目录和 fake:ai 脚本,所以这部分目前仍属于待新增测试支撑能力,而不是现成可执行项。

5.2 fake:ai 断言矩阵

fake:ai 不只是“让页面不报错”,还要能作为 CDP 回放时的稳定证据源。建议第一版就固定支持下面这几类断言:

场景 CDP 页面动作 fake:ai 需要返回 测试证据
Provider 连通性测试 Settings → Copilot → Test connection 200 + 固定模型列表 页面成功提示 + /api/requests 有 GET /v1/models
Provider 保存后首次使用 保存 fake provider 后进入 Copilot/Captain GET /v1/models 或首次 chat 请求成功 配置持久化成功 + 后续 AI 页面可继续使用
Copilot 发问 会话侧边栏输入问题并发送 POST /v1/chat/completions 返回固定答复 气泡渲染 + /api/requests 记录 prompt 摘要
Captain Playground Playground 输入问题 POST /v1/chat/completions 返回固定答复 页面回复 + 请求日志
Reply suggestion / rewrite / summarize 回复框触发 AI 建议 POST /v1/chat/completions 返回不同 action 标记 建议文本正确落入 UI,对应 action 可区分
Document embedding 上传 URL/PDF 文档后触发 embedding POST /v1/embeddings 返回固定维度向量 文档状态变化 + /api/requests 有 embedding 记录
Slow provider 切到 slow 模式后重试 延迟 3~8 秒再返回 200 页面 loading、可取消/可恢复、无死锁
Error provider 切到 error 模式后重试 500 或结构化错误 toast / inline error 正确展示,不泄露 key
Rate limit 切到 rate_limit 模式 429 页面可见限流反馈、不会假成功
敏感信息脱敏 任意 AI 请求 fake:ai 仅记录掩码后的鉴权信息 /api/requests 不出现明文 Authorization / api_key

建议 fake:ai 每条请求至少记录这些字段,便于后续 report 复用:

  • ts
  • method
  • path
  • mode
  • model
  • account_id(若请求链路可带出)
  • request_summary(截断后的 prompt/输入摘要)
  • response_status
  • latency_ms
  • auth_masked

5.3 当前仓库核对结果(2026-07-19)

这部分是为了把“计划建议”和“当前仓库现实”分开:

项 当前状态 结论
根脚本 fake:start / fake:dev / fake:test 已存在 fake channel 现成可用,可直接作为消息 E2E 基线
根脚本 fake:ai 不存在 需要新增
workspace 包 当前只纳入 frontend、channels/fake channels/fake-ai 需要加入 workspace
channels/fake-ai/ 目录 不存在 需要新建最小服务骨架
现有 channels/fake 结构 已具备独立 package + tsconfig 适合直接镜像出 fake-ai 的最小实现

因此,“AI 相关测试可参考 fakechannel 搞一个 fake:ai 来支持对接”在当前仓库里应拆成明确的补齐任务:

  1. 新建 channels/fake-ai/,提供独立 package.json、tsconfig.json、src/index.ts。
  2. 根 package.json 增加 fake:ai、fake:ai:dev、fake:ai:test。
  3. pnpm-workspace.yaml 纳入 channels/fake-ai。
  4. 提供最小 /health、/v1/models、/v1/chat/completions、/v1/embeddings、/api/config、/api/requests、/api/reset。
  5. GoChat 内新增一套本地 fake provider 配置模板,方便 Copilot / Captain 直接切过去联调。

5.4 当前 channels/fake 已可直接复用的测试能力(2026-07-19 核对)

为了避免把 fake channel 和未来的 fake:ai 混在一起,这里把当前已经现成可用的 fake 消息平台能力单独列出来:

能力 当前端点 可直接支撑的测试
健康检查 GET /health 执行前确认 fake 服务在线
运行时改配置 POST /api/config 动态切换 webhook、token、auto reply、delay
客户入站消息 POST /api/send 造新会话、造入站消息、验证 dashboard 实时出现
客户回复消息 POST /api/reply 验证 reply_to / 同会话追加消息
会话结束事件 POST /api/close 验证 session.end、关闭链路、状态流转
typing 事件 POST /api/typing 验证 typing.start / typing.stop UI 提示
agent 在线状态观测 POST /api/agent/online、POST /api/agent/offline 验证 presence / availability 展示
出站消息留痕 GET /api/messages、GET /api/messages/:id 断言客服回复有没有真正发回 fake 平台
平台状态观测 GET /api/status 观察 auto reply、消息计数、agent 状态
内存态重置 POST /api/reset 每轮 CDP 测试前清理平台状态

基于当前实现,channels/fake 已经足够支撑这几类真实验收:

  1. fake 客户发消息 → GoChat 创建或追加会话。
  2. 客服在 dashboard 回复 → fake 平台能收到 outbound。
  3. auto reply 回流 → dashboard 无刷新出现下一条 incoming。
  4. typing / session.end / agent online/offline 等外围实时事件可单独回放。

但它还不是“批量数据工厂”,当前仍缺这些会明显影响全量页面验收的能力:

  • 批量制造多状态会话(open / pending / resolved / snoozed);
  • 批量制造更多消息类型(private note、attachment、email-like、system event);
  • 一次性造多联系人、多公司、多标签、多 team 的数据集;
  • AI provider 兼容接口(这部分应由独立的 fake:ai 负责,而不是继续堆进 channels/fake)。

6. 页面功能矩阵

6.1 Auth / account lifecycle

页面 路径 功能点
登录 /app/login 正确登录、错误密码、空表单校验、无注册链接、回车提交
SSO 登录 /app/login/sso 无配置时错误态,配置后跳转态
重置密码 /app/auth/reset/password 表单校验、提交反馈
邮箱确认 /app/auth/confirmation token 缺失错误态
无账号 /app/no-accounts 空账号用户展示
onboarding /app/accounts/:id/onboarding 首次账号信息表单
suspended /app/accounts/:id/suspended 账号暂停页

6.2 Inbox / conversation

页面 路径 功能点
Dashboard /app/accounts/:id/dashboard 会话列表、筛选、排序、在线状态、未读数
会话详情 /conversations/:conversation_id 消息渲染、发送、私密备注、附件、emoji、引用、草稿
Inbox 会话 /inbox/:inbox_id inbox 筛选、列表一致性
Label 会话 /label/:label 标签过滤、标签增删
Team 会话 /team/:teamId 团队过滤、团队分配
Custom view /custom_view/:id 自定义视图过滤、缺失视图重定向
Mentions /mentions/conversations @ 提及列表
Unattended /unattended/conversations 未处理会话
Conversation search 搜索入口 搜索结果、跳转详情
Inbox view /inbox-view/:type/:id 聚合视图、详情页

核心操作:

  1. fake 客户发消息,dashboard 不刷新出现新会话。
  2. 客服回复,fake /api/messages 能查到 outbound。
  3. auto reply 回流后同一会话追加 incoming。
  4. 切换 open/resolved/pending/snoozed。
  5. 分配 agent/team,刷新后仍保持。
  6. 添加/移除 label、priority。
  7. 上传图片/文件,检查预览和下载。
  8. private note 不发送到 fake。
  9. typing.start/typing.stop 有 UI 指示。
  10. 多标签页实时同步。

说明:

  • 当前 dashboard 登录后的默认会话请求是 assignee_type=me,即“我的”视图。
  • fake 入站若创建的是未分配会话,验证会话可见性时应继续点击切到 未分配的 或 所有的,不要把“我的”视图下不可见误判成实时失败。

6.3 CRM

页面 路径 功能点
Contacts /contacts 列表、搜索、分段、标签过滤、新建
Contact detail /contacts/:contactId 编辑资料、custom attributes、会话历史、备注
Companies /companies 列表、搜索、新建
Company detail /companies/:companyId 编辑、关联联系人、历史记录

6.4 Reports

页面 路径 功能点
Overview /reports/overview 指标卡、日期范围、图表
Conversations /reports/conversations 表格、导出、筛选
Agents /reports/agents agent 维度指标
Labels /reports/labels label 维度指标
Inboxes /reports/inboxes inbox 维度指标
Teams /reports/teams team 维度指标
CSAT /reports/csat 评分分布、评价列表
SLA /reports/sla SLA 命中/违约
Bot /reports/bot bot/assistant 指标
Live reports /reports/live 实时数据刷新

6.5 Settings

页面 路径 功能点
Account /settings/account 名称、语言、auto-resolve、删除保护
Agents /settings/agents/list 创建 agent、临时密码、编辑、禁用、重置密码
Teams /settings/teams/list 创建、成员、编辑、删除
Inboxes list /settings/inboxes/list channel 列表、创建入口、fake/website 可见
Inbox configuration /settings/inboxes/:id 名称、欢迎语、允许域名、sender name、保存
Inbox collaborators /settings/inboxes/:id/collaborators agent 绑定
Pre-chat form /settings/inboxes/:id/pre-chat-form 字段开关、必填、保存
CSAT inbox /settings/inboxes/:id/csat 开关、消息模板
Business hours inbox 子页 每周时间、时区
Channel create pages /settings/inboxes/new/* website/api/email/fake/twilio/line/tiktok/facebook 等表单和错误态
Labels /settings/labels/list CRUD、颜色
Custom attributes /settings/custom-attributes/list contact/conversation/company 属性 CRUD
Automation /settings/automation/list CRUD、条件/动作校验
Macros /settings/macros CRUD、执行宏
Canned responses /settings/canned-response/list CRUD、插入回复框
Agent bots /settings/agent-bots bot 列表、绑定 inbox
Integrations /settings/integrations Slack/Linear/Notion/Webhook/Dashboard app 卡片和配置
Webhooks integration 子页 CRUD、事件选择、签名字段
Conversation workflow /settings/conversation-workflows 开关、保存
Assignment policy /settings/assignment-policy/* assignment、capacity 创建/编辑
Custom roles /settings/custom-roles/list 权限勾选、角色用户
Audit logs /settings/audit-logs/list 列表、筛选
Security/SAML /settings/security 无配置错误态、字段校验
Billing /settings/billing subscription/limits 降级态
Profile /profile/settings 资料、密码、消息签名、通知偏好、access token、MFA
Notifications /notifications 列表、已读、跳转
Copilot 配置 /settings/copilot 或当前实际入口 fake provider 保存、测试连接、账户功能开关

6.6 Help Center

页面 路径 功能点
Portals /portals/:navigationPath portal 列表、新建
Articles /portals/:slug/:locale/articles 列表、草稿/发布 tab
Article editor articles/new / edit/:slug 标题、正文、保存、发布
Categories /categories CRUD、排序
Locales /locales locale 增删
Portal settings /settings 域名、主题、SEO
Article preview /articles/preview/:articleSlug 公开预览

6.7 Campaigns

页面 路径 功能点
Live chat campaigns /campaigns/live_chat 新建、编辑、启停、触发条件
SMS campaigns /campaigns/sms 空配置降级、表单校验
WhatsApp campaigns /campaigns/whatsapp provider 缺失提示、模板字段

6.8 Captain / AI

页面 路径 功能点
Assistants /captain/:navigationPath assistant 列表、新建、切换
FAQs / Responses /captain/:assistantId/faqs CRUD、搜索、批量删除
Pending responses /faqs/pending approve/reject
Documents /documents 新建文档、上传、embedding 状态
Tools /tools custom tool CRUD、参数、鉴权
Scenarios /scenarios CRUD、启停
Playground /playground 输入问题、fake AI 回复、错误态
Inboxes /inboxes assistant 绑定 inbox
Settings /settings 名称、描述、开关
Guardrails /settings/guardrails 规则保存
Guidelines /settings/guidelines response guideline 保存

6.9 Widget / public

页面 路径 功能点
Widget home /widget?website_token=...#/home 可用性、欢迎语、campaign
Widget messages /widget?website_token=...#/messages 客户发消息、附件、emoji、历史
Pre-chat widget widget pre-chat 表单字段、必填校验
Article viewer widget article route 文章搜索、打开
CSAT public public CSAT route 评分、评价提交
Help center public public portal route 文章浏览、搜索

6.10 Global shell / personal / super admin

页面 路径 功能点
侧边栏与全局壳层 dashboard 任意已登录页 logo、主导航、收起/展开、未读徽标、当前激活态
用户菜单 侧边栏头像菜单 键盘快捷键弹层、更改外观、个人设置入口、退出登录
账号切换 用户菜单中的 account switcher 不同 account 间切换、URL/accountId 同步、权限不足账号不应泄露
通知中心 /notifications 列表、已读、全部已读、跳转回原会话/对象
Super admin 入口 /super_admin 仅授权用户可见、入口可打开、能返回主应用
Super admin dashboard super admin 当前实际默认页 概览卡片、列表、降级态
Super admin playground super admin playground 可进入、表单可操作、无权限用户不可见

6.11 页面统一验收模板

为了避免“有些页面只看打开,有些页面又测到了保存”,后续 CDP 执行时建议所有页面按页面类型套同一套断言模板。

A. 列表页

适用:Dashboard、Contacts、Companies、Teams、Labels、Inboxes、Articles、Documents、Responses、Notifications。

统一断言:

  1. 页面可通过真实点击进入。
  2. 列表主表格/卡片区有数据或空态文案,不允许白屏。
  3. 首屏加载请求全部成功,分页/排序/筛选请求状态码正确。
  4. 搜索输入可操作,URL/query 参数与结果同步。
  5. 点击一条记录可进入详情或编辑页。
  6. 返回列表后筛选条件、滚动位置、tab 状态按产品预期保持。
  7. 空态、无结果态、加载态可见。
  8. console 无新的未捕获异常。

B. 详情页

适用:Conversation、Contact detail、Company detail、Inbox detail、Assistant detail、Portal detail。

统一断言:

  1. 必须从列表/入口点击进入,不直接手输内部 URL。
  2. 详情页标题、主信息区、侧栏信息区都已渲染。
  3. 至少执行 1 个读操作和 1 个写操作(如编辑、切状态、加标签、保存备注)。
  4. 保存后 toast/提示正确,刷新后状态仍在。
  5. 若详情页包含关联对象(联系人/会话/文档/工具),至少点进 1 个二级对象。
  6. 404/已删除/无权限的降级态可见且不崩溃。

C. 表单页

适用:创建 Inbox、创建 Agent、Automation、Macro、Custom Attribute、Portal/Article、Campaign、Custom Tool。

统一断言:

  1. 必填项校验正确,错误文案清晰。
  2. 合法数据可提交,非法数据被前端或后端拒绝。
  3. 保存按钮 loading 态和防重复提交正确。
  4. 成功后跳转、返回列表或停留当前页的行为符合预期。
  5. 编辑已有对象时,默认值回填完整。
  6. 离开未保存表单时,如产品定义有提醒则必须触发。

D. 报表页

适用:Overview、Agents、Labels、Inboxes、Teams、CSAT、SLA、Bot、Live Reports。

统一断言:

  1. 默认时间范围有数据或空态,不白屏。
  2. 切换日期范围会重新拉取数据,图表/表格同步变化。
  3. 导出、下载、切换维度时请求参数正确。
  4. 空数据时仍有结构化占位,而不是 main 空白。
  5. 指标卡、图表 legend、表格列头与接口字段一致。

E. AI / Captain / Copilot 页

适用:Copilot 配置、Assistants、Responses、Documents、Tools、Scenarios、Playground。

统一断言:

  1. 页面渲染与列表/表单交互正常。
  2. 在 fake:ai ok 模式下,核心 AI 请求必须可成功走通。
  3. 在 error / slow / rate_limit 模式下,错误态必须可见且不假成功。
  4. 页面不能泄露明文 API key、Authorization、provider secret。
  5. 所有 AI 页面都要同时保留 UI 证据和 fake:ai 请求证据。

7. Fake channel E2E 脚本化步骤

  1. 重置 fake:
curl -fsS -X POST http://127.0.0.1:9100/api/reset
  1. 确认配置:
curl -fsS -X POST http://127.0.0.1:9100/api/config \
  -H 'Content-Type: application/json' \
  -d '{"webhook_url":"http://127.0.0.1:3000/webhooks/fake/fake_01","auto_reply":true}'
  1. 入站消息:
curl -fsS -X POST http://127.0.0.1:9100/api/send \
  -H 'Content-Type: application/json' \
  -d '{"inbox_identifier":"fake_01","sender_id":"cdp_customer_01","sender_name":"CDP测试客户","content":"CDP 全量测试入站消息"}'
  1. CDP 断言 dashboard 出现 CDP测试客户 和消息内容。
  2. CDP 在回复框发送 收到,正在测试。
  3. fake 断言:
curl -fsS http://127.0.0.1:9100/api/messages
  1. CDP 断言 auto reply 回流后同一会话增加客户消息。

8. 报告格式

生成到:

docs/qa/reports/2026-07-15-cdp-user-function-report.md
.tmp/cdp-qa/2026-07-15/

报告必须包含:

  • 服务基线:health、登录账号、测试 account id、fake config。
  • 页面矩阵:pass/fail/blocked/skipped。
  • 每个失败:复现路径、请求、响应、console、截图、影响等级。
  • 数据缺口:缺哪条 seed 导致 blocked。
  • fake channel 证据:/api/messages 摘要。
  • fake:ai 证据:/api/requests 摘要。

9. 第一轮执行顺序

  1. 登录和 WebSocket。
  2. fake channel 消息 E2E。
  3. Dashboard / conversation 核心路径。
  4. Settings 中会影响后续数据的页面:agents、teams、inboxes、labels、attributes。
  5. Reports。
  6. Help Center / Campaigns / Widget。
  7. Captain / Copilot,先用 fake:ai。
  8. 权限用户回归:agent、custom role。

这样排是为了先证明链路活着,再铺开页面。最省事,也最不容易把数据缺口误判成产品 bug。

10. 当前已知高风险 / 预期阻断

以下问题已经在点击驱动验收中出现,后续 CDP 全量测试时应直接按“产品缺陷”记录,不要误归类成数据缺口:

项 当前现象 建议分类
fake auto reply 回流 最新观测表明平台侧 echo 已回流,但 GoChat 侧会出现“新会话分叉”或“同会话重复/顺序异常渲染”两类缺陷,均应按链路问题记录 P1 链路缺陷
widget / public 入口 Website inbox 脚本 / CodePen / 预览 / Chat mode 已基本穷举,但仍未发现可作为“真实 public/widget 用户入口”验收的稳定点击路径;CodePen 外跳也不能替代站内入口 P1 入口未接通
Help Center 后台三页 设置 / 类别 / 语言 三页在 fresh session 中仍稳定落入空白主区,而 文章 列表、编辑、预览链路健康,说明是局部后台渲染缺陷,不是整套帮助中心都坏 P1 页面主内容未渲染
Super admin 入口 从用户菜单点击 超级管理员控制台 后,当前 tab 未进入 /super_admin;额外新 tab 实为此前 CodePen 的迟到外跳 P1 入口失效
通知入口识别 顶部无文案按钮当前确认打开的是“新消息/全局发消息”弹层,不是通知中心;真正通知入口在当前健康链路里仍待明确 P2 验收前置澄清
Captain AI 主链路 FAQ / 文档 / Scenarios / 试验场 / 收件箱 / 工具 / 设置 / Guardrails / Response guidelines 已在健康 click-only 链路下证明可渲染;其中 试验场 等真实 AI 效果仍需 fake:ai 才能做成功/失败/超时/429 全链路断言 P1 测试依赖未就绪
Campaign SMS / WhatsApp 这两页在后续 fresh session 中已能正常渲染内容与空态,不再作为稳定阻断项;后续只需继续做创建/编辑/触发层面的功能验收 已从阻断项移除

执行原则:

  1. 这类问题一旦复现,不再继续用补数据方式兜底。
  2. 报告里要保留“点击路径 + 最终 URL + main 区域状态 + 关键请求/快照”四类证据;如果不是空白而是错误态,也要按真实渲染结果记录。
  3. widget / public 相关在真正站内入口修好前,只保留入口级验证,不做功能通过判定。
  4. Captain 当前不要再按“稳定白屏”预设处理;除了真实 AI 依赖项外,应继续按正常页面矩阵做列表/表单/子页验收。

11. 执行前补齐清单(可直接转实施)

这一节把“测试计划”“缺数据”“缺 fake:ai 支撑”压成执行清单,避免后续再来回翻全文。

11.1 P0:不补就没法做全量功能验收

项 需要补什么 建议落地方式 完成标准
登录与权限基线 1 个管理员、2 个可登录 agent、1 个 custom role 用户 cmd/gochat seed + 后台补齐 三类账号都能真实登录,菜单和权限差异可见
fake 会话主链路 fake_01 inbox、fake webhook 正常、会话能进入正确列表 inbox 配置 + pnpm fake:start 入站、客服回复、auto reply 回流三段都能留证据
基础会话池 至少 6 条不同状态会话,每条 3+ 消息 fake channel 批量灌数 open / pending / resolved / snoozed 都能在 UI 中找到
页面不再只剩空态 contacts 8+、companies 3+、labels 5、teams 2 seed 或 UI 创建 CRM、筛选、报表、分配页面不再被空数据阻断
AI 本地假服务 channels/fake-ai + 根脚本 fake:ai 复用 fake channel 骨架 Copilot / Captain 能走本地假 provider 成功/失败/超时/429

11.2 P1:不补会导致“大量页面只能做 render-only”

项 需要补什么 影响页面
回复提效数据 canned responses 3、macros 3、automation rules 3 回复框、设置 CRUD、自动化
属性与筛选数据 contact / conversation / company custom attributes 各 2 CRM、筛选器、自动化条件
通知与审计数据 notifications 5、audit logs 5 通知中心、审计日志、跳转链路
Help Center 丰富数据 1 portal、2 categories、3 articles、2 locales 后台 portal、public help center、多语言
Campaign 样本 live chat / sms / whatsapp 至少各 1 个样本 Campaigns 列表、编辑、启停
Captain 子资源 documents 3、responses 5、scenarios 2、tools 1 Captain 子页 CRUD、Playground、文档链路

11.3 fake:ai 的最小验收标准

fake:ai 只要做到下面这些,就足够支撑本轮 CDP 页面级功能验收:

能力 最小要求 为什么必须有
OpenAI-compatible chat POST /v1/chat/completions 返回固定答复 Copilot / Captain / reply suggestion 要能成功走通
OpenAI-compatible embeddings POST /v1/embeddings 返回固定维度向量 Captain documents / embedding 状态要能推进
模式切换 ok / error / slow / rate_limit 页面要验证成功、失败、超时、429,而不是只测 happy path
请求留痕 GET /api/requests 可查最近请求摘要 报告要拿得到 AI 调用证据,不只截图
脱敏 不记录明文 Authorization / api_key 测试日志不能泄露敏感配置

11.4 推荐实施顺序

  1. 先补账号、fake_01 inbox、基础会话池。
  2. 再补 contacts / companies / labels / teams,让 dashboard、CRM、reports 能进入“非空态测试”。
  3. 然后补 canned responses / macros / automation / custom attributes,打通 settings 主体 CRUD。
  4. 再补 Help Center / campaigns / notifications / audit logs 这些页面群的数据。
  5. 最后实现 fake:ai,把 Copilot / Captain 从 render-only 升级成真实功能验收。

11.5 本轮文档产出对应关系

为避免后续拆任务时语义漂移,这份计划文档里的三类产出边界如下:

产出 本文档里对应内容 后续动作
CDP 测试执行规则 第 1、2、3、6、7、8、9、10 节 后续按此直接做 click-only QA 和 report 追加
影响全量测试的数据缺口 第 4 节 + 本节 11.1 / 11.2 后续可拆成 seed、fake、后台初始化任务
AI 测试支撑方案 第 5 节 + 本节 11.3 后续单独实现 fake:ai 并接入 Copilot / Captain

11.6 建议直接拆出的实施任务

为了把“计划文档”顺滑转成“落地任务”,建议按下面 4 个实施包推进:

任务包 目标 建议落地位置 完成标志
A. smoke seed 扩容 从单管理员/单会话扩到可支撑大部分页面验收 backend/cmd/gochat seed 能一次性产出 2 agents、更多会话状态、更多 contacts/companies/labels/teams
B. fake channel 批量造数 把会话、消息类型、实时事件做成可重复回放 channels/fake 能按脚本批量制造 open/pending/resolved/snoozed、typing、reply、close
C. fake inbox/bootstrap 让 fake_01 不再靠手工散配置维持 seed + inbox/bootstrap script fresh 环境里一条命令后即可直接收发 fake webhook
D. fake:ai 给 Copilot/Captain 提供本地稳定 AI 依赖 channels/fake-ai chat/completions、embeddings、mode switch、request log 全部可用

推荐先后顺序:

  1. 先做 A + C,保证 dashboard 主链路可测。
  2. 再做 B,把 reports / CRM / settings 从“空态浏览”升级成“真实数据验证”。
  3. 最后做 D,把 Captain / Copilot 从 render-only 升级成完整 E2E。

12. 执行前一页纸清单

这一节是给真正开跑 CDP 全量验收时直接照着做的,避免再从前文抽命令。

12.1 环境与服务核对

curl -fsS http://127.0.0.1:3000/health
curl -fsS http://127.0.0.1:9100/health
curl -fsS http://127.0.0.1:9222/json/version

通过标准:

  1. backend 返回 200。
  2. fake channel 返回 {"status":"ok","service":"fake-message-platform"}。
  3. CDP debug 口能返回 webSocketDebuggerUrl。

12.2 现有仓库能力 vs 需要新增的能力

类别 当前已具备 仍需新增
本地消息 fake 根脚本 fake:start / fake:dev / fake:test,workspace 已纳入 channels/fake 批量造多状态会话、多消息类型、批量造数接口
AI fake 无 channels/fake-ai、根脚本 fake:ai*、workspace 纳入 channels/fake-ai
smoke seed go run ./cmd/gochat seed 可产出管理员、website inbox、portal/article、1 contact/company/conversation、Captain assistant 基线 第二个 agent、fake inbox、更多会话状态、labels/teams、通知/审计、campaign 样本
页面级执行规则 本文档已覆盖 click-only + report sink + fake/fake:ai 证据要求 后续按本文档直接执行

12.3 数据准备责任分层

为了避免后续把所有“补数据”都塞进一个入口,建议这样拆:

层 负责内容 最适合落地位置
smoke seed 可登录账号、website inbox、portal/article、最小 smoke records backend/cmd/gochat seed
fake channel 批量制造会话、消息、typing、close、online/offline channels/fake
后台 UI 自举 labels、teams、macros、canned responses、custom attributes、部分 portal/campaign CDP 执行过程中顺手创建
fake AI chat/completions、embeddings、error/slow/429 模式、请求留痕 channels/fake-ai

12.4 建议先补的 5 个最小 blocker

只要还没补齐下面 5 项,就不要把结果叫“全量实际功能验收完成”:

  1. 第二个可登录 agent。
  2. fake_01 对应 inbox 和 webhook 主链路。
  3. 至少 6 条不同状态会话。
  4. contacts / companies / labels / teams 的非空数据集。
  5. fake:ai 本地假 provider。

12.5 后续实施拆单建议

如果接下来按实现任务推进,建议就按下面 4 张单拆,不要混成一张“大而全”任务:

  1. 扩 cmd/gochat seed:补双 agent、更多 CRM / reports / settings 基线数据。
  2. 扩 channels/fake:补批量造数和多状态回放能力。
  3. 加 fake inbox/bootstrap:fresh 环境一条命令后可直接收发 fake_01。
  4. 新建 channels/fake-ai:给 Copilot / Captain 提供本地稳定 AI 依赖。