Files
EchoChat/.playwright-mcp/task16/README.md
bujinyuan 5ed14c2aac docs(meeting): Task 16 E2E 剧本落盘 + .gitignore 精细化
Playwright MCP 4 场景剧本(.playwright-mcp/task16/):
- README.md:总览 + 账号/环境/资源断言指南
- scenarios/01-create-and-join-by-code.md:创建→会议号加入→媒体打通→结束,含 Redis/MySQL/media-server 三维资源断言
- scenarios/02-invite-link-with-password.md:邀请链接带密码 + P0-4 "密码不走 URL query" 回归
- scenarios/03-notify-quickjoin.md:通知中心「立即加入」跳转 + 过期卡片降级
- scenarios/04-host-toolkit-and-transfer.md:主持人四件套 + 宽限期重连/到期自动转让(P1-1 原子性 + P1-7 处理锁验证)
- scenarios/05-reopen-5times-resource-cleanup.md:反复开关 5 次 + 前端 heap 快照/ Redis 累积对比/ media-server 观测端点对比,验证 Step A(f5ae095)资源清理修复

手工回归点(manual-regression.md):17 项 MCP 难以稳定覆盖的交互场景
(HTTPS 自签 / 跨网段 iOS / 网络抖动 / 物理返回 / 跨 tab 并发 / 摄像头抢占 等)

.gitignore 调整:
- 放行 .playwright-mcp/task16/ 下的 Markdown 剧本文档进入版本控制
- 仍忽略运行时产物(*.log/*.png/*.yml/截图)
- task15/ 保持未跟踪状态,避免历史截图噪声入库

Made-with: Cursor
2026-04-23 17:21:42 +08:00

92 lines
4.8 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.

# Task 16 Playwright MCP E2E 剧本
> 生成时间2026-04-23UTC+8
> 回归范围Phase 2e-2 Task 16 —— E2E 总回归 + 资源清理专项
> 环境macOS 25.3.0 / ChromiumPlaywright MCP/ 1440×900 桌面视口
> 三件套:`go-service :8085`、`media-server :3300`、`frontend :5173`HTTPS 自签)
## 场景矩阵
| # | 文件 | 覆盖设计文档章节 | 验证目标 | 资源断言 |
|---|---|---|---|---|
| 01 | [`scenarios/01-create-and-join-by-code.md`](scenarios/01-create-and-join-by-code.md) | §6.1 / §6.3 | 创建即时会议 → 会议号加入 → 双向音视频打通 → 主持人结束 | Router/Transport/Producer/Consumer 全量创建 + CloseRouter 级联释放 |
| 02 | [`scenarios/02-invite-link-with-password.md`](scenarios/02-invite-link-with-password.md) | §6.2 / §6.4 | 邀请链接带密码 → 受邀人免密加入 | `meeting_invites``consumed_at` 更新;密码不出现在 URL query |
| 03 | [`scenarios/03-notify-quickjoin.md`](scenarios/03-notify-quickjoin.md) | §6.4 | 通知中心「立即加入」按钮跳转 | `meeting_invitation` 通知类型 + `expired_at` 边界 |
| 04 | [`scenarios/04-host-toolkit-and-transfer.md`](scenarios/04-host-toolkit-and-transfer.md) | §6.5 / §6.6 | 主持人四件套(请静音/开麦/转让/踢出)+ host 宽限期自动转让 | `meeting_participants.role` 原子转让;`host_grace` Redis key + 处理锁 SETNX |
| 05 | [`scenarios/05-reopen-5times-resource-cleanup.md`](scenarios/05-reopen-5times-resource-cleanup.md) | §5.4 / §资源清理专项 | **反复开关 5 次会议,验证资源无泄漏** | `echo:meeting:resource:*` / `echo:meeting:member_state:*` / `echo:meeting:host_grace:*` / `echo:meeting:empty_ttl:*` 全部不残留;前端 `_engine` / `AudioContext` / `setInterval` 全部释放 |
## 测试账号
沿用 Task 15 账号体系(固定 `user_id` 便于断言):
| 账号 | 密码 | user_id | 角色 |
|---|---|---:|---|
| `task15_a` | `Task15@2026` | 55 | 主持人 Alice |
| `task15_b` | `Task15@2026` | 56 | 参会人 Bob |
| `task15_c` | `Task15@2026` | 57 | 参会人 Carol场景 04 需要第三人验证 host 宽限期转让目标) |
> 账号若不存在可用 `POST /api/v1/auth/register` 脚本化创建;密码策略要求大写 + 特殊字符。
## 通用前置条件
1. **三件套已就绪**
```bash
# backend/go-service
go run cmd/allinone/main.go
# media-server
cd media-server && npm run dev
# frontend
cd frontend && npm run dev:h5:https
```
2. **DB/Redis 干净**
```bash
# MySQL确认 meeting_rooms / meeting_participants / meeting_invites 无遗留 active 会话
mysql -e "UPDATE meeting_rooms SET status='ended' WHERE status='active'" echochat
# Redis清掉可能的残留
redis-cli --scan --pattern 'echo:meeting:*' | xargs -r redis-cli DEL
```
3. **浏览器**Chromium 允许 `localhost` 自签证书(`chrome://flags/#allow-insecure-localhost`),并授予 `camera` / `microphone` 权限。
4. **控制台期望**:无 `RTCPeerConnection error` / `NotReadableError` / `ResourceNotOwned`。
## 运行方式
每个剧本文件的 **"MCP 执行脚本"** 段落直接复制给 Playwright MCP AgentCursor Chat 中 `Use playwright-mcp` 触发):
```text
请按照 @.playwright-mcp/task16/scenarios/01-create-and-join-by-code.md 的 "MCP 执行脚本" 章节逐步执行并逐条断言。
```
Agent 会用 `browser_navigate` / `browser_click` / `browser_fill_form` / `browser_evaluate` 完成剧本,每步结果以截图 + 控制台日志 + Pinia state 快照形式落盘到 `.playwright-mcp/task16/<scene>/`。
## 资源断言脚本
每个场景结束后需要运行的资源检查(用于证明 Step A 的资源清理修复生效):
```bash
# Redis会议期间 key 清单(应仅含活跃会议,结束后应清零)
redis-cli KEYS 'echo:meeting:resource:*'
redis-cli KEYS 'echo:meeting:member_state:*'
redis-cli KEYS 'echo:meeting:host_grace:*'
redis-cli KEYS 'echo:meeting:empty_ttl:*'
# MySQL所有 active 会议
mysql -e "SELECT id, room_code, status, host_id FROM meeting_rooms WHERE status='active'" echochat
# media-server 观测端点Router / Transport / Producer / Consumer 汇总
curl -s -H "X-Internal-Token: $INTERNAL_TOKEN" http://localhost:3300/internal/info | jq .stats
```
## 产出物
每个场景执行后需要落盘:
- `scenarios/XX-*/screenshots/`:关键 UI 截图(入会前、打通后、结束后)
- `scenarios/XX-*/console.log`:浏览器控制台归档
- `scenarios/XX-*/result.md`:逐条断言结果(✅/❌ + 证据链接)
所有 5 场景跑完后在 `docs/reports/test-report-phase2e-2-meeting.md` 汇总。
## 手动回归点
Playwright MCP 难以覆盖的交互场景归档在 [`manual-regression.md`](manual-regression.md),由开发者手工过一遍并记录结论。