305 lines
16 KiB
Markdown
305 lines
16 KiB
Markdown
# 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`
|