---
stepsCompleted: ['step-01-init', 'step-02-discovery', 'step-03-success', 'step-04-journeys', 'step-07-project-type', 'step-08-scoping', 'step-09-functional', 'step-10-nonfunctional', 'step-11-complete', 'revision-2025-01-10', 'revision-2026-01-12', 'revision-2026-01-15-business-context', 'revision-2026-01-15-order-stats-fields']
inputDocuments:
  - name: 项目文档索引
    path: docs/index.md
    type: project-knowledge
    loadedAt: '2026-01-07T12:00:00.000Z'
  - name: 测试策略
    path: docs/standards/testing-standards.md
    type: testing-standards
    loadedAt: '2026-01-07T12:00:00.000Z'
  - name: Web UI测试规范
    path: docs/standards/web-ui-testing-standards.md
    type: testing-standards
    loadedAt: '2026-01-07T12:00:00.000Z'
  - name: 残疾人管理组件
    path: allin-packages/disability-person-management-ui/src/components/DisabilityPersonManagement.tsx
    type: source-code
    loadedAt: '2026-01-07T12:00:00.000Z'
  - name: 残疾人实体模型
    path: allin-packages/disability-module/src/entities/disabled-person.entity.ts
    type: source-code
    loadedAt: '2026-01-07T12:00:00.000Z'
  - name: E2E测试示例
    path: web/tests/e2e/specs/admin/users.spec.ts
    type: test-reference
    loadedAt: '2026-01-07T12:00:00.000Z'
documentCounts:
  briefs: 0
  research: 0
  projectDocs: 3
  testReferences: 1
workflowType: 'prd'
lastStep: 6
revisedAt: '2026-01-15'
revisionNotes: '添加订单统计字段说明：实际人数、本月打卡、工资视频、个税视频的业务含义和数据来源；原有修订：扩展业务上下文章节：补充残疾人招聘管理系统的业务需求分析，包括系统概述、业务目标、用户角色、业务流程和实体关系；修订范围：从"测试工具包开发"扩展为"Web E2E 测试覆盖"，业务测试为主，工具包为支持手段；增加 Epic C: 订单管理 E2E 测试；新增 Epic D/E/F: 小程序相关测试（用户管理、跨端同步、基础配置）'
---

# Product Requirements Document - Web 应用 E2E 测试覆盖

**作者:** Root
**创建日期:** 2026-01-07
**修订日期:** 2026-01-15

---

## 业务上下文 (Business Context)

### 系统概述

这是一个残疾人招聘管理系统，包含三个端：

| 端 | 名称 | 用途 |
|----|------|------|
| **管理后台** | WEB | 系统管理员和企业管理员使用，负责所有配置和数据管理 |
| **企业小程序** | yongren | 企业用户查看订单、人才、统计数据 |
| **人才小程序** | rencai | 残疾人查看个人信息、打卡、查看考勤薪资 |

核心价值：为残疾人提供就业机会，为企业提供合规的残疾人用工管理。

### 业务目标

本系统的核心业务目标是：

1. **促进残疾人就业**：连接残疾人与用工企业，提供完整的招聘管理流程
2. **合规用工管理**：确保企业用工符合残疾人用工相关法规要求
3. **全流程数字化**：从订单创建到薪资发放的全流程线上化管理
4. **便捷信息查询**：通过小程序实现便捷的信息查询和打卡操作

### 用户角色

系统包含三类主要用户角色：

#### 1. 管理员（系统管理员）

**使用端：** 管理后台（WEB）

**主要职责：**
- 平台（Platform）配置管理
- 公司（Company）配置管理
- 渠道（Channel）配置管理
- 用户管理（创建企业用户和人才用户）
- 订单分配和管理
- 残疾人档案管理

**权限特点：** 拥有系统的最高权限，可以执行所有写操作。

#### 2. 企业管理员（企业用户）

**使用端：** 管理后台 + 企业小程序（yongren）

**主要职责：**
- 创建和管理订单（Order）
- 查看分配到订单的残疾人
- 查看企业统计数据
- 发放薪资

**权限特点：**
- 在管理后台：可以创建和管理订单
- 在企业小程序：只读查看数据，无写操作

#### 3. 残疾人/人才

**使用端：** 人才小程序（rencai）

**主要职责：**
- 查看个人信息
- 查看考勤记录
- 查看薪资信息
- **上下班打卡**（小程序中唯一的写操作）

**权限特点：** 主要是只读操作，仅可进行打卡操作。

### 核心业务流程

```
┌─────────────────────────────────────────────────────────────────────┐
│                        残疾人招聘管理流程                              │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  1. 管理员配置基础数据                                               │
│     └─ 创建 Platform（平台）                                         │
│     └─ 创建 Company（公司），关联 Platform                           │
│     └─ 创建 Channel（渠道，可选）                                     │
│                                                                     │
│  2. 企业管理员创建订单                                               │
│     └─ 创建 Order，选择 Platform、Company、Channel                   │
│     └─ 订单状态：草稿 → 已确认 → 进行中 → 已完成                     │
│                                                                     │
│  3. 管理员分配残疾人到订单                                           │
│     └─ 为订单添加 DisabledPerson（残疾人）                           │
│     └─ 设置残疾人在订单中的工作状态                                   │
│                                                                     │
│  4. 人才通过小程序打卡上岗                                           │
│     └─ 使用人才小程序进行上下班打卡                                   │
│     └─ 打卡记录同步到 Attendance 表                                  │
│                                                                     │
│  5. 企业查看统计数据并发放薪资                                       │
│     └─ 通过企业小程序查看订单统计                                     │
│     └─ 发放薪资到人才银行卡                                           │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘
```

### 核心实体关系

```
Platform (平台)
  │ 1:N
  ▼
Company (公司)
  │ 1:N (必须 platformId)
  ▼
Order (订单)
  │ 1:N (必须 companyId，可选 channelId)
  ▼
DisabledPerson (残疾人/人才)
  │ 关联
  ├─► Attendance (考勤打卡记录)
  └─► Salary (薪资记录)
```

**实体说明：**

