Просмотр исходного кода

docs(e2e): 创建 Story 10.9 - 编写人员关联功能测试

- 创建完整的 Story 文档,包含详细的验收标准和任务分解
- 关键挑战:解决 Story 10.8 中选择残疾人对话框的交互问题
- Page Object 已有 `addPersonToOrder()` 和 `updatePersonWorkStatus()` 方法
- 测试场景:添加人员到订单、管理工作状态、设置实际入职日期、人员离职
- sprint-status.yaml: 10-9-order-person-tests backlog → ready-for-dev

Generated with [Claude Code](https://claude.com/claude-code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
yourname 6 дней назад
Родитель
Сommit
2f618774b1

+ 347 - 0
_bmad-output/implementation-artifacts/10-9-order-person-tests.md

@@ -0,0 +1,347 @@
+# Story 10.9: 编写人员关联功能测试
+
+Status: ready-for-dev
+
+<!-- Note: Validation is optional. Run validate-create-story for quality check before dev-story. -->
+
+## Story
+
+作为测试开发者,
+我想要编写人员关联功能的 E2E 测试,
+以便验证添加人员到订单和管理工作状态的功能。
+
+## Acceptance Criteria
+
+**Given** 订单管理 Page Object 已创建
+**When** 编写人员关联测试用例
+**Then** 包含以下测试场景:
+
+1. **添加人员到订单**
+   - 打开订单人员管理对话框
+   - 选择残疾人
+   - 设置入职日期和薪资
+   - 验证人员添加成功
+   - 验证人员出现在订单详情中
+
+2. **管理工作状态**
+   - 修改人员工作状态(未就业→待就业→已就业)
+   - 验证状态更新正确
+
+3. **设置实际入职日期**
+   - 设置人员的实际入职日期
+   - 验证日期保存正确
+
+4. **人员离职**
+   - 设置人员为已离职状态
+   - 设置离职日期
+   - 验证离职信息保存正确
+
+**测试文件:** `web/tests/e2e/specs/admin/order-person.spec.ts`
+
+## Tasks / Subtasks
+
+- [ ] 补充 Page Object 人员管理方法 (AC: When)
+  - [ ] 验证并修复 `addPersonToOrder()` 方法中的残疾人选择逻辑
+  - [ ] 添加支持选择残疾人对话框的辅助方法(如需要)
+  - [ ] 添加设置实际入职日期的方法
+  - [ ] 添加设置离职日期的方法
+- [ ] 创建人员关联测试文件 (AC: When)
+  - [ ] 创建 `web/tests/e2e/specs/admin/order-person.spec.ts`
+  - [ ] 导入必要的测试依赖和 Page Object
+  - [ ] 配置测试 Fixtures(adminLoginPage, orderManagementPage, disabilityPersonPage)
+- [ ] 编写添加人员到订单测试 (AC: Then #1)
+  - [ ] 测试打开订单人员管理对话框
+  - [ ] 测试选择残疾人(关键:修复选择残疾人对话框的交互)
+  - [ ] 测试设置入职日期和薪资
+  - [ ] 测试验证人员添加成功(Toast 消息 + 详情列表)
+  - [ ] 测试验证人员出现在订单详情中
+- [ ] 编写管理工作状态测试 (AC: Then #2)
+  - [ ] 测试修改人员工作状态(未就业→待就业→已就业)
+  - [ ] 测试验证状态更新正确(从人员列表中验证)
+  - [ ] 测试工作状态流转的正确性
+- [ ] 编写设置实际入职日期测试 (AC: Then #3)
+  - [ ] 测试设置人员的实际入职日期
+  - [ ] 测试验证日期保存正确
+  - [ ] 测试验证日期格式正确(YYYY-MM-DD)
+- [ ] 编写人员离职测试 (AC: Then #4)
+  - [ ] 测试设置人员为已离职状态
+  - [ ] 测试设置离职日期
+  - [ ] 测试验证离职信息保存正确
+  - [ ] 测试验证离职后人员状态显示
+- [ ] 确保所有测试通过 (AC: And)
+  - [ ] 运行测试并修复问题
+  - [ ] 验证测试稳定性(连续运行 3 次)
+  - [ ] 启用 Story 10.8 中被跳过的测试(依赖此 Story 完成)
+
+## Dev Notes
+
+### Epic Context
+
+**Epic 10: 订单管理 E2E 测试 (Epic C - 业务测试 Epic)**
+
+- **目标**: 测试开发者可以为订单管理功能编写完整的 E2E 测试,验证订单的 CRUD、状态流转、人员关联和附件管理功能
+- **业务分组**: Epic C(业务测试 Epic)
+- **背景**: 订单管理是招聘系统的核心业务功能,涉及复杂表单(多选择器联动)、状态流转、人员关联等场景
+- **模式**: 业务测试为主,工具包支持为辅(遵循 Epic A 成功模式)
+
+**依赖:**
+- Epic 1: ✅ 已完成(Select 工具基础框架)
+- Epic 2: ✅ 已完成(Select 工具在真实 E2E 测试中验证)
+- Story 10.1: ✅ 已完成(订单管理 Page Object)
+- Story 10.2 - 10.7: ✅ 已完成(订单列表、筛选、CRUD、状态流转测试)
+- Story 10.8: 🔄 进行中(订单详情查看测试 - 依赖本 Story 完成选择残疾人功能)
+
+### 前序 Story 关键发现 (Story 10.8)
+
+**从 Story 10.8 学到的经验:**
+
+1. **关键阻塞问题 - 选择残疾人功能未实现**:
+   - Story 10.8 中无法在"选择残疾人"对话框中找到已创建的残疾人数据
+   - **原因**: Story 10.9 ("编写人员关联功能测试") 正是处理"选择残疾人"功能的地方
+   - **影响**: Story 10.8 中所有需要创建订单的测试被标记为 `test.skip()`
+   - **解决方案**: 本 Story 需要正确实现选择残疾人对话框的交互
+
+2. **Page Object 已有方法**:
+   - `openPersonManagementDialog(orderName?)`: 打开人员管理对话框
+   - `addPersonToOrder(personData)`: 添加人员到订单(需验证选择残疾人逻辑)
+   - `updatePersonWorkStatus(personName, newStatus)`: 修改人员工作状态
+   - `getPersonListFromDetail()`: 从订单详情对话框中获取关联人员列表(已实现)
+
+3. **测试数据准备**:
+   - Story 10.8 中在 `beforeEach` 创建残疾人测试数据(使用 `disabilityPersonPage`)
+   - 使用时间戳 + 随机数确保数据唯一性(如 `测试残疾人_${timestamp}_${random}`)
+
+4. **遵循 Epic 9.6 并行执行决策**:
+   - 测试不使用 `test.describe.serial`
+   - 每个测试创建独立的测试数据
+   - 测试执行后清理数据(如可能)
+
+### Page Object 已有功能分析
+
+**订单人员管理相关方法** (`web/tests/e2e/pages/admin/order-management.page.ts`):
+
+| 方法 | 说明 | 当前状态 | 本 Story 需求 |
+|------|------|---------|--------------|
+| `openPersonManagementDialog(orderName?)` | 打开人员管理对话框 | 已实现 | 可直接使用 |
+| `addPersonToOrder(personData)` | 添加人员到订单 | 已实现 | **需验证/修复**选择残疾人逻辑 |
+| `updatePersonWorkStatus(personName, newStatus)` | 修改人员工作状态 | 已实现 | 可能需验证 |
+| `getPersonListFromDetail()` | 获取人员列表 | 已实现 | 验证人员添加后检查 |
+
+**`addPersonToOrder()` 方法当前实现(行 844-892):**
+
+```typescript
+async addPersonToOrder(personData: OrderPersonData) {
+  // 点击添加人员按钮
+  const addButton = this.page.getByRole('button', { name: /添加人员|新增人员/ });
+  await addButton.click();
+  await this.page.waitForTimeout(300);
+
+  // 选择残疾人(支持通过名称选择)
+  if (personData.disabledPersonName) {
+    await selectRadixOption(this.page, '残疾人|选择残疾人', personData.disabledPersonName);
+  } else if (personData.disabledPersonId) {
+    // 如果只提供了 ID,尝试在对话框中选择第一个残疾人
+    const firstCheckbox = this.page.locator('[role="dialog"]').locator('table tbody tr').first().locator('input[type="checkbox"]').first();
+    try {
+      await firstCheckbox.waitFor({ state: 'visible', timeout: 3000 });
+      await firstCheckbox.check();
+    } catch {
+      console.debug('没有可用的残疾人数据');
+    }
+  }
+  // ... 填写入职日期、薪资、工作状态等
+}
+```
+
+**潜在问题**:
+- 使用 `selectRadixOption()` 选择残疾人,但"选择残疾人"可能不是标准的 Radix Select 组件
+- 可能是自定义对话框,需要直接点击行或复选框
+- 需要通过实际 UI 探索确定正确的选择模式
+
+**已有的订单人员数据接口**:
+```typescript
+export interface OrderPersonData {
+  disabledPersonId: number;
+  disabledPersonName?: string;
+  hireDate?: string;
+  salary?: number;
+  workStatus?: WorkStatus;
+  actualHireDate?: string;  // 实际入职日期 - 可能需添加
+  resignDate?: string;      // 离职日期 - 可能需添加
+}
+```
+
+### 测试覆盖场景清单
+
+**添加人员到订单:**
+- [ ] 打开订单人员管理对话框
+- [ ] **[关键]** 在"选择残疾人"对话框中找到并选择已创建的残疾人
+- [ ] 填写入职日期
+- [ ] 填写薪资
+- [ ] 选择工作状态(默认未就业)
+- [ ] 提交并验证成功 Toast 消息
+- [ ] 在订单详情中验证人员显示正确
+
+**管理工作状态:**
+- [ ] 修改人员工作状态:未就业 → 待就业
+- [ ] 修改人员工作状态:待就业 → 已就业
+- [ ] 修改人员工作状态:已就业 → 已离职
+- [ ] 验证状态更新后在人员列表中显示正确
+- [ ] 验证状态流转的正确性(不能跳过状态)
+
+**设置实际入职日期:**
+- [ ] 在人员管理中设置实际入职日期
+- [ ] 验证日期保存成功
+- [ ] 验证日期格式正确(YYYY-MM-DD)
+
+**人员离职:**
+- [ ] 设置人员工作状态为已离职
+- [ ] 设置离职日期
+- [ ] 验证离职信息保存成功
+- [ ] 验证离职后状态显示为"已离职"
+
+### UI 结构探索要点
+
+**人员管理对话框结构假设(需要验证):**
+
+1. **打开方式**:
+   - 从订单列表页:点击订单行的"人员"按钮
+   - 从订单详情页:点击"人员管理"或"添加人员"按钮
+
+2. **人员列表区域**:
+   - 可能使用表格展示已关联人员
+   - 每行显示人员姓名、工作状态、入职日期、薪资等
+   - 可能有"添加人员"按钮
+   - 可能有"编辑"、"删除"操作按钮
+
+3. **添加人员对话框**:
+   - **关键组件**: 选择残疾人(可能是对话框或下拉选择器)
+   - 入职日期输入框(日期选择器)
+   - 薪资输入框(数字类型)
+   - 工作状态选择器(下拉选择)
+   - 可能还有实际入职日期、离职日期等字段
+   - 提交/取消按钮
+
+4. **"选择残疾人"对话框结构(关键探索点)**:
+   - **假设1**: 标准 Radix Select 下拉框
+     - 使用 `selectRadixOption()` 直接选择
+   - **假设2**: 自定义对话框
+     - 显示残疾人列表(表格或卡片)
+     - 使用复选框或单选框选择
+     - 需要点击特定行来选择
+   - **假设3**: 搜索 + 选择组合
+     - 有搜索框输入姓名
+     - 有结果列表供选择
+
+**测试时优先探索的顺序:**
+1. 先使用已有方法 `openPersonManagementDialog()` 打开人员管理对话框
+2. 点击"添加人员"按钮
+3. **[关键]** 探索"选择残疾人"组件的 DOM 结构
+4. 确定正确的选择策略(Select vs 对话框 vs 其他)
+5. 定位入职日期、薪资、工作状态等字段
+6. 定位提交按钮和验证方式
+
+**探索策略**:
+```typescript
+// 策略1: 尝试使用 Select
+await selectRadixOption(this.page, '残疾人', personName);
+
+// 策略2: 如果是自定义对话框
+const dialog = this.page.locator('[role="dialog"]');
+const personRow = dialog.locator('table tbody tr').filter({ hasText: personName });
+await personRow.click();
+// 或
+const checkbox = personRow.locator('input[type="checkbox"]');
+await checkbox.check();
+
+// 策略3: 如果是搜索 + 选择
+await searchInput.fill(personName);
+await searchButton.click();
+const resultOption = this.page.getByRole('option', { name: personName });
+await resultOption.click();
+```
+
+### 项目结构对齐
+
+**遵循 Epic 9.6 并行执行决策:**
+- ✅ 不使用 `test.describe.serial`
+- ✅ 每个测试创建独立的测试数据
+- ✅ 使用时间戳确保订单名称和残疾人姓名唯一
+
+**遵循项目的类型规范:**
+- ✅ 使用 TypeScript 严格模式
+- ✅ 使用 `WORK_STATUS` 和 `WORK_STATUS_LABELS` 常量
+- ✅ 工作状态类型使用 `WorkStatus` 类型别名
+
+**遵循项目的测试模式:**
+- ✅ 使用 Playwright fixtures
+- ✅ 使用 Page Object 模式
+- ✅ Toast 消息使用 `data-sonner-toast` 选择器
+- ✅ 对话框使用 `role="dialog"` 或 `role="alertdialog"`
+
+**测试数据隔离:**
+- 使用 `disabilityPersonPage` 创建测试残疾人数据
+- 使用 `orderManagementPage` 创建测试订单
+- 测试名称添加时间戳确保唯一性
+
+### Project Structure Notes
+
+**测试文件位置:**
+```
+web/tests/e2e/
+├── pages/admin/
+│   └── order-management.page.ts  (需验证/修复人员管理方法)
+└── specs/admin/
+    └── order-person.spec.ts      (新建)
+```
+
+**与其他测试的关系:**
+- `order-create.spec.ts`: 创建订单测试(提供订单数据源)
+- `order-detail.spec.ts`: 订单详情测试(依赖本 Story 的选择残疾人功能)
+- `disability-person-complete.spec.ts`: 残疾人管理测试(测试数据来源)
+
+**本 Story 完成后的影响:**
+- 解除 Story 10.8 中被跳过的测试
+- 为 Story 10.10(附件管理)提供人员数据
+- 为 Story 10.11(完整流程测试)提供完整人员管理功能
+
+### References
+
+**Epic 需求来源:**
+- [Source: _bmad-output/planning-artifacts/epics.md](../planning-artifacts/epics.md) - Story 10.9 详细需求(行 2143-2178)
+
+**Page Object 现有实现:**
+- [Source: web/tests/e2e/pages/admin/order-management.page.ts](../../web/tests/e2e/pages/admin/order-management.page.ts) - 人员管理方法、人员数据接口
+
+**前序 Story 学习:**
+- [Source: _bmad-output/implementation-artifacts/10-7-order-status-tests.md](10-7-order-status-tests.md) - 状态流转操作模式、常量使用
+- [Source: _bmad-output/implementation-artifacts/10-8-order-detail-tests.md](10-8-order-detail-tests.md) - 选择残疾人阻塞问题、Page Object 已有方法
+
+**项目上下文:**
+- [Source: _bmad-output/project-context.md](../project-context.md) - 技术栈、测试规范、类型系统
+
+**Epic 9 并行执行决策:**
+- [Source: _bmad-output/implementation-artifacts/epic-9-retrospective-2026-01-12.md](epic-9-retrospective-2026-01-12.md) - 测试隔离和并行执行最佳实践
+
+## Dev Agent Record
+
+### Agent Model Used
+
+claude-opus-4-5-20251101
+
+### Debug Log References
+
+无
+
+### Completion Notes List
+
+待实现
+
+### File List
+
+**预计修改的文件:**
+- `web/tests/e2e/pages/admin/order-management.page.ts` - 可能需要验证/修复人员管理方法
+
+**预计新建的文件:**
+- `web/tests/e2e/specs/admin/order-person.spec.ts` - 人员关联功能测试文件
+

+ 2 - 2
_bmad-output/implementation-artifacts/sprint-status.yaml

@@ -117,7 +117,7 @@ development_status:
   8-4-edit-region-test: done             # 编写编辑区域测试(10个测试通过,2个跳过:子区域编辑需要修复createChildRegion功能)
   8-5-delete-region-test: done              # 编写删除区域测试(15个测试全部通过,代码审查完成,所有HIGH和MEDIUM问题已修复)
   8-6-cascade-select-test: done          # 编写级联选择完整流程测试 (代码审查完成,所有HIGH和MEDIUM问题已修复)
-  8-7-run-tests-collect-issues: review  # 运行测试并收集问题和改进建议 - HIGH问题已修复(refreshTree + expandNode优化),待验证
+  8-7-run-tests-collect-issues: done     # 运行测试并收集问题和改进建议 - 代码审查完成,所有CRITICAL和MEDIUM问题已修复
   8-8-extend-utils-if-needed: backlog    # 扩展工具包(如需要)
   8-9-region-stability-test: backlog     # 区域管理稳定性验证
   epic-8-retrospective: optional
@@ -154,7 +154,7 @@ development_status:
   10-6-order-delete-tests: done         # 编写删除订单测试 - 代码审查完成,所有HIGH和MEDIUM问题已修复
   10-7-order-status-tests: done                # 编写订单状态流转测试 - 代码审查完成,所有HIGH和MEDIUM问题已修复
   10-8-order-detail-tests: in-progress           # 编写订单详情查看测试 - 代码审查完成,HIGH问题已修复,等待Story 10.9实现选择残疾人功能后验证测试
-  10-9-order-person-tests: backlog         # 编写人员关联功能测试
+  10-9-order-person-tests: ready-for-dev   # 编写人员关联功能测试
   10-10-order-attachment-tests: backlog    # 编写附件管理测试
   10-11-order-complete-tests: backlog      # 编写订单完整流程测试
   10-12-run-tests-collect-issues: backlog  # 运行测试并收集问题和改进建议