Files
EchoChat/.playwright-mcp/task16/scenarios/02-invite-link-with-password.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

3.4 KiB
Raw Blame History

场景 02邀请链接加入带密码

目标

  • 验证 POST /api/v1/meeting/rooms/:code/invites(签发邀请)+ POST /api/v1/meeting/invites/:token/consume(消费邀请)
  • 覆盖设计 §6.2(邀请 token 7 天有效期、§6.4(邀请链接 URL
  • 验证 Task 16 P0-4 修复:密码不出现在 URL query仅通过内存 state 或 Sec-Fetch 头传递

前置条件

../README.md 通用前置。

MCP 执行脚本

步骤 1Alice 创建带密码的会议

  1. task15_a 登录
  2. 会议首页 → 「创建会议(自定义)」→ 切换到有密码模式
  3. 填充:
    • 会议主题:Task16 邀请回归
    • 密码:invite@2026
    • 其他留默认
  4. 点「创建并进入」
  5. 记录 $ROOM_CODE

步骤 2Alice 生成邀请链接

  1. 工具栏 → 「邀请」 → 「复制邀请链接」
  2. 从剪贴板读取链接;格式示例:https://localhost:5173/#/pages/meeting/preview?mode=join&code=xxx&invite_token=yyy
  3. 断言 URL query 不含 password 明文P0-4 核心断言):
    // browser_evaluate
    const link = await navigator.clipboard.readText()
    return { link, hasPassword: /password=/i.test(link) }
    
    期望:hasPassword=false

步骤 3Bob 通过邀请链接加入

  1. 开 Bob tab已登录 task15_b
  2. browser_navigate → 步骤 2 拿到的链接
  3. 预览页展示「即将加入 $ROOM_CODE / 邀请人 Alice」+ 设备选择面板
  4. 点「立即加入」
  5. 期望:无需输入密码(邀请 token 已授权)
  6. 截图 → 02-bob-joined-via-invite.png

步骤 4资源与 DB 断言

# meeting_invites.consumed_at 应被填充
mysql -e "SELECT invite_token, invitee_id, consumed_at FROM meeting_invites \
         WHERE room_id=(SELECT id FROM meeting_rooms WHERE room_code='$ROOM_CODE')" echochat

# meeting_participants 应有 Bob 行joined_method='invite'
mysql -e "SELECT user_id, joined_method, invite_token FROM meeting_participants \
         WHERE room_id=(SELECT id FROM meeting_rooms WHERE room_code='$ROOM_CODE')" echochat

期望:

  • consumed_at 时间戳为最近几秒
  • Bob 行 joined_method='invite'invite_token 与邀请链接一致

步骤 5直接输入会议号不含邀请 token应要求密码

  1. 第三个 tab 以 task15_c 登录
  2. 会议首页 → 「通过会议号加入」 → 输入 $ROOM_CODE
  3. 预览页 / 加入接口应返回 ErrPasswordRequired → UI 弹出密码输入框
  4. 输入错误密码 wrong,断言返回 401 + UI 提示
  5. 输入正确密码 invite@2026,成功加入
  6. 截图 → 03-carol-password-join.png

步骤 6资源清理场景结束

Alice 结束会议;执行 01-create-and-join-by-code.md 步骤 6-7 的 Redis/DB 断言。

预期结果汇总

断言 预期
邀请 URL 不含 password hasPassword=false
Bob 免密通过邀请加入 HTTP 200 + WS room.join ACK
meeting_invites.consumed_at 时间戳 ≈ 加入瞬间
Carol 直接加入需要密码 401 → 输入后成功

失败排查

现象 定位
URL 仍含 password= P0-4 回归:frontend/src/store/meeting.js draftJoinPayload 是否将密码存内存
Bob 使用邀请仍被要求密码 meeting_service.JoinRoom 的 invite token 分支
consumed_at 仍为 NULL MeetingInviteDAO.Consume 未调 / 事务回滚