| 实体 | 说明 | 关键字段 |
|------|------|---------|
| **Platform** | 平台 | 平台名称、配置信息 |
| **Company** | 公司 | 公司名称、platformId（必选） |
| **Channel** | 渠道 | 渠道名称、类型（可选） |
| **Order** | 订单 | 订单标题、platformId、companyId、channelId、状态 |
| **DisabledPerson** | 残疾人/人才 | 姓名、身份证号、残疾类型、银行卡信息 |
| **Attendance** | 考勤打卡 | 关联人员、打卡时间、打卡类型（上班/下班） |
| **Salary** | 薪资 | 关联人员、金额、发放时间 |

**重要约束：**
- Company 必须关联一个 Platform
- Order 必须关联一个 Platform 和一个 Company
- Channel 是订单的可选项

### 订单统计字段

企业小程序的订单卡片中显示以下统计字段，用于企业了解订单执行情况：

#### 实际人数
- **业务含义**：当前订单实际关联的残疾人人数
- **数据来源**：`order_person` 表
- **计算逻辑**：统计 `order_person` 表中 `order_id` 等于当前订单 ID 的记录数量
- **显示格式**：`XX人`

#### 本月打卡
- **业务含义**：本月内残疾人上下班打卡的视频记录数量统计
- **数据来源**：`order_person_asset` 表，`asset_type='checkin_video'`
- **计算逻辑**：统计本月内该订单关联人员的打卡视频数量，格式为 `实际打卡数/订单总人数 百分比`
- **显示格式**：
  ```
  本月打卡
  24/30
  80%
  ```

#### 工资视频
- **业务含义**：残疾人每月薪资确认视频，用于合规证明和薪资发放记录
- **数据来源**：`order_person_asset` 表，`asset_type='salary_video'`
- **计算逻辑**：统计本月内该订单关联人员的工资确认视频数量
- **显示格式**：
  ```
  工资视频
  22/24
  92%
  ```

#### 个税视频
- **业务含义**：残疾人每月个税确认视频，用于税务合规证明
- **数据来源**：`order_person_asset` 表，`asset_type='tax_video'`
- **计算逻辑**：统计本月内该订单关联人员的个税确认视频数量
- **显示格式**：
  ```
  个税视频
  20/24
  83%
  ```

#### 数据实体关系

```
OrderPersonAsset (人员资产/视频)
  ├─► CHECKIN_VIDEO (打卡视频) → 本月打卡统计
  ├─► SALARY_VIDEO (工资视频) → 工资视频统计
  └─► TAX_VIDEO (个税视频) → 个税视频统计
```

### 小程序与管理后台的分工

| 操作类型 | 管理后台 | 企业小程序 | 人才小程序 |
|---------|---------|-----------|-----------|
| **创建** | 全部创建权限 | 无 | 无 |
| **编辑/更新** | 全部编辑权限 | 无 | 无 |
| **删除** | 全部删除权限 | 无 | 无 |
| **查看** | 全部查看权限 | 订单、人才、统计 | 个人信息、考勤、薪资 |
| **打卡** | - | - | 上班/下班打卡 |

**数据同步机制：**
- 后台操作后，数据实时同步到小程序
- 小程序通过 WebSocket 接收数据更新
  - 企业小程序：`/mini-ws`
  - 人才小程序：`/talent-mini-ws`
- 人才打卡记录同步到后台

### 技术栈概览

| 层级 | 技术 |
|------|------|
| **前端** | React 19 |
| **后端** | Hono 4.x |
| **数据库** | PostgreSQL + TypeORM |
| **E2E 测试** | Playwright |
| **项目结构** | Monorepo |

### 本 PRD 的范围

本 PRD 专注于 **Web 管理后台的 E2E 测试覆盖**，确保以下功能的质量：

1. **残疾人管理**（Epic A）- 已完成
2. **区域管理**（Epic B）- 待开发
3. **订单管理**（Epic C）- 待开发
4. **用户管理与小程序登录**（Epic D）- 待开发
5. **跨端数据同步**（Epic E）- 待开发
6. **基础配置管理**（Epic F）- 待开发

小程序端的测试（Epic D/E）作为扩展范围，验证完整的业务流程。

---

## 执行摘要

本项目旨在为 Web 管理后台的关键业务功能建立完整的 E2E 测试覆盖。在编写业务测试的过程中，将通用测试模式抽象到 `@d8d/e2e-test-utils` 包中，以加速后续功能的测试开发。

### 项目背景

188-179 招聘系统是一个大型企业级 Monorepo 招聘管理平台，采用 React 19 + Hono 4.x + TypeORM 技术栈。现有 E2E 测试使用 Playwright，遵循 Page Object 模式。

当前残疾人管理功能已经实现了完整的业务逻辑，包括：
- 照片上传管理（身份证、残疾证、个人照片等）
- 银行卡信息管理（支持多张卡）
- 备注管理（支持特殊需求标记）
- 回访记录管理

订单管理是招聘系统的核心业务功能，包括：
- 订单 CRUD 操作（创建、查看、编辑、删除）
- 订单状态管理（草稿、已确认、进行中、已完成、已取消）
- 人员关联管理（添加残疾人到订单、管理工作状态）
- 附件管理（添加订单相关资产文件）
- 多维度筛选（按平台、公司、渠道、状态等）

但 E2E 测试覆盖不完整，需要补充这些功能的测试用例。

### 核心目标

**主目标：为 Web 管理后台的业务功能建立完整的 E2E 测试覆盖**

**副目标：在测试过程中抽象可复用工具**

**工作方式：测试驱动 + 工具演进**

1. **编写业务 E2E 测试**（主任务）
   - 优先完成业务功能的测试覆盖
   - 验证业务逻辑的正确性
   - 确保测试稳定性

2. **抽象通用测试工具**（自然演进）
   - 从业务测试中发现重复模式
   - 将通用模式抽象到 `@d8d/e2e-test-utils` 包
   - 持续完善工具函数

3. **输出两种形式**
   - **业务测试覆盖**：完整的 E2E 测试用例
   - **共享测试工具包**：`packages/e2e-test-utils`

### Epic 组织

本项目按业务功能组织为多个 Epic：

