# 会议出勤（Meeting Attendance）- E2E 测试报告

> **日期**: 2026-01-25
> **执行人**: AI Agent + Playwright MCP
> **报告类型**: E2E 冒烟

## 测试范围
- 仪表盘访问与统计卡片展示
- 会议列表访问与数据加载
- 会议详情访问与信息展示
- 会议二维码页访问与二维码可见
- 系统用户签到提交与成功提示
- 访客签到页提交与成功提示
- 报表页访问与统计加载
- 系列会议页访问与数据加载
- 模板列表访问与空态展示
- 用户管理列表访问与数据加载
- 审计日志访问与统计卡片展示
- 会议创建页表单展示
- 会议编辑弹窗展示
- Teams 会议页访问与列表展示
- Teams 报表页访问与统计展示
- Teams 配置页访问与配置卡片展示
- 改密码页表单展示
- 模板创建表单展示
- 用户创建表单展示
- 用户编辑表单展示
- 用户重置密码表单展示

## 环境信息
- 前端地址: http://localhost:3000
- 后端地址: http://localhost:3001/api/v1
- 浏览器: Chromium（Playwright MCP）
- 设备: 桌面视口
- 执行时间: 2026-01-25
- storageState: `testing/storage/meeting-attendance-admin.json`
- 等待策略: domcontentloaded + 条件等待

## 执行命令
- 无脚本执行（使用 Playwright MCP 交互）

## 数据准备
- 创建会议：`POST /api/v1/meeting-attendance/meetings`
  - meetingId: `cmkussofo000hjx4d2uwytt9p`
  - title: `E2E Guest Check-in 2026-01-26T06:40`
  - startTime: `2026-01-26T06:50:09.366Z`
  - endTime: `2026-01-26T07:50:09.366Z`
  - timezone: `America/Los_Angeles`
  - location: `E2E Room`
- 追加参会人：`POST /api/v1/meeting-attendance/meetings/:id/required-attendees`
  - meetingId: `cmkussofo000hjx4d2uwytt9p`
  - name: `Test Guest`
  - email: `guest@test.com`
- 创建会议（扩展测试）：`POST /api/v1/meeting-attendance/meetings`
  - meetingId: `cmkusy3hf000kjx4dflr99eri`
  - title: `E2E Full Smoke 2026-01-26T06:44`
  - startTime: `2026-01-26T06:54:22.150Z`
  - endTime: `2026-01-26T07:54:22.150Z`
  - timezone: `America/Los_Angeles`
  - location: `E2E Room`
- 追加参会人（扩展测试）：`POST /api/v1/meeting-attendance/meetings/:id/required-attendees`
  - meetingId: `cmkusy3hf000kjx4dflr99eri`
  - name: `Test Guest`
  - email: `guest@test.com`
- 创建会议（提交测试）：`POST /api/v1/meeting-attendance/meetings`
  - meetingId: `cmkutupri000ojx4dx4rc0pfs`
  - title: `E2E Submit Meeting 2026-01-26T07:00`
  - startTime: `2026-01-26T23:00:00`
  - endTime: `2026-01-26T23:30:00`
  - timezone: `America/Los_Angeles`
  - location: `E2E Submit Room`
- 创建模板（提交测试）：`POST /api/v1/meeting-attendance/templates`
  - templateName: `E2E Template 2026-01-26T07:10`
  - meetingTitle: `E2E Template Meeting`
  - durationMinutes: `30`
  - location: `E2E Template Room`
- 模板创建会议（提交测试）：`POST /api/v1/meeting-attendance/templates/:id/create-meeting`
  - meetingId: `cmkuu11nx000sjx4dsse6qs5x`
  - title: `E2E Template Meeting`
  - startTime: `2026-01-27 09:00`
  - endTime: `2026-01-27 09:30`
  - timezone: `UTC`
- 创建用户（提交测试）：`POST /api/v1/meeting-attendance/users`
  - email: `e2e.user.20260126.0700@ff.com`
  - name: `E2E Submit User`
  - department: `IT`
  - company: `FF`
  - position: `QA`
  - defaultPassword: `najdozra`
- 重置密码（提交测试）：`POST /api/v1/meeting-attendance/users/:id/reset-password`
  - user: `E2E Submit User / e2e.user.20260126.0700@ff.com`
  - newPassword: `E2EReset@2026`

