Files
gochat/docs/qa/2026-07-10-test-plan-round7.md
T
2026-07-13 10:47:58 +08:00

305 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# QA Test Plan — CDP Full-Page Functional Testing Round 7
> **Date:** 2026-07-10
> **Commit tested:** 690796a (fix: resolve 4 bugs from QA round 6 — BUG-F/G/H/I)
> **Previous round:** Round 6 (Redis Stream migration verification, 11 pages, 4 findings)
> **Round 7 focus:** BUG-F/G/H/I fix verification + full 28-page matrix completion + FakeMessagePlatform E2E
---
## 1. Round 7 Goals
### 1.1 Primary: Verify 4 Bug Fixes from Round 6
| Bug | Sev | Fix Summary | Verification Method |
|-----|-----|-------------|---------------------|
| BUG-F | P1 | `fake_webhook.go:168` now casts `channel_config::jsonb` before `@>` operator | Send fake webhook → verify message persisted in DB + appears in browser conversation list |
| BUG-G | P3 | `Settings.vue:544` passes `window.history.state` (not `null`) to `replaceState`; same fix in Instagram.vue, Tiktok.vue, portalThemeHelper.js | Navigate to Activity page → check console for Vue Router history.state warning (should be absent) |
| BUG-H | P3 | `account_service.go` CacheKeys() now derives real inbox/label/team keys from DB state (count + max(updated_at)) instead of hardcoded `"0000000000"` | Navigate to Settings → Inboxes → verify both inboxes (web_widget + fake) appear in list |
| BUG-I | P3 | `worker.go:386` generates unique `consumerID := fmt.Sprintf("%s-%d", wp.workerID, index)` per goroutine | Redis `XINFO CONSUMERS` for any queue → verify 5 consumers (not 1) |
### 1.2 Secondary: Complete the 28-Page Matrix
Round 6 tested only 11 pages (browser session timeout). Round 7 must cover ALL 28 pages
in the standard matrix, with special attention to pages skipped in round 6:
- Settings: Teams, Labels, Custom Attributes, Automation, Macros, Canned Responses,
Integrations, Conversation Workflow
- Profile page
- Reports: Conversations, Agents, Labels, Inboxes, Teams, CSAT (round 6 only tested
Overview, SLA, Bot)
### 1.3 Tertiary: FakeMessagePlatform E2E Integration
BUG-F blocked all fake channel testing in round 6. With the fix, perform the full
inbound → outbound message flow:
1. Start FakeMessagePlatform (:9100)
2. Send customer message via `POST /api/send` → GoChat webhook → DB persist
3. Verify in browser: conversation appears in dashboard, message renders in chat
4. Agent reply in browser (Ctrl+Enter) → FakeMessagePlatform `/receive` → verify via
`GET /api/messages`
5. Verify real-time delivery: message appears instantly (WebSocket)
### 1.4 Quaternary: Complete Phase 5 Real-time Verification
Round 6 skipped Phase 5 (iteration limit). Round 7 must:
- Send message → instant render in chat UI
- Verify `message.created` event in backend logs
- Presence indicator shows status (online/busy/offline)
- 30s stable /cable monitoring
- Direct WS test via shell (websocat or Python)
- Cross-tab real-time delivery (2 tabs, same credentials)
### 1.5 Quinary: Redis Worker Observability (BUG-I fix)
- Start backend with `concurrency: 5` (config.dev.yaml)
- Trigger at least one job (send a message)
- Redis `XINFO CONSUMERS gochat:jobs:high gochat-workers` → verify 5 consumers
- Verify each consumer has a unique name (`worker-<timestamp>-0` through `-4`)
---
## 2. Test Execution Plan
### Phase 1 — Start Dev Services + Pre-checks
1. Start backend (air hot-reload, :3000) and frontend (Vite, :3036) as background processes
2. Health check: `curl :3000/health` and `curl :3036/` → both OK
3. DB schema integrity check: hit 6 historically-missing endpoints → all 200 (not 500)
4. Capture backend log baseline
5. Start FakeMessagePlatform: `cd channels/fake && npx tsx src/index.ts` (background)
6. Verify FakeMessagePlatform health: `curl :9100/health`
### Phase 2 — Browser Login + Console Hook Injection
1. Navigate to `http://127.0.0.1:3036/app/login` (only allowed direct URL)
2. Inject console hooks (error + warn capture, `__resetConsole`)
3. Fill login form: `admin@gochat.local` / `changeme`
4. Submit → verify redirect to `/app/` (dashboard)
5. Re-inject hooks if full-page reload occurred
6. Read console buffer → verify clean
### Phase 3 — WebSocket /cable Verification
1. Wait 3–5s for WS connect
2. Read console buffer for `/cable` 401 or WS errors
3. Poll backend logs for `ws: connection established`
4. Monitor network 10s — `/cable` stable, no reconnect loop
5. If /cable broken → record P0, continue page tests (note degraded real-time)
### Phase 4 — Full 28-Page Matrix (Click Navigation)
**Per-page protocol (EVERY page, non-negotiable):**
1. `window.__resetConsole()` — reset buffer
2. Click to navigate (record click path)
3. Wait to settle — `browser_vision` confirms content rendered
4. Read console buffer → any error or non-allowlisted warning is a finding
5. Monitor network 10s → flag any endpoint called >3x (except `cache_keys`)
6. Verify core content renders (not blank, not error boundary)
7. Attempt one CRUD interaction where applicable
8. Poll backend logs for errors during this page
9. Capture transition errors before leaving
**Page matrix:**
| # | Page | Click Path | Key Checks | Round 6 Status |
|---|------|------------|------------|----------------|
| 1 | Dashboard | (post-login) | Conversation list, sidebar, online status | ✅ PASS |
| 2 | Conversation detail | Click a conversation | Messages, reply box, send msg, real-time | ✅ PASS |
| 3 | Contacts | Sidebar: 联系人 | Edit, save, search; no refetch loop | ✅ PASS |
| 4 | Reports Overview | Sidebar: 报告 → Overview | Stats cards, charts, date picker | ✅ PASS |
| 5 | Reports Conversations | Reports sub-tab: 会话 | Table, filter change | ⬜ NOT TESTED |
| 6 | Reports Agents | Reports sub-tab: 客服 | Agent table | ⬜ NOT TESTED |
| 7 | Reports Labels | Reports sub-tab: 标签 | Verify load | ⬜ NOT TESTED |
| 8 | Reports Inboxes | Reports sub-tab: 收件箱 | Verify load | ⬜ NOT TESTED |
| 9 | Reports Teams | Reports sub-tab: 团队 | Verify load | ⬜ NOT TESTED |
| 10 | Reports CSAT | Reports sub-tab: 客户满意度 | Verify load | ⬜ NOT TESTED |
| 11 | Reports SLA | Reports sub-tab: SLA | SLA metrics | ✅ PASS |
| 12 | Reports Bot | Reports sub-tab: 机器人 | BUG-A regression | ✅ PASS (FIXED) |
| 13 | Activity | Sidebar: 活动 (JS click) | BUG-1 + **BUG-G regression** | ✅ PASS (BUG-G warning) |
| 14 | Help Center | Sidebar: 帮助中心 (JS click) | Portal list, articles, tabs | ✅ PASS |
| 15 | Settings General | 设置 → 账户设置 | Update a field, save | ✅ PASS |
| 16 | Settings Agents | 设置: 客服代理 | List, search | ⬜ NOT TESTED |
| 17 | Settings Teams | 设置: 团队 | List, create team wizard | ⬜ NOT TESTED |
| 18 | Settings Inboxes | 设置: 收件箱 | **BUG-H regression: 2 inboxes visible** | ✅ PASS (BUG-H: 1 of 2) |
| 19 | Settings Labels | 设置: 标签 | Create label, **BUG-3/B regression** | ⬜ NOT TESTED |
| 20 | Settings Custom Attributes | 设置: 自定义属性 | List, tabs | ⬜ NOT TESTED |
| 21 | Settings Automation | 设置: 自动化 | List | ⬜ NOT TESTED |
| 22 | Settings Agent Bots | 设置: 机器人 | BUG-2 regression | ✅ PASS (FIXED) |
| 23 | Settings Macros | 设置: 宏 | List | ⬜ NOT TESTED |
| 24 | Settings Canned Responses | 设置: 预设回复 | Create canned response | ⬜ NOT TESTED |
| 25 | Settings Integrations | 设置: 集成方式 | Cards, configure one | ⬜ NOT TESTED |
| 26 | Settings Conv. Workflow | 设置: Conversation Workflows | Toggle switch | ⬜ NOT TESTED |
| 27 | Settings Assignment | 设置: Agent Assignment | Forms, add buttons | ⬜ NOT TESTED |
| 28 | Profile | Avatar dropdown → profile | Update profile, save | ⬜ NOT TESTED |
**Inbox Settings Deep Dive (page 18 sub-tabs):**
| Sub-tab | Key Check | Round 6 |
|---------|-----------|---------|
| 收件箱设置 | Config form loads | ✅ |
| 协作 | Agent assignment list | ⬜ |
| 预聊天表单 | BUG-C regression (null pre_chat_form_options) | ✅ FIXED |
| 后聊天表单 | Form renders | ⬜ |
| 消息标签 | Message labels config | ⬜ |
| 自动化规则 | Auto-assign rules | ⬜ |
| 业务时间 | Business hours config | ⬜ |
### Phase 4b — BUG-F Verification: FakeMessagePlatform E2E
**This is the highest-priority test in round 7 (P1 bug fix verification).**
1. Navigate to Settings → Inboxes → verify Fake Test Inbox (id=3) is visible (BUG-H fix)
2. Record the Fake Test Inbox identifier (e.g., `fake_test_1`)
3. Configure FakeMessagePlatform webhook URL to match:
```
curl -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_test_1","token":"fake_test_token"}'
```
4. **Inbound test:** Send customer message via 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_round7","sender_name":"Round7测试客户","content":"你好,这是第7轮测试消息"}'
```
5. Verify GoChat response: `{"status":"success"}` (NOT `{"status":"ignored"}`)
6. Verify in DB:
```sql
SELECT id, content, sender_type, inbox_id, conversation_id
FROM messages WHERE inbox_id=3 ORDER BY id DESC LIMIT 5;
```
7. **Browser verification:** Navigate to Dashboard → verify new conversation appears
in conversation list with "Round7测试客户" and message preview "你好,这是第7轮测试消息"
8. Click the conversation → verify message renders in chat window
9. **Outbound test:** In the browser, click reply box, type "您好,有什么可以帮您?",
Ctrl+Enter to send
10. Verify FakeMessagePlatform received the outbound message:
```
curl http://127.0.0.1:9100/api/messages?inbox_identifier=fake_test_1
```
11. Verify the outbound message appears in the chat UI with timestamp "now"
12. **Real-time verification:** If another browser tab is open, verify the message
appears in that tab without manual refresh
### Phase 4c — BUG-D Regression: Channel Creation Page
1. Navigate to Settings → Inboxes → click "添加收件箱" (Add Inbox)
2. Verify the "Fake 测试平台" channel card is visible and NOT disabled (BUG-D)
3. Do NOT create a new inbox unless testing BUG-E (inbox_members)
### Phase 5 — Real-time WebSocket Feature Verification
1. Open a conversation, send a message → verify instant render with "now" timestamp
2. Poll backend logs for `ws: connection established` and `message.created` event
3. Verify presence/availability indicator shows status (not empty)
4. Monitor network 30s — `/cable` stable, no 401s, no reconnect storm
5. **Direct WS test:** Extract JWT via shell curl → connect with websocat/Python →
expect `{"type":"welcome"}` then `{"type":"ping",...}` every 5s
6. **Cross-tab real-time delivery:** Open 2nd tab, login, send message from tab 1 →
verify it appears in tab 2 without refresh
### Phase 6 — Redis Worker Observability (BUG-I Fix)
1. Trigger a job: send an agent reply via API or browser
2. Redis CLI:
```
redis-cli XINFO CONSUMERS gochat:jobs:high gochat-workers
```
3. Verify 5 consumers with unique names: `worker-<timestamp>-0` through `worker-<timestamp>-4`
4. Verify at least 1 consumer has a pending=0 after ACK (job consumed successfully)
### Phase 7 — Collect, Report, Teardown
1. Kill background dev servers + FakeMessagePlatform
2. Write report to `docs/qa/2026-07-10-qa-report-round7.md`
3. Delete previous round's report from `docs/` (round 6 report at `docs/QA_REPORT_2026-07-10_cdp_round6.md`)
4. Update `references/known-bugs.md` with round 7 statuses
---
## 3. Known Bug Re-Verification Matrix
Every bug in the registry must be re-verified. Mark FIXED / PERSISTING / REGRESSED
with evidence.
| Bug | Sev | Description | Round 6 Status | Round 7 Check |
|-----|-----|-------------|----------------|---------------|
| BUG-1 | P2 | Activity page route missing | FIXED | Sidebar "活动" → `/campaigns/live_chat` |
| BUG-2 | P3 | Bots sidebar link not navigating | FIXED | Settings → "机器人" → `/settings/agent-bots` |
| BUG-3/B | P4 | intlify empty key warnings | NOT TESTED | **Create a label** → check console |
| BUG-4 | P3 | Vue prop type mismatch on message ID | (assumed fixed) | Open conversation with messages → no prop warnings |
| BUG-5 | P1 | NotificationSetting handler not registered | (assumed fixed) | `curl notification_settings` → 200 |
| BUG-7 | P0 | Missing DB tables → 500 on 6 endpoints | FIXED | All 6 endpoints → 200 |
| BUG-A | P3 | Bot Reports sidebar nav from Reports | FIXED | Reports SLA → "机器人" → `/reports/bot` |
| BUG-C | P2 | Pre-chat Form tab null error | FIXED | Inbox settings → 预聊天表单 → no Vue error |
| BUG-D | P2 | ChannelItem isActive whitelist (fake) | NOT TESTED | Add Inbox page → Fake card NOT disabled |
| BUG-E | P3 | inbox_members not written | NOT TESTED | Create new inbox → verify inbox_members |
| BUG-F | P1 | Fake webhook JSONB @> on TEXT | NEW → **FIX PENDING VERIFY** | FakeMessagePlatform E2E (Phase 4b) |
| BUG-G | P3 | Vue Router history.state warning | NEW → **FIX PENDING VERIFY** | Activity page → console clean |
| BUG-H | P3 | Inbox list shows 1 of 2 | NEW → **FIX PENDING VERIFY** | Settings → Inboxes → 2 inboxes visible |
| BUG-I | P3 | Worker consumer name shared | NEW → **FIX PENDING VERIFY** | Redis XINFO → 5 consumers |
---
## 4. Console Warning Allowlist
Warnings in this list are acceptable and do NOT count as findings unless they
increase in frequency or appear in new contexts:
| Warning | Where | Sev |
|---------|-------|-----|
| `[DEPRECATED] The 'onClose' prop is deprecated` | Widget/UI components | P4 |
| `[DEPRECATED] <WootInput> has be deprecated` | Old WootInput components | P4 |
| `Lit is in dev mode` / `Multiple versions of Lit loaded` | Initial load | P4 |
| `[Vue Router warn]: Discarded invalid param(s) "page"` | Route nav | P4 |
| `SW registration failed (SecurityError)` | Vite dev server | P4 |
**BUG-G warning (`history.state seems to have been manually replaced`) should NOT
appear after the fix.** If it does, BUG-G is PERSISTING.
---
## 5. Network False-Positive: `cache_keys` Endpoint
`/api/v1/.../cache_keys` is called multiple times on page load. This is NOT an
infinite loop. Do not flag unless it continues repeating after the 10s settle window.
**BUG-H context:** The fix changes `cache_keys` response values from hardcoded
`"0000000000"` to real DB-derived keys. The frontend uses these to invalidate
IndexedDB cache. After the fix, navigating to Settings → Inboxes should trigger
a fresh API call (not cached) and return both inboxes.
---
## 6. Testing Principles (Non-Negotiable)
1. **Console warnings ARE errors** — zero tolerance for non-allowlisted warnings
2. **Watch for infinite network loops** — 10s monitor per page, >3 calls = finding
(except `cache_keys`)
3. **Navigate by clicking, never by URL** — login is the sole exception
4. **Capture transition errors** — reset buffer before leaving, read after arriving
5. **CRUD interaction where applicable** — not just "page loads"
6. **Use `chrome_devtools` MCP if `browser_*` tools lose context 2+ times** (round 5 lesson)
---
## 7. Success Criteria
Round 7 is a PASS if:
- ✅ All 28 pages tested via click navigation with per-page console/network checks
- ✅ BUG-F verified: FakeMessagePlatform E2E (inbound + outbound) works end-to-end
- ✅ BUG-G verified: Activity page has no `history.state` warning
- ✅ BUG-H verified: Settings → Inboxes shows both web_widget and fake inboxes
- ✅ BUG-I verified: Redis `XINFO CONSUMERS` shows 5 unique consumers
- ✅ WebSocket /cable connected and stable (30s, no reconnect storm)
- ✅ Direct WS test: welcome + ping frames received
- ✅ Cross-tab real-time delivery works
- ✅ All known bugs re-verified (FIXED / PERSISTING / REGRESSED status recorded)
- ✅ Zero new P0/P1 findings
- ✅ Report written to `docs/qa/2026-07-10-qa-report-round7.md`