| Epic | 内容 | 状态 |
|------|------|------|
| **Epic A: 残疾人管理 E2E 测试** | 完整的残疾人管理功能测试覆盖 | ✅ 已完成 |
| **Epic B: 区域管理 E2E 测试** | 区域管理（省市区街道）测试覆盖 | 🔄 待开发 |
| **Epic C: 订单管理 E2E 测试** | 订单管理（CRUD、状态流转、人员关联）测试覆盖 | 📋 待开发 |
| **Epic D: 用户管理与小程序登录测试** | 用户创建、小程序登录 E2E 测试 | 🆕 待开发 |
| **Epic E: 跨端数据同步测试** | 后台操作 → 小程序数据验证 | 🆕 待开发 |
| **Epic F: 基础配置管理测试** | 平台、公司、渠道配置管理测试 | 🆕 待开发 |
| **Epic G: e2e-test-utils 包维护** | 支持性任务：维护测试工具包 | 🌟 持续演进 |

**说明**：
- Epic A、B、C 是**管理后台业务测试 Epic**，直接交付业务价值
- Epic D、E、F 是**小程序相关测试 Epic**，扩展测试覆盖到完整业务流程
- Epic G 是**支持性 Epic**，为业务测试提供工具支持
- 工具包的开发是**自然演进**的结果，不是预先规划的目标

### 特殊价值

**这个项目的特殊之处在于：**

1. **业务价值优先**：直接交付业务测试覆盖，确保产品质量

2. **工具自然演进**：不是"为了做工具而做工具"，而是从实践中抽象

3. **双重收益**：
   - 直接收益：完成业务功能的 E2E 测试覆盖
   - 长期收益：可复用的测试工具，加速后续开发

4. **降低认知负担**：新测试开发者不需要深入理解 Radix UI 内部机制，只需调用统一 API

5. **提高测试稳定性**：统一的等待策略、错误处理和重试逻辑

### 为什么现在做

- 残疾人管理功能已实现，E2E 测试覆盖是质量保障的需要
- 在编写残疾人管理测试时，发现可以抽象通用工具
- 未来还有更多管理功能需要测试，提前建立工具能避免重复工作
- 区域管理功能需要测试，是继续实践的好机会
- 订单管理是招聘系统的核心业务功能，涵盖 CRUD、状态流转、人员关联等复杂场景，是测试工具演进的绝佳实践场

---

## 项目分类

**技术类型：** `testing`（E2E 测试覆盖）

**领域：** `web_admin`（Web 管理后台业务功能测试）

**复杂度：** `medium`（业务测试 + 工具抽象）

**项目上下文：** 棕地项目 - 为现有 Web 管理后台补充 E2E 测试覆盖，遵循现有 Page Object 模式

---

## 成功标准

### 用户成功

**测试开发者视角的成功指标：**

1. **快速上手**
   - 新测试开发者在 30 分钟内能写出第一个包含 Radix UI Select 的测试用例
   - 不需要深入研究 Radix UI 内部机制或 DOM 结构

2. **一次成功**
   - 第一次运行测试就通过，不需要反复调试时序问题
   - 测试连续运行 20 次全部通过，无 flaky 失败

3. **易于维护**
   - 其他团队成员接手测试时，能在 10 分钟内理解并修改测试代码
   - 测试代码清晰表达意图，不需要注释就能看懂

4. **稳定的开发体验**
   - 测试失败时能快速定位是产品问题还是测试问题
   - 有清晰的错误提示指向问题所在

### 业务成功

**业务测试覆盖率（主指标）：**

| 业务功能 | 目标覆盖率 | 当前状态 | 测量方式 |
|---------|-----------|---------|---------|
| 残疾人管理 | 关键流程 100% | ✅ 已完成 | 代码覆盖率报告 |
| 区域管理 | 关键流程 100% | 🔄 待开发 | 代码覆盖率报告 |
| 订单管理 | 关键流程 100% | 📋 待开发 | 代码覆盖率报告 |
| 其他管理功能 | 按需补充 | ⏳ 规划中 | 业务优先级 |

**短期（1-3个月）**
- E2E 测试编写时间减少 50%（相比之前每次重新摸索）
- 残疾人管理功能的测试覆盖率达到关键用户流程 100% ✅
- 区域管理功能的测试覆盖率达到关键用户流程 100%
- 订单管理功能的测试覆盖率达到关键用户流程 100%
- 工具函数被业务测试自然复用

**中期（3-6个月）**
- 新功能的 E2E 测试开发周期显著缩短
- E2E 测试的 flaky 率降低到 5% 以下
- 至少 4 个管理功能完成 E2E 测试覆盖（残疾人、区域、订单、其他）

**长期（6-12个月）**
- 建立 E2E 测试规范成为团队标准
- 新人 E2E 测试培训时间减少 70%
- 测试工具函数成为项目的标准基础设施

### 技术成功

**代码质量**
- 共享工具函数的测试覆盖率 ≥ 80%
- TypeScript 类型安全，无 any 类型
- 代码通过 ESLint 和 TypeScript 严格模式检查

**可扩展性**
- 新增组件测试模式只需扩展，无需修改核心逻辑
- 支持未来的 Radix UI 版本升级
- 工具函数设计支持配置和自定义

**文档完整性**
- 测试指南覆盖所有提取的模式
- 每个模式至少提供 1 个实际使用示例
- 文档清晰说明静态 vs 异步 Select 的区别

### 可衡量的结果

| 指标 | 当前状态 | 目标状态 | 测量方式 |
|------|---------|---------|---------|
| 残疾人管理测试覆盖率 | ✅ 关键流程 100% | ✅ 已达成 | 代码覆盖率报告 |
| 区域管理测试覆盖率 | 0% | 关键流程 100% | 代码覆盖率报告 |
| 订单管理测试覆盖率 | 0% | 关键流程 100% | 代码覆盖率报告 |
| Radix Select 测试编写时间 | 需要研究/摸索 | 5 分钟内完成 | 计时实验 |
| 测试稳定性（通过率） | 良好 | 20 次连续运行 100% 通过 | 自动化运行 |
| 工具函数测试覆盖率 | 进行中 | ≥ 80% | 代码覆盖率报告 |
| 文档完整性 | 基础 | 覆盖所有工具 + 示例 | 文档检查清单 |