## 用例明细

### E2E-01 会议列表可访问并加载（P0）
- 前置条件: 已登录；存在会议数据
- 步骤:
  1) 打开 `/meetingattendance/meetings`
  2) 等待列表加载完成
- 断言:
  - 到达断言: 标题“Meeting Management”可见
  - 稳定断言: 列表中出现会议卡片（至少 1 条）
- 关联 API: [001] GET /meeting-attendance/meetings
- 结果: ✅ 通过
- 截图: `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-01-meetings-list-success.png`

### E2E-02 会议二维码页可访问并展示二维码（P0）
- 前置条件: 已登录；存在会议 ID
- 数据:
  - meetingId: `cmhhz1l2a005iy6ov1flgyohc`
  - 标题: `FFAI EC Meeting - Session 13 (01/26/2026)`
- 步骤:
  1) 打开 `/meetingattendance/meetings/cmhhz1l2a005iy6ov1flgyohc/qr`
- 断言:
  - 到达断言: 标题“Meeting Check-in QR Codes”可见
  - 稳定断言: 线上/线下二维码至少一个可见
- 关联 API: [003] GET /meeting-attendance/meetings/:id
- 结果: ✅ 通过
- 截图: `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-02-qr-success.png`

### E2E-03 访客签到可提交并成功提示（P0）
- 前置条件: 会议处于 SCHEDULED/IN_PROGRESS 且在可签到时间窗口内；参会名单包含该访客
- 数据:
  - meetingId: `cmkussofo000hjx4d2uwytt9p`
  - 访客: `Test Guest / guest@test.com`
- 步骤:
  1) 打开 `/meetingattendance/checkin/guest?meeting=cmkussofo000hjx4d2uwytt9p`
  2) 输入姓名与邮箱并提交
- 断言:
  - 到达断言: 访客签到表单可见
  - 成功断言: 出现“Check-in Successful”与参会信息
- 关联 API: [014] POST /meeting-attendance/meetings/:id/guest-checkin
- 结果: ✅ 通过
- 截图: `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-03-guest-checkin-success.png`

### E2E-04 报表页可访问并加载统计（P1）
- 前置条件: 已登录；存在统计数据
- 数据:
  - 选择会议: `E2E Guest Check-in 2026-01-26T06:37 - 1/25/2026, 10:47:49 PM`
- 步骤:
  1) 打开 `/meetingattendance/reports`
  2) 在单场会议报表中选择会议
- 断言:
  - 到达断言: 标题“Meeting Reports”可见
  - 稳定断言: 统计卡片出现数据（Required Attendees / Attended / Attendance Rate）
- 关联 API: [046] GET /meeting-attendance/reports/single-meeting
- 结果: ✅ 通过
- 截图: `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-04-reports-success.png`

### E2E-05 仪表盘可访问并展示概览（P1）
- 前置条件: 已登录
- 步骤:
  1) 打开 `/meetingattendance/dashboard`
- 断言:
  - 到达断言: 标题“Welcome back, IT Administrator”可见
  - 稳定断言: 概览卡片（Today's Meetings / Active Meetings / Total Users / Today's Attendance）可见
- 关联 API: [001] GET /meeting-attendance/meetings（间接）
- 结果: ✅ 通过
- 截图: `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-05-dashboard-success.png`

### E2E-06 会议详情可访问并展示信息（P0）
- 前置条件: 已登录；存在会议 ID
- 数据:
  - meetingId: `cmkusy3hf000kjx4dflr99eri`
  - 标题: `E2E Full Smoke 2026-01-26T06:44`
- 步骤:
  1) 打开 `/meetingattendance/meetings/cmkusy3hf000kjx4dflr99eri`
- 断言:
  - 到达断言: 标题“Meeting Details”可见
  - 稳定断言: 会议基本信息卡片可见
- 关联 API: [003] GET /meeting-attendance/meetings/:id
- 结果: ✅ 通过
- 截图: `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-06-meeting-detail-success.png`

### E2E-07 系统用户签到可提交并成功提示（P0）
- 前置条件: 已登录；会议处于可签到时间窗口内；当前用户在参会名单内
- 数据:
  - meetingId: `cmkusy3hf000kjx4dflr99eri`
  - 用户: `IT Administrator / itadmin@ff.com`
