# 用户反馈系统 - E2E 测试详细规范

> **版本**: v1.0.4  
> **创建日期**: 2026-01-06  
> **最后更新**: 2026-01-07  
> **维护者**: FFOA QA Team  
> **参考文档**: `05-ui-interaction-spec.md`

---

## ✅ 执行与产出（无测试代码）

- 执行器：Agent + Playwright MCP
- 执行依据：本结构化文档（步骤 + 断言 + 数据）
- 报告产出：测试报告 Markdown（含截图）
- 报告路径：`testing/reports/{module}-{YYYY-MM-DD}-{type}-report.md`

---

## 📋 目录

- [测试覆盖范围](#测试覆盖范围)
- [测试准备](#测试准备)
- [最小断言规范](#最小断言规范)
- [页面测试规范](#页面测试规范)
- [通用测试场景](#通用测试场景)
- [性能与兼容性](#性能与兼容性)
- [测试数据](#测试数据)

---

## 📊 测试覆盖范围

| 模块 | 页面数 | 场景数 | 优先级 | 状态 |
|------|-------|-------|--------|------|
| 用户反馈 | 4 | 18 | P0/P1 | 🚧 进行中 |

**总计**: 4 个页面，18 个测试场景

---

## 🧪 测试准备

### 最小断言规范

- 每个用例至少包含 1 个“到达”断言（URL/页面/弹窗可见）
- 每个用例至少包含 1 个“成功/稳定”断言（提示气泡/数据/状态变化）
- 校验失败时弹窗必须保持打开
- 必须使用 `expect()` 进行断言

### 鉴权策略（storageState）

```json
{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": [
        "@playwright/mcp@latest",
        "--storage-state=testing/.auth/storageState.json"
      ]
    }
  }
}
```

### 等待策略

- 导航使用 `waitUntil: 'domcontentloaded'`
- 使用条件等待（`expect` / `waitForSelector`）替代硬编码等待

### 测试账号

```typescript
const TEST_ACCOUNTS = {
  admin: {
    username: 'test_admin',
    password: 'Admin@2026',
    roles: ['ADMINISTRATOR'],
    permissions: ['feedback:read', 'feedback:update', 'feedback:delete']
  },
  regionalAdmin: {
    username: 'test_feedback_cn',
    password: 'Admin@2026',
    roles: ['FEEDBACK_ADMIN_CN'],
    permissions: ['feedback:read', 'feedback:update']
  },
  user: {
    username: 'test_user',
    password: 'User@2026',
    roles: [],
    permissions: []
  }
};
```

### 测试环境

| 环境 | URL | 说明 |
|------|-----|------|
| 开发环境 | `http://localhost:3000` | 本地开发 |
| 测试环境 | `https://test.ff.com` | E2E 测试 |

### 前置条件

- [ ] 数据库初始化测试数据
- [ ] 测试账号已创建
- [ ] `storageState` 已生成

---

## 📄 页面测试规范

> 说明：以下为 E2E 测试规范与场景清单。

### 页面1: 反馈入口（悬浮按钮）

**路由**: 全局页面  
**权限要求**: 登录

**关键断言**:
- 到达断言：反馈弹窗可见
- 稳定断言：提交按钮可用

---

### 页面2: 我的反馈列表

**路由**: `/feedback`  
**权限要求**: 登录

**关键断言**:
- 到达断言：页面标题可见
- 稳定断言：列表或空状态渲染完成

---

### 页面3: 管理端列表

**路由**: `/settings/feedback`  
**权限要求**: `feedback:read`

**关键断言**:
- 到达断言：页面标题可见
- 稳定断言：列表数据渲染完成

---

### 页面4: 管理端详情

**路由**: `/settings/feedback/:id`  
**权限要求**: `feedback:read`

**关键断言**:
- 到达断言：URL 匹配
- 稳定断言：详情字段渲染完成

---

## ✅ 通用测试场景

### 场景 A: 提交反馈（P0）

1. 点击反馈入口
2. 填写类型、标题、内容
3. 提交

**断言**:
- 到达断言：弹窗可见
- 成功断言：出现提交成功提示

---

### 场景 A1: 提交反馈必填校验（P0）

1. 打开反馈弹窗
2. 不填写必填项直接提交

**断言**:
- 到达断言：弹窗仍可见
- 稳定断言：出现字段校验提示

---

### 场景 A2: 附件上限校验（P1）

1. 打开反馈弹窗
2. 输入 6 个附件 URL
3. 提交

**断言**:
- 到达断言：弹窗仍可见
- 成功断言：提示“附件数量超限”

---

### 场景 B: 查看我的反馈（P0）

1. 访问 `/feedback`
2. 等待列表渲染

**断言**:
- 到达断言：页面标题可见
- 稳定断言：表格或空状态显示

---

### 场景 B1: 我的反馈空状态（P1）

1. 访问 `/feedback`
2. 等待列表渲染

**断言**:
- 到达断言：页面标题可见
- 稳定断言：空状态提示可见

---

### 场景 B2: 我的反馈筛选（P1）

1. 访问 `/feedback`
2. 选择状态筛选
3. 选择类型筛选

**断言**:
- 到达断言：页面仍在 `/feedback`
- 稳定断言：列表结果与筛选一致

---

### 场景 B3: 查看我的反馈详情（P0）

1. 访问 `/feedback`
2. 点击“查看详情”

**断言**:
- 到达断言：详情页或弹窗可见
- 成功断言：不展示管理员内部备注

---

### 场景 C0: 管理端列表加载（P0）

1. 访问 `/settings/feedback`
2. 等待列表渲染

**断言**:
- 到达断言：页面标题可见
- 稳定断言：表格或空状态显示

---

### 场景 C0.1: 管理端筛选（P1）

1. 访问 `/settings/feedback`
2. 选择状态/类型/区域筛选

**断言**:
- 到达断言：页面仍在管理端列表
- 稳定断言：列表结果与筛选一致

---

### 场景 C: 管理员更新状态（P0）

1. 进入管理端详情
2. 更新状态为 `IN_PROGRESS`

**断言**:
- 到达断言：详情页可见
- 成功断言：状态徽章更新

---

### 场景 C1: 管理端详情加载（P1）

1. 访问 `/settings/feedback/:id`
2. 等待详情渲染

**断言**:
- 到达断言：URL 匹配
- 稳定断言：详情字段渲染完成

---

### 场景 C2: 管理端批量关闭（P1）

1. 在列表中选择多条记录
2. 触发批量关闭

**断言**:
- 到达断言：列表页可见
- 成功断言：成功提示显示，状态更新

---

### 场景 C3: 管理端批量关闭超限（P1）

1. 选择 101 条记录
2. 触发批量关闭

**断言**:
- 到达断言：列表页可见
- 成功断言：提示数量超限

---
## ⚡ 性能与兼容性

- 开发环境仅跑 Chromium
- CI 可启用多浏览器
- 页面加载使用 `domcontentloaded`

---

## 🧾 测试数据

```json
{
  "feedback": {
    "type": "BUG",
    "title": "测试反馈标题",
    "content": "测试反馈内容"
  },
  "attachments": ["https://cdn.example.com/feedbacks/test.png"]
}
```

---

## 🧾 测试报告（执行记录）

### 批次 2026-01-07-02

- 执行环境：`http://localhost:3000`
- 执行账号：管理员（itadmin）
- 执行方式：Playwright MCP（手工执行）
- 测试报告：`testing/reports/feedback-2026-01-07-e2e-report.md`

**汇总**：通过 11 / 失败 0 / 阻塞 2 / 待执行 0

| 编号 | 场景 | 结果 | 备注 |
| --- | --- | --- | --- |
| A | 提交反馈（P0） | 通过 | - |
| A1 | 提交反馈必填校验（P0） | 通过 | - |
| A2 | 附件上限校验（P1） | 通过 | - |
| B | 查看我的反馈（P0） | 通过 | - |
| B1 | 我的反馈空状态（P1） | 阻塞 | 已有反馈记录 |
| B2 | 我的反馈筛选（P1） | 通过 | - |
| B3 | 查看我的反馈详情（P0） | 通过 | - |
| C0 | 管理端列表加载（P0） | 通过 | - |
| C0.1 | 管理端筛选（P1） | 通过 | - |
| C | 管理员更新状态（P0） | 通过 | Pending -> In Progress |
| C1 | 管理端详情加载（P1） | 通过 | - |
| C2 | 管理端批量关闭（P1） | 通过 | 2 条记录批量关闭 |
| C3 | 管理端批量关闭超限（P1） | 阻塞 | 记录不足 101 条 |

---

**最后更新**: 2026-01-07  
**版本**: v1.0.4  
**维护者**: FFOA QA Team