---

## 产品范围

### MVP - Minimum Viable Product

**核心：为 Web 管理后台的业务功能建立完整的 E2E 测试覆盖**

**1. Epic A: 残疾人管理 E2E 测试** ✅ 已完成

完整的残疾人管理功能测试覆盖：

- 照片上传功能测试（身份证、残疾证、个人照片）
- 银行卡管理功能测试（添加、编辑、删除）
- 备注功能测试（添加、修改、删除）
- 回访功能测试（记录创建、查看）
- 完整流程测试（所有功能组合）

**测试过程中抽象的工具：**
- Radix UI Select 测试工具（静态/异步）
- 文件上传测试工具
- 其他表单交互工具

**2. Epic B: 区域管理 E2E 测试** 🔄 当前目标

区域管理功能的完整测试覆盖：

- 区域列表查看测试
- 添加区域测试（省/市/区/街道）
- 编辑区域测试
- 删除区域测试
- 级联选择测试（省市区街道四级联动）
- 完整流程测试

**可能需要抽象的工具：**
- 级联选择测试工具（如现有工具不满足需求）
- 树形结构操作工具（如需要）

**3. Epic C: 订单管理 E2E 测试** 📋 待开发

订单管理功能的完整测试覆盖（核心业务功能）：

- 订单列表功能测试（查看、搜索、筛选、分页）
- 订单 CRUD 测试（创建、编辑、删除订单）
- 订单状态流转测试（激活订单、关闭订单）
- 订单详情查看测试
- 人员关联功能测试（添加人员到订单、管理工作状态）
- 附件管理测试（添加附件）
- 完整流程测试

**可能需要抽象的工具（按需）：**
- 复杂表单提交工具（订单表单包含多个选择器：平台、公司、渠道）
- 状态流转测试工具（订单状态变更操作）
- 资产附件操作工具

**4. e2e-test-utils 包** 🌟 支持性任务

作为业务测试的支持工具，自然演进：

```
packages/e2e-test-utils/
├── src/
│   ├── index.ts
│   ├── select.ts            # Radix UI Select 工具 ✅
│   ├── file-upload.ts       # 文件上传工具 🔄
│   └── ...                  # 其他工具（按需添加）
├── tests/
└── README.md
```

**价值主张：** 业务测试覆盖直接交付价值，工具包是自然演进的支持产物。

**5. Epic D: 用户管理与小程序登录测试** 🆕 待开发

用户管理和小程序登录的完整测试覆盖：

**测试前置条件：**
- 管理员创建企业用户（EMPLOYER 类型），关联公司
- 管理员创建人才用户（TALENT 类型），关联残疾人
- 用户可登录到对应小程序

**测试场景：**
- 用户管理 Page Object 开发
- 后台创建企业用户测试
- 后台创建人才用户测试
- 企业小程序 Page Object 开发
- 企业小程序登录测试
- 人才小程序 Page Object 开发
- 人才小程序登录测试
- 用户权限验证测试（确保小程序无写操作）

**技术要点：**
- 小程序通过 H5 URL 访问（`/mini` 和 `/talent-mini`）
- 使用 Playwright 测试 H5 页面
- 登录后存储 token 进行后续操作

**6. Epic E: 跨端数据同步测试** 🆕 待开发

验证后台操作后小程序端的数据同步：

**测试场景：**
- 后台创建订单 → 企业小程序验证订单显示
- 后台编辑订单 → 企业小程序验证订单更新
- 后台添加残疾人到订单 → 人才小程序验证人员显示
- 后台更新工作状态 → 双小程序验证状态同步
- 跨端测试稳定性验证

**技术要点：**
- 多 Page 对象管理（后台 + 小程序）
- 数据同步等待策略
- WebSocket 通信验证（`/mini-ws`、`/talent-mini-ws`）
- 测试隔离和清理

### 业务流程缺失分析

在 Epic 13 的验证过程中，发现以下业务流程缺失：

#### 1. 打卡记录创建流程

| 项目 | 状态 | 说明 |
|------|------|------|
| **打卡记录导出** | ✅ 已实现 | 管理后台可以导出打卡记录为 Excel |
| **打卡记录录入** | ❌ 缺失 | 管理后台无 UI 可添加打卡记录 |
| **小程序打卡功能** | ❓ 未确认 | 需确认小程序端是否有打卡功能 |

**业务影响**：
- 测试人员无法通过 UI 创建打卡测试数据
- 业务流程不完整：只有"导出"没有"录入"
- 如果需要添加历史打卡记录，只能通过 API

**建议方案**：

1. **管理后台添加"添加打卡记录"对话框**（推荐用于测试）
   - 位置：订单详情 → 人员管理 → 点击人员 → 添加打卡记录
   - 字段：打卡日期、打卡时间、打卡类型（上班/下班）、视频文件

2. **小程序端实现残疾人打卡功能**（推荐用于生产）
   - 残疾人用户通过人才小程序进行上下班打卡
   - 自动记录打卡时间和地点
   - 打卡记录同步到后台

**相关发现来源**：
- **验证时间**: 2026-01-16
- **验证方式**: Playwright MCP 手动探索管理后台 UI
- **验证 Story**: Story 13-14 (订单详情页统计修复)

**管理后台路径说明**：
- 订单详情页: 订单管理 → 选择订单 → 点击"详情"按钮
- 资源上传: 订单详情对话框 → 资源上传按钮 → 选择月份（年/月）→ 对应列点击"上传文件"

**7. Epic F: 基础配置管理测试** 🆕 待开发

平台、公司、渠道配置管理的测试覆盖：

**实体关系链：**
```
Platform (平台)
  ↓ 1:N
Company (公司) - 必须 platformId
  ↓ 1:N
Order (订单) - 必须 companyId
```

**测试场景：**
- Platform 管理测试
  - 创建测试平台
  - 验证平台列表显示
- Company 管理测试（重点）
  - 创建测试公司（需要先有平台）
  - 验证公司列表显示
  - 验证平台关联
- Channel 管理测试（可选）
  - 创建测试渠道
  - 验证渠道列表显示