- 步骤:
  1) 打开 `/meetingattendance/checkin?meeting=cmkusy3hf000kjx4dflr99eri`
  2) 选择签到方式并提交
- 断言:
  - 到达断言: 系统签到页表单可见
  - 成功断言: 出现签到成功提示
- 关联 API: [013] POST /meeting-attendance/meetings/:id/checkin
- 结果: ✅ 通过
- 截图: `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-07-system-checkin-success.png`

### E2E-08 系列会议页可访问并加载（P1）
- 前置条件: 已登录；存在系列会议数据
- 步骤:
  1) 打开 `/meetingattendance/series`
- 断言:
  - 到达断言: 标题“Meeting Series”可见
  - 稳定断言: 系列会议卡片可见
- 关联 API: [016] GET /meeting-attendance/series
- 结果: ✅ 通过
- 截图: `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-08-series-list-success.png`

### E2E-09 模板列表可访问并展示空态（P1）
- 前置条件: 已登录；无模板或模板列表为空
- 步骤:
  1) 打开 `/meetingattendance/templates`
- 断言:
  - 到达断言: 标题“Meeting Templates”可见
  - 稳定断言: 空态文案“No templates yet”可见
- 关联 API: [029] GET /meeting-attendance/templates
- 结果: ✅ 通过
- 截图: `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-09-templates-list-success.png`

### E2E-10 用户管理列表可访问并加载（P1）
- 前置条件: 已登录；存在用户数据
- 步骤:
  1) 打开 `/meetingattendance/users`
- 断言:
  - 到达断言: 标题“User Management”可见
  - 稳定断言: 用户列表卡片可见
- 关联 API: [034] GET /meeting-attendance/users
- 结果: ✅ 通过
- 截图: `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-10-users-list-success.png`

### E2E-11 审计日志可访问并展示统计（P1）
- 前置条件: 已登录；存在审计日志数据
- 步骤:
  1) 打开 `/meetingattendance/audit-logs`
- 断言:
  - 到达断言: 标题“Audit Logs”可见
  - 稳定断言: 统计卡片（Total Logs / Top Action / Top Resource / Most Active User）可见
- 关联 API: [047] GET /meeting-attendance/audit-logs, [048] GET /meeting-attendance/audit-logs/stats
- 结果: ✅ 通过
- 截图: `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-11-audit-logs-success.png`

### E2E-12 会议创建页表单可访问并展示（P1）
- 前置条件: 已登录
- 步骤:
  1) 打开 `/meetingattendance/meetings/create`
- 断言:
  - 到达断言: 标题“Create Meeting”可见
  - 稳定断言: 表单字段（Title/Timezone/Start Time/End Time）可见
- 关联 API: 无（表单展示）
- 结果: ✅ 通过
- 截图: `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-12-meeting-create-form-success.png`

### E2E-13 会议编辑弹窗可访问并展示（P1）
- 前置条件: 已登录；存在会议 ID
- 数据:
  - meetingId: `cmkusy3hf000kjx4dflr99eri`
- 步骤:
  1) 打开 `/meetingattendance/meetings/cmkusy3hf000kjx4dflr99eri`
  2) 点击 “Edit”
- 断言:
  - 到达断言: 标题“Edit Meeting”可见
  - 稳定断言: 编辑表单字段可见
- 关联 API: [003] GET /meeting-attendance/meetings/:id
- 结果: ✅ 通过
- 截图: `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-13-meeting-edit-form-success.png`

### E2E-14 Teams 会议页可访问并加载列表（P1）
- 前置条件: 已登录
- 步骤:
  1) 打开 `/meetingattendance/teams/meetings`
- 断言:
  - 到达断言: 标题“My Meetings”可见
  - 稳定断言: 会议卡片列表可见
- 关联 API: [001] GET /meeting-attendance/meetings（Teams 页面数据源）
- 结果: ✅ 通过
- 截图: `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-14-teams-meetings-success.png`

### E2E-15 Teams 报表页可访问并展示统计（P1）
- 前置条件: 已登录；存在统计数据
- 步骤:
  1) 打开 `/meetingattendance/teams/reports`
  2) 等待统计卡片加载完成
- 断言:
  - 到达断言: 标题“Attendance Report”可见
  - 稳定断言: 统计卡片（Total Attendance Records / Checked In / Late / Attendance Rate）可见
