# Story 10.8: 编写订单详情查看测试

Status: done

<!-- 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. **查看订单附件**
   - 在详情中查看附件列表
   - 验证附件显示正确

**测试文件:** `web/tests/e2e/specs/admin/order-detail.spec.ts`

## Tasks / Subtasks

- [x] 补充 Page Object 订单详情方法 (AC: When)
  - [x] 在 `OrderManagementPage` 中添加 `getPersonListFromDetail()` 方法
  - [x] 在 `OrderManagementPage` 中添加 `getAttachmentListFromDetail()` 方法
  - [x] 在 `OrderManagementPage` 中添加 `closeDetailDialog()` 方法
- [x] 创建订单详情测试文件 (AC: When)
  - [x] 创建 `web/tests/e2e/specs/admin/order-detail.spec.ts`
  - [x] 导入必要的测试依赖和 Page Object
- [x] 编写基本订单详情测试 (AC: Then #1)
  - [x] 测试打开订单详情对话框
  - [x] 测试验证订单名称显示正确
  - [x] 测试验证平台、公司、渠道显示正确
  - [x] 测试验证订单状态和工作状态显示正确
  - [x] 测试验证预计开始日期显示正确
- [x] 编写订单人员列表测试 (AC: Then #2)
  - [x] 测试在详情中查看关联人员列表
  - [x] 测试验证人员姓名显示正确
  - [x] 测试验证人员工作状态显示正确
  - [x] 测试验证入职日期显示正确（如有）
- [x] 编写订单附件测试 (AC: Then #3)
  - [x] 测试在详情中查看附件列表
  - [x] 测试验证附件名称显示正确
  - [x] 测试验证附件上传日期显示（如有）
- [x] 确保所有测试通过 (AC: And)

## 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: ✅ 已完成（订单列表查看测试）
- Story 10.3: ✅ 已完成（订单搜索和筛选测试）
- Story 10.4: ✅ 已完成（创建订单测试）
- Story 10.5: ✅ 已完成（编辑订单测试）
- Story 10.6: ✅ 已完成（删除订单测试）
- Story 10.7: ✅ 已完成（订单状态流转测试）

### 前序 Story 情报 (Story 10.7)

**从 Story 10.7 学到的经验:**

1. **状态流转操作模式**：
   - 激活/关闭订单操作都通过"打开菜单"按钮进入
   - 确认对话框使用 `role="alertdialog"` 定位
   - 按钮名称使用正则表达式匹配多种可能性

2. **状态常量使用**：
   - 使用 `ORDER_STATUS` 和 `ORDER_STATUS_LABELS` 常量
   - 使用 `WORK_STATUS` 和 `WORK_STATUS_LABELS` 常量
   - 状态类型使用 `OrderStatus` 和 `WorkStatus` 类型别名

3. **Toast 消息验证**：
   - 使用 `data-sonner-toast` 选择器
   - 区分 `data-type="error"` 和 `data-type="success"`
   - 使用正则表达式匹配关键词而非精确匹配

### Page Object 已有功能

**订单详情相关方法** (`web/tests/e2e/pages/admin/order-management.page.ts`):

| 方法 | 说明 | 详情测试用途 |
|------|------|-------------|
| `openDetailDialog(orderName)` | 打开订单详情对话框 | 打开详情进行查看 |
| `getOrderDetailInfo()` | 获取订单详情中的基本信息 | 验证订单基本信息显示 |
| `openPersonManagementDialog(orderName?)` | 打开人员管理对话框 | 可从详情页打开 |
| `openAddAttachmentDialog()` | 打开添加附件对话框 | 可从详情页打开 |

**已有的订单数据接口:**
```typescript
export interface OrderData {
  name: string;
  expectedStartDate?: string;
  platformId?: number;
  platformName?: string;
  companyId?: number;
  companyName?: string;
  channelId?: number;
  channelName?: string;
  status?: OrderStatus;
  workStatus?: WorkStatus;
}
```

**已有的订单人员数据接口:**
```typescript
export interface OrderPersonData {
  disabledPersonId: number;
  disabledPersonName?: string;
  hireDate?: string;
  salary?: number;
  workStatus?: WorkStatus;
  actualHireDate?: string;
  resignDate?: string;
}
```

### 需要补充的 Page Object 方法

**订单详情查看方法（需要添加）:**

1. **获取人员列表方法:**
   ```typescript
   /**
    * 从订单详情对话框中获取关联人员列表
    * @returns 人员信息列表
    */
   async getPersonListFromDetail(): Promise<Array<{
     name?: string;
     workStatus?: string;
     hireDate?: string;
     salary?: string;
   }>>
   ```

2. **获取附件列表方法:**
   ```typescript
   /**
    * 从订单详情对话框中获取附件列表
    * @returns 附件信息列表
    */
   async getAttachmentListFromDetail(): Promise<Array<{
     fileName?: string;
     uploadDate?: string;
     uploader?: string;
   }>>
   ```

3. **关闭详情对话框方法:**
   ```typescript
   /**
    * 关闭订单详情对话框
    */
   async closeDetailDialog(): Promise<void>
   ```

### 测试覆盖场景清单

**基本订单详情查看:**
- [ ] 打开订单详情对话框
- [ ] 验证订单名称显示正确
- [ ] 验证平台名称显示正确
- [ ] 验证公司名称显示正确
- [ ] 验证渠道名称显示正确
- [ ] 验证订单状态徽章显示正确
- [ ] 验证工作状态徽章显示正确
- [ ] 验证预计开始日期显示正确

**订单人员列表查看:**
- [ ] 在详情中定位人员列表区域
- [ ] 验证人员姓名显示正确
- [ ] 验证人员工作状态显示正确
- [ ] 验证入职日期显示（如有该字段）
- [ ] 验证薪资信息显示（如有该字段）
- [ ] 验证无人员时显示占位文本

**订单附件查看:**
- [ ] 在详情中定位附件列表区域
- [ ] 验证附件文件名显示正确
- [ ] 验证附件上传日期显示（如有该字段）
- [ ] 验证上传者信息显示（如有该字段）
- [ ] 验证无附件时显示占位文本

### UI 结构探索要点

**订单详情对话框结构假设（需要验证）:**

1. **基本信息区域**:
   - 使用标签-值对布局（如: `text-muted-foreground` 标签 + 值）
   - 订单名称、状态、日期等字段
   - 可能使用 Tabs 或分组布局

2. **人员列表区域**:
   - 可能使用表格展示
   - 每行显示人员姓名、工作状态等
   - 可能有"添加人员"按钮

3. **附件列表区域**:
   - 可能使用列表或卡片展示
   - 每项显示文件名、上传信息
   - 可能有"添加附件"按钮

4. **关闭按钮**:
   - 右上角 X 按钮
   - 底部取消/关闭按钮

**测试时优先探索的顺序:**
1. 先使用已有方法 `openDetailDialog()` 打开详情
2. 检查详情对话框的整体结构（Tabs、分组等）
3. 定位基本信息区域的元素选择器
4. 定位人员列表区域的元素选择器
5. 定位附件列表区域的元素选择器
6. 确定关闭详情对话框的方式

### 项目结构对齐

**遵循 Epic 9.6 并行执行决策:**
- ✅ 不使用 `test.describe.serial`
- ✅ 每个测试创建独立的测试数据
- ✅ 使用时间戳确保订单名称唯一

**遵循项目的类型规范:**
- ✅ 使用 TypeScript 严格模式
- ✅ 使用 `ORDER_STATUS` 和 `ORDER_STATUS_LABELS` 常量
- ✅ 使用 `WORK_STATUS` 和 `WORK_STATUS_LABELS` 常量
- ✅ 状态类型使用 `OrderStatus` 和 `WorkStatus` 类型别名

**遵循项目的测试模式:**
- ✅ 使用 Playwright fixtures
- ✅ 使用 Page Object 模式
- ✅ Toast 消息使用 `data-sonner-toast` 选择器
- ✅ 对话框使用 `role="dialog"` 或 `role="alertdialog"`

### Project Structure Notes

**测试文件位置:**
```
web/tests/e2e/
├── pages/admin/
│   └── order-management.page.ts  (需要补充详情查看方法)
└── specs/admin/
    └── order-detail.spec.ts      (新建)
```

**与其他测试的关系:**
- `order-list.spec.ts`: 验证列表中信息显示（详情是更完整的信息）
- `order-create.spec.ts`: 创建测试订单作为详情查看的数据源
- `order-edit.spec.ts`: 编辑后验证详情中的更新
- `order-status.spec.ts`: 状态流转后验证详情中的状态变更
- `order-person.spec.ts` (后续 Story): 人员管理功能
- `order-attachment.spec.ts` (后续 Story): 附件管理功能

**潜在冲突:**
- 订单详情测试可能依赖先创建订单数据
- 建议使用唯一的订单名称前缀：`详情查看测试_${timestamp}`

### References

**Epic 需求来源:**
- [Source: _bmad-output/planning-artifacts/epics.md](epics.md) - Story 10.8 详细需求（行 2111-2138）

**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/project-context.md](project-context.md) - 技术栈、测试规范、类型系统

## Dev Agent Record

### Agent Model Used

claude-opus-4-5-20251101

### Debug Log References

无

### Completion Notes List

**2026-01-13 - 所有测试通过 (13/13):**

1. **Page Object 修复**: 修复了 `getOrderDetailInfo()` 方法的选择器问题：
   - 使用 `data-testid="order-detail-expected-start"` 直接定位预计开始日期元素
   - 修复了工作状态选择器逻辑
   - 添加了订单名称、状态、平台、公司、渠道的 data-testid 定位

2. **日期格式修正**: 更新测试用例中的日期格式期望值：
   - 从 "2025-01-15" 改为 "2025/1/15"（匹配 UI 实际显示格式）
   - 修复了 2 个之前因日期格式不匹配而失败的测试

3. **工作状态值更新**: 添加 "未入职" 到有效工作状态列表：
   - 有效工作状态：['未入职', '未就业', '待就业', '已就业', '已离职']
   - 修复了之前因状态值不匹配而失败的测试

4. **测试结果**: 全部 13 个测试通过
   - 基本订单详情查看（5个测试）✓
   - 订单人员列表查看（4个测试）✓
   - 订单附件查看（2个测试）✓
   - 详情对话框操作（2个测试）✓

5. **TIMEOUTS 常量使用**: 将硬编码的超时值替换为 TIMEOUTS 常量，提高代码可维护性。

### Code Review Follow-ups (AI-Review)

**第一次代码审查 (2026-01-12):**

1. **[HIGH - 已修复]** 测试 skip 语法问题
   - **问题**: 使用 `test.skip(true, ...)` 放在 `test.describe` 内部，语法不正确
   - **修复**: 改为使用 `test.describe.skip()` 正确跳过整个测试块

2. **[HIGH - 已修复]** Story 状态问题
   - **问题**: Story 标记为 "done" 但核心测试被跳过，AC 未完全验证
   - **修复**: 将 Story 状态改为 "in-progress"，等待 Story 10.9 完成后重新启用测试

3. **[HIGH - 已修复]** 缺少跳过原因说明
   - **问题**: 代码中缺少对测试跳过的清晰说明
   - **修复**: 在每个 `test.describe.skip()` 前添加详细注释，说明跳过原因和依赖关系

4. **[HIGH - 待验证]** Page Object 方法选择器假设
   - **问题**: `getPersonListFromDetail()` 和 `getAttachmentListFromDetail()` 使用的选择器可能不匹配实际 UI
   - **状态**: 需要在 Story 10.9 启用测试后验证
   - **位置**: `order-management.page.ts:630-778`

5. **[MEDIUM - 已记录]** waitForTimeout 使用
   - **问题**: 辅助函数 `selectDisabledPersonForOrder` 中多处使用硬编码延迟
   - **状态**: 已记录，该函数是临时实现，Story 10.9 将实现正确的人员关联功能
   - **位置**: `order-detail.spec.ts:28, 41, 108`

6. **[MEDIUM - 已记录]** 测试名称唯一性
   - **问题**: 使用 `Date.now() + random` 可能仍产生重复（同一毫秒内运行）
   - **状态**: 已记录，实际风险较低（测试通常不会在同一毫秒内运行）

### File List

**修改的文件:**
- `web/tests/e2e/pages/admin/order-management.page.ts` - 添加了 `getPersonListFromDetail()`, `getAttachmentListFromDetail()`, `closeDetailDialog()` 三个方法

**新建的文件:**
- `web/tests/e2e/specs/admin/order-detail.spec.ts` - 订单详情查看测试文件（13个测试用例）

**修改的配置文件:**
- `_bmad-output/implementation-artifacts/sprint-status.yaml` - 更新 Story 10.8 状态为 review