- 配置数据验证
  - 验证订单可以选择平台和公司
  - 验证用户可以关联公司

**重要性说明：**
- Platform 是订单创建的必要条件
- Company 是订单和企业用户的必要条件（关联 Platform）
- Channel 是订单的可选条件

---

**Epic 优先级建议：**

**Phase 1（当前进行中）：**
1. **Epic B: 区域管理** - 相对简单，可作为工具演进实践
2. **Epic C: 订单管理** - 核心业务功能，复杂场景

**Phase 2（小程序测试）：**
3. **Epic F: 基础配置管理** - 为后续 Epic 提供测试数据
   - 必须先完成：Platform 和 Company 测试
4. **Epic D: 用户管理与小程序登录** - 小程序测试的入口
   - 依赖：Epic F（需要 Company 数据）
5. **Epic E: 跨端数据同步测试** - 验证完整业务流程
   - 依赖：Epic D 和 Epic C

### Growth Features (Post-MVP)

**更多业务功能的 E2E 测试覆盖：**
- 其他管理功能的测试（按业务优先级）
- 用户权限管理测试
- 系统配置管理测试
- 报表功能测试

**工具包持续演进（按需）：**
- 在编写新业务测试时，如发现重复模式则抽象新工具
- Date Picker、Slider、Tabs 等 Radix 组件测试模式（如业务需要）
- 表单验证错误处理测试模式（如业务需要）

**开发体验增强：**
- VS Code snippets 快速插入测试代码
- 测试模板和最佳实践文档
- 更完善的错误提示和调试信息

### Vision (Future)

**完整的 E2E 测试覆盖：**
- Web 管理后台所有关键功能的测试覆盖
- 自动化测试作为 CI/CD 的标准环节
- 测试覆盖率可视化仪表盘

**智能化测试开发：**
- AI 辅助测试编写（描述行为自动生成测试）
- 自动发现页面组件并生成测试骨架
- 智能等待策略（根据组件特性自动调整）

**团队测试文化：**
- 测试驱动开发成为团队标准实践
- 新人培训包含 E2E 测试开发
- 测试模式库和最佳实践分享

---

## 用户旅程

### 旅程 1：张伟 - 赶时间的测试开发者

**人物设定：**
- **姓名：** 张伟
- **角色：** 全栈开发者，需要为新功能编写 E2E 测试
- **情境：** 产品经理刚刚要求他为残疾人管理功能补充完整的 E2E 测试
- **痛点：** 之前每次写测试都要花大量时间研究 Radix UI 的 DOM 结构，测试经常因为时序问题失败
- **目标：** 快速完成测试任务，测试要稳定可靠

**他的故事：**

周一早上，张伟接到任务："残疾人管理功能需要补充照片上传、银行卡管理等功能的 E2E 测试，周三前完成。"

张伟叹了口气。上次写测试时，他花了整整一下午研究 Radix UI Select 的测试方法，还要处理各种时序问题。测试写完后还经常 flaky，团队 CI 管道里经常因为这个功能失败。

他打开项目，注意到有个新包 `packages/e2e-test-utils`。他好奇地点开 README，发现里面正好有他需要的 Radix UI Select 测试工具。

他决定试一试。只需要导入工具函数，然后调用 `selectRadixOption(page, '残疾类型', '视力残疾')` 就可以了。不需要研究 DOM 结构，不需要处理复杂的等待逻辑。

**第一个小时：** 张伟轻松完成了照片上传和银行卡管理的测试。这些功能之前他一直觉得很难测试，现在居然这么简单。

**第二个小时：** 他继续添加备注和回访功能的测试。遇到异步加载的省份选择器时，他发现工具函数已经处理了等待逻辑，直接用 `selectRadixOptionAsync` 就可以了。

**第三个小时：** 张伟写完最后一个测试，点击运行。所有测试一次性通过！他有些不敢相信，又运行了 5 次，全部稳定通过。

**结果：** 周二下午，张伟不仅完成了所有测试，还把工具函数推荐给了团队其他成员。他甚至有时间优化测试代码，让测试更清晰易懂。

---

### 旅程需求总结

这些用户旅程揭示了以下核心需求：

**测试开发者（张伟）的需求：**
- 简单易用的 API，不需要深入理解 Radix UI
- 自动处理等待和时序问题
- 清晰的错误提示和调试信息
- 完整的使用文档和示例
- 工具函数开箱即用，快速集成

**新手测试开发者的需求：**
- 快速入门指南，降低学习曲线
- 渐进式的学习路径（从简单到复杂）
- 丰富的实际代码示例
- 常见问题和解决方案文档

**QA 工程师的需求：**
- 测试工具函数的可靠性保障
- 测试覆盖率和质量报告
- 测试最佳实践指南
- 团队协作和代码审查支持

**Tech Lead 的需求：**
- 代码质量和可维护性标准
- 测试模式的一致性和规范性
- 技术决策文档和架构说明
- 团队培训和知识传递材料

---

## Developer Tool Specific Requirements

### Project-Type Overview

188-179 E2E 测试工具包是一个**开发者工具库**，专注于简化 Playwright E2E 测试中对 Radix UI 组件的测试。作为内部工具包，它需要提供清晰的 API、完整的类型安全和易用的开发体验。

### Technical Architecture Considerations

**语言与类型系统：**
- 纯 TypeScript 实现，目标 ES2020+
- 严格类型检查，无 `any` 类型
- 完整的 JSDoc 注释用于 IDE 提示

**包结构：**
```
packages/e2e-test-utils/
├── package.json
├── src/
│   ├── index.ts              # 主导出
│   ├── radix-select.ts       # Radix UI Select 工具
│   ├── file-upload.ts        # 文件上传工具
│   ├── form-helper.ts        # 表单辅助函数
│   ├── dialog.ts             # 对话框操作
│   └── dynamic-list.ts       # 动态列表管理
├── tests/                    # 工具函数的单元测试
└── README.md
```

**依赖管理：**
- Peer dependency: `@playwright/test` (由测试项目提供)
- 无运行时依赖，保持轻量
- 开发依赖: TypeScript, Vitest (用于自测)

### Language & API Matrix