- 关联 API: [044] GET /meeting-attendance/reports/attendance
- 结果: ✅ 通过
- 截图: `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-15-teams-reports-success.png`

### E2E-16 Teams 配置页可访问并展示配置（P1）
- 前置条件: 已登录
- 步骤:
  1) 打开 `/meetingattendance/teams/config`
- 断言:
  - 到达断言: 标题“Configure Meeting Attendance App”可见
  - 稳定断言: “Save Configuration”按钮可见
- 关联 API: 无（配置页静态内容）
- 结果: ✅ 通过
- 截图: `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-16-teams-config-success.png`

### E2E-17 改密码页可访问并展示表单（P1）
- 前置条件: 已登录
- 步骤:
  1) 打开 `/meetingattendance/settings/change-password`
- 断言:
  - 到达断言: 标题“Change Password”可见
  - 稳定断言: 表单字段（Current Password / New Password / Confirm New Password）可见
- 关联 API: 无（表单展示）
- 结果: ✅ 通过
- 截图: `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-17-change-password-success.png`

### E2E-18 模板创建表单可访问并展示（P1）
- 前置条件: 已登录
- 步骤:
  1) 打开 `/meetingattendance/templates`
  2) 点击 “Create Template”
- 断言:
  - 到达断言: 标题“Create Meeting Template”可见
  - 稳定断言: 表单字段（Template Name / Meeting Title / Duration）可见
- 关联 API: [029] GET /meeting-attendance/templates
- 结果: ✅ 通过
- 截图: `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-18-template-create-form-success.png`

### E2E-19 用户创建表单可访问并展示（P1）
- 前置条件: 已登录
- 步骤:
  1) 打开 `/meetingattendance/users`
  2) 点击 “Create User”
- 断言:
  - 到达断言: 标题“Create User”可见
  - 稳定断言: 表单字段（Email / Name / Role）可见
- 关联 API: [034] GET /meeting-attendance/users
- 结果: ✅ 通过
- 截图: `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-19-user-create-form-success.png`

### E2E-20 用户编辑表单可访问并展示（P1）
- 前置条件: 已登录；存在用户数据
- 数据:
  - 用户: `Test Guest / guest@test.com`
- 步骤:
  1) 打开 `/meetingattendance/users`
  2) 点击用户卡片上的编辑按钮
- 断言:
  - 到达断言: 标题“Edit User”可见
  - 稳定断言: 编辑表单字段可见（含只读 Email）
- 关联 API: [034] GET /meeting-attendance/users
- 结果: ✅ 通过
- 截图: `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-20-user-edit-form-success.png`

### E2E-21 用户重置密码表单可访问并展示（P1）
- 前置条件: 已登录；存在用户数据
- 数据:
  - 用户: `Test Guest / guest@test.com`
- 步骤:
  1) 打开 `/meetingattendance/users`
  2) 点击用户卡片上的“Reset Password”
- 断言:
  - 到达断言: 标题“Reset password for Test Guest”可见
  - 稳定断言: 表单字段（New Password / Confirm New Password）可见
- 关联 API: [042] POST /meeting-attendance/users/:id/reset-password
- 结果: ✅ 通过
- 截图: `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-21-user-reset-password-form-success.png`

### E2E-22 会议创建可提交并成功创建（P0）
- 前置条件: 已登录；具备创建会议权限
- 数据:
  - title: `E2E Submit Meeting 2026-01-26T07:00`
  - startTime: `2026-01-26T23:00`
  - endTime: `2026-01-26T23:30`
- 步骤:
  1) 打开 `/meetingattendance/meetings/create`
  2) 填写必填信息并提交
- 断言:
  - 到达断言: 详情页标题为新会议
  - 成功断言: 进入新会议详情页 `/meetingattendance/meetings/cmkutupri000ojx4dx4rc0pfs`
- 关联 API: [002] POST /meeting-attendance/meetings
- 结果: ✅ 通过
- 截图: `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-22-meeting-create-submit-success.png`

### E2E-23 模板创建可提交并成功创建（P1）
- 前置条件: 已登录
- 数据:
  - templateName: `E2E Template 2026-01-26T07:10`
  - meetingTitle: `E2E Template Meeting`
- 步骤:
  1) 打开 `/meetingattendance/templates`
  2) 填写模板信息并提交
- 断言:
  - 到达断言: 模板卡片标题可见
  - 成功断言: 提示 “Template created successfully”
- 关联 API: [030] POST /meeting-attendance/templates
- 结果: ✅ 通过
- 截图: `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-23-template-create-submit-success.png`

### E2E-24 用户创建可提交并成功创建（P1）
- 前置条件: 已登录；具备用户管理权限
- 数据:
  - email: `e2e.user.20260126.0700@ff.com`
  - name: `E2E Submit User`
- 步骤:
  1) 打开 `/meetingattendance/users`
  2) 填写用户信息并提交
- 断言:
  - 到达断言: 新用户卡片可见
  - 成功断言: 提示 “User created successfully”
- 关联 API: [035] POST /meeting-attendance/users
- 结果: ✅ 通过
- 截图: `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-24-user-create-submit-success.png`

### E2E-25 用户重置密码可提交并成功提示（P1）
- 前置条件: 已登录；存在目标用户
- 数据:
  - 用户: `E2E Submit User / e2e.user.20260126.0700@ff.com`
  - newPassword: `E2EReset@2026`
- 步骤:
  1) 打开 `/meetingattendance/users`
  2) 点击目标用户“Reset Password”并提交
- 断言:
  - 到达断言: 重置密码弹窗标题可见
  - 成功断言: 提示 “Password reset successfully”
- 关联 API: [042] POST /meeting-attendance/users/:id/reset-password
- 结果: ✅ 通过
- 截图: `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-25-user-reset-password-submit-success.png`

### E2E-26 模板创建会议可提交并成功创建（P1）
- 前置条件: 已登录；存在模板
- 数据:
  - templateName: `E2E Template 2026-01-26T07:10`
  - startTime: `2026-01-27 09:00`
  - endTime: `2026-01-27 09:30`
- 步骤:
  1) 打开 `/meetingattendance/templates`
  2) 点击模板“Create Meeting”
  3) 输入开始/结束时间并确认
- 断言:
  - 到达断言: 详情页标题“E2E Template Meeting”可见
  - 成功断言: 提示 “Meeting created successfully”
- 关联 API: [033] POST /meeting-attendance/templates/:id/create-meeting
- 结果: ✅ 通过
- 截图: `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-26-template-create-meeting-success.png`

## 失败/阻断汇总
- 无

## 覆盖度说明
- 覆盖页面: 17/17（仪表盘、会议列表、会议详情、二维码页、系统签到、访客签到、报表页、系列会议、模板、用户管理、审计日志、会议创建、会议编辑、Teams 会议/报表/配置、改密码）
- 覆盖核心流程: 仪表盘概览、会议列表访问、会议详情、二维码展示、系统/访客签到、报表统计加载、系列会议浏览、用户列表与审计日志浏览、会议/模板/用户创建、用户重置密码、模板创建会议、Teams 入口浏览、改密码入口
- 未覆盖页面: 无

## 契约一致性
- 本次冒烟未发现与文档契约冲突。

## 资产清单
- `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-01-meetings-list-success.png`
- `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-02-qr-success.png`
- `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-03-guest-checkin-success.png`
- `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-04-reports-success.png`
- `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-05-dashboard-success.png`
- `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-06-meeting-detail-success.png`
- `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-07-system-checkin-success.png`
- `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-08-series-list-success.png`
- `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-09-templates-list-success.png`
- `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-10-users-list-success.png`
- `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-11-audit-logs-success.png`
- `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-12-meeting-create-form-success.png`
- `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-13-meeting-edit-form-success.png`
- `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-14-teams-meetings-success.png`
- `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-15-teams-reports-success.png`
- `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-16-teams-config-success.png`
- `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-17-change-password-success.png`
- `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-18-template-create-form-success.png`
- `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-19-user-create-form-success.png`
- `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-20-user-edit-form-success.png`
- `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-21-user-reset-password-form-success.png`
- `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-22-meeting-create-submit-success.png`
- `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-23-template-create-submit-success.png`
- `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-24-user-create-submit-success.png`
- `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-25-user-reset-password-submit-success.png`
- `testing/reports/meeting-attendance-2026-01-25-e2e/E2E-26-template-create-meeting-success.png`

## 需要后续确认/行动
1) Teams 页面在非 Teams 宿主环境出现控制台报错（No Parent window found），需确认是否为预期行为。