| 组件类型 | 工具函数 | 参数 | 返回值 |
|---------|---------|------|--------|
| Radix UI Select (静态) | `selectRadixOption(page, label, value)` | Page, 标签文本, 选项值 | Promise\<void\> |
| Radix UI Select (异步) | `selectRadixOptionAsync(page, label, value, options)` | Page, 标签文本, 选项值, 等待配置 | Promise\<void\> |
| 文件上传 | `uploadFileToField(page, selector, fileName)` | Page, 选择器, 文件名 | Promise\<void\> |
| 多步骤表单 | `fillMultiStepForm(page, steps)` | Page, 步骤数组 | Promise\<void\> |
| 动态列表 | `addDynamicListItem(page, itemType, data)` | Page, 项类型, 数据 | Promise\<void\> |
| 对话框操作 | `handleDialog(page, action)` | Page, 操作类型 | Promise\<void\> |

### Installation Methods

**在测试项目中安装：**

```bash
# 在 web/ 目录下
pnpm add -D @d8d/e2e-test-utils@workspace:*
```

**在测试文件中导入：**

```typescript
import { selectRadixOption, uploadFileToField } from '@d8d/e2e-test-utils';
```

### API Surface

**核心工具函数签名：**

```typescript
/**
 * 选择 Radix UI 下拉框的静态选项
 * @param page Playwright Page 对象
 * @param label 下拉框标签文本
 * @param value 要选择的选项值
 */
export async function selectRadixOption(
  page: Page,
  label: string,
  value: string
): Promise<void>

/**
 * 选择 Radix UI 下拉框的异步加载选项
 * @param page Playwright Page 对象
 * @param label 下拉框标签文本
 * @param value 要选择的选项值
 * @param options 等待配置 (超时、重试等)
 */
export async function selectRadixOptionAsync(
  page: Page,
  label: string,
  value: string,
  options?: AsyncSelectOptions
): Promise<void>

/**
 * 上传文件到指定字段
 * @param page Playwright Page 对象
 * @param selector 文件输入选择器
 * @param fileName 要上传的文件名（相对于 fixtures 目录）
 */
export async function uploadFileToField(
  page: Page,
  selector: string,
  fileName: string
): Promise<void>
```

### Code Examples

**示例 1：选择静态枚举型下拉框**

```typescript
import { selectRadixOption } from '@d8d/e2e-test-utils';

// 选择残疾类型
await selectRadixOption(page, '残疾类型', '视力残疾');
```

**示例 2：选择异步加载的下拉框**

```typescript
import { selectRadixOptionAsync } from '@d8d/e2e-test-utils';

// 选择省份（异步加载）
await selectRadixOptionAsync(page, '省份', '广东省', {
  timeout: 5000,
  waitForOption: true
});
```

**示例 3：上传照片**

```typescript
import { uploadFileToField } from '@d8d/e2e-test-utils';

// 上传身份证照片
await uploadFileToField(page, '[data-testid="id-card-photo-input"]', 'sample-id-card.jpg');
```

### Migration Guide

**从现有的内联测试代码迁移到工具函数：**

**之前（内联代码）：**
```typescript
// 需要手动处理 Radix UI 的复杂 DOM 结构和时序
await page.click(`text=残疾类型`);
await page.waitForSelector('[role="option"]');
await page.click(`[role="option"]:has-text("视力残疾")`);
```

**之后（使用工具函数）：**
```typescript
import { selectRadixOption } from '@d8d/e2e-test-utils';

await selectRadixOption(page, '残疾类型', '视力残疾');
```

**迁移步骤：**
1. 安装工具包：`pnpm add -D @d8d/e2e-test-utils@workspace:*`
2. 导入需要的工具函数
3. 替换内联的 Radix UI 操作代码
4. 验证测试通过

### Implementation Considerations

**等待策略：**
- 使用 `waitForLoadState('networkidle')` 处理异步加载
- 为静态选项设置合理默认超时（2秒）
- 为异步选项提供可配置超时

**错误处理：**
- 提供清晰的错误消息，指出具体失败点
- 区分"元素未找到"和"超时"错误
- 包含上下文信息（选择器、标签、期望值）

**测试稳定性：**
- 使用 Playwright 的 auto-waiting 机制
- 添加显式等待防止时序问题
- 支持重试机制处理 flaky 网络请求

**可扩展性：**
- 工具函数支持配置对象参数
- 预留钩子函数用于自定义行为
- 设计支持未来 Radix UI 版本升级

---

## Project Scoping & Phased Development

### MVP Strategy & Philosophy

**MVP 方法：** 测试驱动 + 工具演进

核心理念：优先完成业务功能的 E2E 测试覆盖，在测试过程中自然抽象可复用工具。工具包是支持手段，不是目标本身。

**资源需求：**
- 团队规模：1-2 名开发者
- 技能要求：TypeScript、Playwright、业务理解
- 时间估算：每个业务功能 1-2 周

### MVP Feature Set (Phase 1)

**核心用户旅程支持：**
- ✅ 张伟的快速测试开发旅程（残疾人管理测试）
- 🔄 张伟继续旅程（区域管理测试）
- 📋 张伟再出发（订单管理测试）

**Epic A: 残疾人管理 E2E 测试** ✅ 已完成

**业务测试覆盖：**
- 照片上传功能测试
- 银行卡管理功能测试
- 备注功能测试
- 回访功能测试
- 完整流程测试

**测试过程中抽象的工具：**
- `selectRadixOption()` - 静态枚举型下拉框
- `selectRadixOptionAsync()` - 异步加载型下拉框
- `uploadFileToField()` - 文件上传
- 其他表单辅助函数

**Epic B: 区域管理 E2E 测试** 🔄 当前目标

**业务测试覆盖：**
- 区域列表查看
- 添加区域（省/市/区/街道）
- 编辑区域
- 删除区域
- 级联选择测试
- 完整流程测试

**可能需要抽象的工具（按需）：**
- 级联选择工具（如现有 `selectCascade` 不满足需求）
- 树形结构操作工具（如需要）

**Epic C: 订单管理 E2E 测试** 📋 待开发

**业务测试覆盖：**
- 订单列表功能（查看、搜索、筛选、分页）
- 订单 CRUD 操作（创建、编辑、删除）
- 订单状态流转（激活订单、关闭订单）
- 订单详情查看
- 人员关联功能（添加人员、管理工作状态）
- 附件管理（添加附件）
- 完整流程测试

**可能需要抽象的工具（按需）：**
- 复杂表单提交工具（平台、公司、渠道等多选择器）
- 状态流转测试工具（订单状态变更）
- 资产附件操作工具

**e2e-test-utils 包维护** 🌟 持续演进

- 工具函数测试覆盖率 ≥ 80%
- 完善文档和使用示例
- 按业务需求添加新工具

**MVP 排除的功能（留给后续版本）：**
- VS Code snippets
- CLI 测试生成器
- AI 辅助测试生成
- 跨项目的工具包开源

### Post-MVP Features

**Phase 2 (Post-MVP) - 业务测试扩展：**

**更多业务功能测试：**
- 其他管理功能的 E2E 测试覆盖
- 按业务优先级和风险评估确定测试顺序
- 每个功能的完整测试用例

**工具包按需演进：**
- 在编写新业务测试时，如发现重复模式则抽象新工具
- Date Picker、Slider、Tabs 等（如业务需要）
- 表单验证错误处理模式（如业务需要）

**开发体验增强：**
- VS Code snippets 快速插入
- 测试模板和最佳实践文档
- 更完善的错误提示和调试信息

**质量保障：**
- CI/CD 集成测试报告
- 测试覆盖率趋势追踪
- Flaky 测试检测和报告

### Risk Mitigation Strategy

**技术风险：**
- **风险：** Radix UI DOM 结构变化导致工具函数失效
- **缓解：**
  - 使用稳定的选择器策略（role、data-testid）
  - 设计可扩展的函数签名，支持自定义选择器
  - 工具函数自测，快速发现问题

**业务测试风险：**
- **风险：** 业务功能变更导致测试用例失效
- **缓解：**
  - 测试用例与业务实现解耦
  - 使用 Page Object 模式提高可维护性
  - 定期审查和更新测试用例

**市场/采用风险：**
- **风险：** 团队成员不愿意使用新工具，继续用老方法
- **缓解：**
  - 通过实际业务测试证明价值
  - 渐进式推广：让早期使用者推荐给团队
  - 完善文档：降低学习成本

**资源风险：**
- **风险：** 测试开发时间超出预期
- **缓解：**
  - 按业务优先级排序，先做高价值功能
  - 每个业务功能独立时间盒（1-2 周）
  - 降级方案：优先保证关键路径的测试覆盖

**质量风险：**
- **风险：** 测试不稳定，经常 flaky 失败
- **缓解：**
  - 工具函数编写单元测试
  - 20 次连续运行稳定性验证
  - 代码审查确保质量

### Scope Decision Rationale

**为什么 MVP 范围这样设计：**

1. **业务价值优先**：直接交付业务测试覆盖，确保产品质量

2. **工具自然演进**：不预设工具需求，从实践中抽象

3. **渐进式扩展**：每个业务功能独立 Epic，可并行或串行

4. **可测量成果**：每个 Epic 都有明确的成功标准（覆盖率、稳定性）

5. **风险可控**：范围明确，时间盒限制，有降级方案

**MVP 成功标志：**
- ✅ 残疾人管理 E2E 测试覆盖关键流程 100%
- ✅ 测试连续运行 20 次，100% 通过
- ✅ 从测试中抽象可复用工具
- 🔄 区域管理 E2E 测试覆盖关键流程 100%
- 📋 订单管理 E2E 测试覆盖关键流程 100%

---

## Functional Requirements

### Radix UI Select 组件测试支持

- FR1: 测试开发者可以使用工具函数选择静态枚举型 Radix UI Select 下拉框的选项
- FR2: 测试开发者可以使用工具函数选择异步加载型 Radix UI Select 下拉框的选项
- FR3: 工具函数可以自动处理 Radix UI Select 的 DOM 结构和交互流程
- FR4: 工具函数可以等待异步加载的选项出现在下拉列表中
- FR5: 工具函数可以提供清晰的错误提示，包含标签、期望值等上下文信息
- FR6: 工具函数可以区分"元素未找到"和"超时"错误类型

### 文件上传测试支持

- FR7: 测试开发者可以使用工具函数上传文件到指定的文件输入字段
- FR8: 工具函数可以从 fixtures 目录加载测试文件
- FR9: 工具函数可以支持多文件上传场景
- FR10: 工具函数可以验证文件上传是否成功完成

### 表单交互测试支持

- FR11: 测试开发者可以使用工具函数填写多步骤表单
- FR12: 工具函数可以滚动页面到特定的表单区域
- FR13: 工具函数可以处理表单验证错误场景
- FR14: 测试开发者可以使用工具函数提交表单并等待响应
- FR15: 工具函数可以支持常见的表单字段类型（文本、选择器、日期等）

### 动态列表测试支持

- FR16: 测试开发者可以使用工具函数向动态列表中添加新项
- FR17: 测试开发者可以使用工具函数从动态列表中删除项
- FR18: 工具函数可以支持不同类型的动态列表项（银行卡、备注等）
- FR19: 工具函数可以验证动态列表项添加或删除后的状态
- FR20: 工具函数可以处理动态列表的异步更新场景

### 对话框操作测试支持

- FR21: 测试开发者可以使用工具函数统一操作对话框（确认、取消、关闭）
- FR22: 工具函数可以等待对话框完全关闭后再继续执行
- FR23: 工具函数可以处理对话框内的表单填写和提交
- FR24: 工具函数可以验证对话框是否按预期打开或关闭

### 测试工具包基础设施

- FR25: 测试开发者可以通过 npm workspace 协议安装测试工具包
- FR26: 工具包可以作为 peer dependency 依赖 Playwright，不增加运行时依赖
- FR27: 工具包提供完整的 TypeScript 类型定义和类型提示
- FR28: 工具包的所有导出函数都有完整的 JSDoc 注释
- FR29: 工具包使用严格类型检查，不使用 any 类型
- FR30: 工具包支持目标 ES2020+ 的 JavaScript 环境
- FR31: 工具包的每个工具函数都可以独立导入和使用
- FR32: 工具包可以与其他测试工具和库兼容使用

### 文档和开发者支持

- FR33: 测试开发者可以通过 README 快速了解工具包的用途和安装方法
- FR34: 文档提供每个工具函数的详细使用示例
- FR35: 文档提供静态 Select 和异步 Select 的区别说明
- FR36: 文档提供从现有测试代码迁移到工具函数的指南
- FR37: 文档提供常见问题和解决方案
- FR38: 文档提供残疾人管理测试作为完整的使用示例
- FR39: 测试开发者可以在 30 分钟内使用工具函数编写第一个测试
- FR40: 工具包的使用示例覆盖所有 6 个核心工具函数

### 测试质量和稳定性保障

- FR41: 工具函数使用 Playwright 的 auto-waiting 机制防止时序问题
- FR42: 工具函数为静态选项设置合理的默认超时配置
- FR43: 工具函数为异步选项提供可配置的超时参数
- FR44: 工具函数可以支持重试机制处理不稳定的网络请求
- FR45: 工具函数可以在测试连续运行 20 次时保持 100% 通过率

### 可扩展性和维护性

- FR46: 工具函数支持配置对象参数，允许自定义行为
- FR47: 工具函数设计支持未来的 Radix UI 版本升级
- FR48: 工具函数使用稳定的选择器策略（role、data-testid）
- FR49: 工具包预留扩展接口，支持新增其他 Radix 组件测试模式
- FR50: 工具包的代码结构清晰，便于团队贡献和维护

---

## Non-Functional Requirements

### 可靠性

**测试稳定性（最关键）：**
- NFR1: 工具函数在相同条件下连续运行 20 次，必须保持 100% 通过率，无 flaky 失败
- NFR2: 工具函数能够正确处理异步加载场景，避免时序问题导致的测试失败
- NFR3: 当 DOM 元素暂时不可用时，工具函数提供清晰的错误消息，而不是超时无响应
- NFR4: 工具函数能够区分产品 bug 和测试代码问题，帮助开发者快速定位问题根源

**错误处理和诊断：**
- NFR5: 当选择操作失败时，错误消息包含以下信息：
  - 下拉框标签名称
  - 期望选择的值
  - 实际可用的选项列表
  - 失败原因（元素未找到、超时、选项不存在等）
- NFR6: 当文件上传失败时，错误消息包含文件路径、选择器、失败原因
- NFR7: 错误消息格式统一，便于日志分析和问题定位

### 性能

**测试执行效率：**
- NFR8: 单个 Radix UI Select 选择操作（静态）应在 2 秒内完成
- NFR9: 单个 Radix UI Select 选择操作（异步）应在 5 秒内完成（默认超时）
- NFR10: 工具函数本身的开销不超过 100ms（不包括 Playwright 操作时间）
- NFR11: 使用工具函数的测试比手动编写 DOM 操作的测试执行时间差异 < 10%

**等待策略优化：**
- NFR12: 静态选项使用合理的默认超时（2 秒），避免不必要的等待
- NFR13: 异步选项提供可配置的超时参数，默认值为 5 秒
- NFR14: 工具函数使用 Playwright 的 auto-waiting 机制，减少显式等待的需要

### 集成性

**Playwright 兼容性：**
- NFR15: 工具包兼容 Playwright 最新稳定版本和上一个 LTS 版本
- NFR16: 工具包可以作为 peer dependency 引用，不增加运行时依赖
- NFR17: 工具函数接受标准 Playwright Page 对象作为参数
- NFR18: 工具包不依赖特定版本的 Playwright，使用灵活的版本范围

**测试框架集成：**
- NFR19: 工具函数可以在任何使用 Playwright 的测试框架中运行（Vitest、Jest 等）
- NFR20: 工具包不修改全局配置，不需要额外的测试框架配置
- NFR21: 工具函数可以与现有的 Page Object 模式无缝集成

**Monorepo 集成：**
- NFR22: 工具包通过 pnpm workspace 协议安装，支持本地开发
- NFR23: 工具包的构建产物与项目的 TypeScript 配置兼容
- NFR24: 工具包的类型定义可以自动被 IDE 识别和提示

### 代码质量

**类型安全：**
- NFR25: 工具包使用 TypeScript 严格模式，无 `any` 类型
- NFR26: 所有导出函数都有完整的参数类型和返回值类型
- NFR27: 类型定义支持 IDE 自动补全和类型检查
- NFR28: 类型错误在编译时被捕获，不在运行时暴露

**代码可维护性：**
- NFR29: 工具包的代码覆盖率 ≥ 80%
- NFR30: 每个工具函数都有对应的单元测试
- NFR31: 代码遵循项目的 ESLint 和 Prettier 配置
- NFR32: 函数复杂度保持在低水平（圈复杂度 < 10）

**文档质量：**
- NFR33: 每个导出函数都有完整的 JSDoc 注释
- NFR34: README 包含快速入门、安装说明、基本用法
- NFR35: 每个工具函数至少有 1 个实际使用示例
- NFR36: 文档说明静态 Select 和异步 Select 的区别和使用场景

**开发者体验：**
- NFR37: 新测试开发者可以在 30 分钟内使用工具函数编写第一个测试
- NFR38: 工具函数的命名清晰直观，不需要频繁查看文档
- NFR39: 函数参数设计简洁，必需参数 ≤ 3 个
- NFR40: 错误消息对新手友好，包含问题诊断和建议修复步骤

### 兼容性

**浏览器和环境：**
- NFR41: 工具函数在 Playwright 支持的所有浏览器中正常工作（Chromium、Firefox、WebKit）
- NFR42: 工具函数在 headless 和 headed 模式下都能正常工作
- NFR43: 工具函数在 CI/CD 环境中稳定运行

**版本兼容性：**
- NFR44: 工具包支持 Node.js 当前 LTS 版本和上一个 LTS 版本
- NFR45: 工具包的设计考虑未来 Radix UI 版本升级，使用稳定的选择器策略
- NFR46: 重大版本变更时提供迁移指南
