|
@@ -0,0 +1,423 @@
|
|
|
|
|
+# Story 10.10: 编写订单附件管理测试
|
|
|
|
|
+
|
|
|
|
|
+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. **附件文件格式验证**
|
|
|
|
|
+ - 上传支持的文件格式
|
|
|
|
|
+ - 验证上传成功
|
|
|
|
|
+ - 尝试上传不支持的格式
|
|
|
|
|
+ - 验证错误提示
|
|
|
|
|
+
|
|
|
|
|
+**测试文件:** `web/tests/e2e/specs/admin/order-attachment.spec.ts`
|
|
|
|
|
+
|
|
|
|
|
+## Tasks / Subtasks
|
|
|
|
|
+
|
|
|
|
|
+- [ ] 探索附件上传 UI 结构 (AC: When)
|
|
|
|
|
+ - [ ] 分析订单详情对话框中的附件管理区域
|
|
|
|
|
+ - [ ] 确认添加附件对话框的打开方式
|
|
|
|
|
+ - [ ] 确认人员选择器的交互模式
|
|
|
|
|
+ - [ ] 确认文件上传输入框的选择器
|
|
|
|
|
+- [ ] 验证 Page Object 附件方法 (AC: Given)
|
|
|
|
|
+ - [ ] 验证 `openAddAttachmentDialog()` 方法可用
|
|
|
|
|
+ - [ ] 验证 `uploadAttachment(personName, fileName, mimeType)` 方法可用
|
|
|
|
|
+ - [ ] 验证 `getAttachmentListFromDetail()` 方法可用
|
|
|
|
|
+ - [ ] 补充必要的辅助方法(如需要)
|
|
|
|
|
+- [ ] 创建附件管理测试文件 (AC: When)
|
|
|
|
|
+ - [ ] 创建 `web/tests/e2e/specs/admin/order-attachment.spec.ts`
|
|
|
|
|
+ - [ ] 导入必要的测试依赖和 Page Object
|
|
|
|
|
+ - [ ] 配置测试 Fixtures(adminLoginPage, orderManagementPage, disabilityPersonPage)
|
|
|
|
|
+- [ ] 编写添加附件测试 (AC: Then #1)
|
|
|
|
|
+ - [ ] 测试打开添加附件对话框
|
|
|
|
|
+ - [ ] 测试选择订单人员
|
|
|
|
|
+ - [ ] 测试上传图片文件(JPG 格式)
|
|
|
|
|
+ - [ ] 测试验证附件添加成功(Toast 消息)
|
|
|
|
|
+ - [ ] 测试验证附件出现在订单详情中
|
|
|
|
|
+- [ ] 编写文件格式验证测试 (AC: Then #2)
|
|
|
|
|
+ - [ ] 测试上传 JPG 格式文件
|
|
|
|
|
+ - [ ] 测试上传 PNG 格式文件
|
|
|
|
|
+ - [ ] 测试上传 WEBP 格式文件(如支持)
|
|
|
|
|
+ - [ ] 测试尝试上传不支持的格式(如 .txt、.exe)
|
|
|
|
|
+ - [ ] 测试验证错误提示显示正确
|
|
|
|
|
+- [ ] 确保所有测试通过 (AC: And)
|
|
|
|
|
+ - [ ] 运行测试并修复问题
|
|
|
|
|
+ - [ ] 验证测试稳定性(连续运行 3 次)
|
|
|
|
|
+
|
|
|
|
|
+## 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.8: ✅ 已完成(订单详情查看测试)
|
|
|
|
|
+- Story 10.9: ✅ 已完成(人员关联功能测试 - 提供了选择残疾人的实现)
|
|
|
|
|
+
|
|
|
|
|
+### 前序 Story 关键发现 (Story 10.8 和 10.9)
|
|
|
|
|
+
|
|
|
|
|
+**从 Story 10.8 学到的经验:**
|
|
|
|
|
+
|
|
|
|
|
+1. **订单详情对话框结构**:
|
|
|
|
|
+ - 使用 `openDetailDialog(orderName)` 打开订单详情对话框
|
|
|
|
|
+ - 详情对话框中包含多个 Tab 或区域:基本信息、人员列表、附件列表
|
|
|
|
|
+ - 使用 `closeDetailDialog()` 关闭对话框
|
|
|
|
|
+
|
|
|
|
|
+2. **附件列表获取**:
|
|
|
|
|
+ - `getAttachmentListFromDetail()` 方法已实现(行 752-818)
|
|
|
|
|
+ - 支持表格和列表两种形式
|
|
|
|
|
+ - 返回附件信息:fileName, uploadDate, uploader
|
|
|
|
|
+
|
|
|
|
|
+**从 Story 10.9 学到的经验:**
|
|
|
|
|
+
|
|
|
|
|
+1. **API 直接创建测试数据**:
|
|
|
|
|
+ - 使用 `createDisabledPersonViaAPI()` 创建残疾人数据
|
|
|
|
|
+ - 使用时间戳确保数据唯一性
|
|
|
|
|
+ - 避免依赖 UI 创建流程的超时问题
|
|
|
|
|
+
|
|
|
|
|
+2. **人员管理验证**:
|
|
|
|
|
+ - `getPersonListFromDetail()` 方法已修复(正确选择绑定人员列表表格)
|
|
|
|
|
+ - 使用 `hasText: '工作状态'` 作为筛选条件
|
|
|
|
|
+
|
|
|
|
|
+3. **测试数据隔离**:
|
|
|
|
|
+ - 使用 `testDataCounter` 全局计数器确保唯一性
|
|
|
|
|
+ - 每个测试创建独立的测试数据
|
|
|
|
|
+ - 身份证号格式修正为 18 位标准格式
|
|
|
|
|
+
|
|
|
|
|
+### Page Object 已有功能分析
|
|
|
|
|
+
|
|
|
|
|
+**订单附件管理相关方法** (`web/tests/e2e/pages/admin/order-management.page.ts`):
|
|
|
|
|
+
|
|
|
|
|
+| 方法 | 说明 | 当前状态 | 本 Story 需求 |
|
|
|
|
|
+|------|------|---------|--------------|
|
|
|
|
|
+| `openAddAttachmentDialog()` | 打开添加附件对话框 | 已实现 (行 1032-1036) | 可直接使用 |
|
|
|
|
|
+| `uploadAttachment(personName, fileName, mimeType)` | 上传附件 | 已实现 (行 1044-1067) | **需验证**UI 结构 |
|
|
|
|
|
+| `getAttachmentListFromDetail()` | 获取附件列表 | 已实现 (行 752-818) | 验证附件后检查 |
|
|
|
|
|
+
|
|
|
|
|
+**`openAddAttachmentDialog()` 方法当前实现(行 1032-1036):**
|
|
|
|
|
+
|
|
|
|
|
+```typescript
|
|
|
|
|
+async openAddAttachmentDialog() {
|
|
|
|
|
+ const attachmentButton = this.page.getByRole('button', { name: /添加附件|上传附件/ });
|
|
|
|
|
+ await attachmentButton.click();
|
|
|
|
|
+ await this.page.waitForSelector('[role="dialog"]', { state: 'visible', timeout: TIMEOUTS.DIALOG });
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**`uploadAttachment()` 方法当前实现(行 1044-1067):**
|
|
|
|
|
+
|
|
|
|
|
+```typescript
|
|
|
|
|
+async uploadAttachment(personName: string, fileName: string, mimeType: string = 'image/jpeg') {
|
|
|
|
|
+ // 选择订单人员
|
|
|
|
|
+ const personSelect = this.page.getByLabel(/选择人员|订单人员/);
|
|
|
|
|
+ await personSelect.click();
|
|
|
|
|
+ await this.page.getByRole('option', { name: personName }).click();
|
|
|
|
|
+
|
|
|
|
|
+ // 查找文件上传输入框
|
|
|
|
|
+ const fileInput = this.page.locator('input[type="file"]');
|
|
|
|
|
+ await fileInput.setInputFiles({
|
|
|
|
|
+ name: fileName,
|
|
|
|
|
+ mimeType,
|
|
|
|
|
+ buffer: Buffer.from(`fake ${fileName} content`),
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // 等待上传处理
|
|
|
|
|
+ await this.page.waitForTimeout(TIMEOUTS.MEDIUM);
|
|
|
|
|
+
|
|
|
|
|
+ // 提交
|
|
|
|
|
+ const submitButton = this.page.getByRole('button', { name: /^(上传|确定|保存)$/ });
|
|
|
|
|
+ await submitButton.click();
|
|
|
|
|
+
|
|
|
|
|
+ await this.page.waitForLoadState('networkidle');
|
|
|
|
|
+ await this.page.waitForTimeout(TIMEOUTS.LONG);
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**潜在问题**:
|
|
|
|
|
+- 人员选择假设使用标准 Select(`getByLabel` + `getByRole('option')`)
|
|
|
|
|
+- 文件上传使用 `setInputFiles` 的 buffer 模式(而非 fixtures 文件路径)
|
|
|
|
|
+- 提交按钮名称假设为"上传"|"确定"|"保存"
|
|
|
|
|
+
|
|
|
|
|
+**需要验证的 UI 结构**:
|
|
|
|
|
+1. 添加附件按钮在哪里(订单详情对话框内?人员列表区域?)
|
|
|
|
|
+2. 人员选择是否使用 Radix Select 还是自定义组件
|
|
|
|
|
+3. 文件上传是否使用 `<input type="file">` 标准 HTML 元素
|
|
|
|
|
+4. 附件列表展示的格式(表格 vs 卡片列表)
|
|
|
|
|
+
|
|
|
|
|
+### 测试覆盖场景清单
|
|
|
|
|
+
|
|
|
|
|
+**为订单添加附件:**
|
|
|
|
|
+- [ ] 打开订单详情对话框
|
|
|
|
|
+- [ ] **[关键]** 找到并点击添加附件按钮
|
|
|
|
|
+- [ ] 在添加附件对话框中选择订单人员
|
|
|
|
|
+- [ ] 上传图片文件(JPG 格式)
|
|
|
|
|
+- [ ] 验证上传成功 Toast 消息
|
|
|
|
|
+- [ ] 在订单详情中验证附件显示正确(文件名、上传时间)
|
|
|
|
|
+
|
|
|
|
|
+**附件文件格式验证:**
|
|
|
|
|
+- [ ] 上传 JPG 格式文件 → 验证成功
|
|
|
|
|
+- [ ] 上传 PNG 格式文件 → 验证成功
|
|
|
|
|
+- [ ] 上传 WEBP 格式文件 → 验证成功(如 UI 支持)
|
|
|
|
|
+- [ ] 尝试上传不支持的格式(.txt、.exe)→ 验证错误提示
|
|
|
|
|
+- [ ] 验证文件大小限制(如有)
|
|
|
|
|
+
|
|
|
|
|
+### UI 结构探索要点
|
|
|
|
|
+
|
|
|
|
|
+**附件管理对话框结构假设(需要验证):**
|
|
|
|
|
+
|
|
|
|
|
+1. **添加附件按钮位置**:
|
|
|
|
|
+ - **假设1**: 在订单详情对话框中,有一个独立的"附件"标签页
|
|
|
|
|
+ - **假设2**: 在人员列表中,每个人员行有一个"添加附件"按钮
|
|
|
|
|
+ - **假设3**: 在订单详情对话框底部,有一个"添加附件"按钮
|
|
|
|
|
+
|
|
|
|
|
+2. **添加附件对话框结构**:
|
|
|
|
|
+ - **人员选择器**: 选择要关联附件的订单人员
|
|
|
|
|
+ - 可能是 Radix Select 下拉框
|
|
|
|
|
+ - 可能是搜索 + 选择组合
|
|
|
|
|
+ - **文件上传区域**: 文件上传输入框
|
|
|
|
|
+ - 标准 `<input type="file">` 元素
|
|
|
|
|
+ - 可能有拖放区域
|
|
|
|
|
+ - **提交按钮**: "上传"或"确定"按钮
|
|
|
|
|
+
|
|
|
|
|
+3. **附件列表展示**:
|
|
|
|
|
+ - **表格形式**: 文件名、上传时间、上传者
|
|
|
|
|
+ - **卡片形式**: 每个附件一个卡片
|
|
|
|
|
+ - **位置**: 在订单详情对话框中
|
|
|
|
|
+
|
|
|
|
|
+**测试时优先探索的顺序:**
|
|
|
|
|
+1. 先使用 `openDetailDialog(orderName)` 打开订单详情对话框
|
|
|
|
|
+2. 检查对话框中的附件区域或标签页
|
|
|
|
|
+3. 找到添加附件按钮并点击
|
|
|
|
|
+4. **[关键]** 探索添加附件对话框的 DOM 结构
|
|
|
|
|
+5. 确定人员选择的正确策略(Select vs 其他)
|
|
|
|
|
+6. 定位文件上传输入框
|
|
|
|
|
+7. 定位提交按钮和验证方式
|
|
|
|
|
+
|
|
|
|
|
+**探索策略**:
|
|
|
|
|
+```typescript
|
|
|
|
|
+// 步骤1: 打开订单详情
|
|
|
|
|
+await orderPage.openDetailDialog(orderName);
|
|
|
|
|
+
|
|
|
|
|
+// 步骤2: 查找添加附件按钮
|
|
|
|
|
+const attachmentButton = page.getByRole('button', { name: /添加附件|上传附件/ });
|
|
|
|
|
+// 或
|
|
|
|
|
+const attachmentButton = page.getByTestId('add-attachment-button');
|
|
|
|
|
+
|
|
|
|
|
+// 步骤3: 点击并验证对话框打开
|
|
|
|
|
+await attachmentButton.click();
|
|
|
|
|
+await page.waitForSelector('[role="dialog"]', { state: 'visible' });
|
|
|
|
|
+
|
|
|
|
|
+// 步骤4: 探索对话框结构
|
|
|
|
|
+// - 人员选择器
|
|
|
|
|
+const personSelect = page.getByLabel(/选择人员|订单人员/);
|
|
|
|
|
+// 或 Radix Select
|
|
|
|
|
+await selectRadixOption(page, '订单人员', personName);
|
|
|
|
|
+
|
|
|
|
|
+// - 文件上传输入框
|
|
|
|
|
+const fileInput = page.locator('input[type="file"]');
|
|
|
|
|
+// 使用 fixtures 文件
|
|
|
|
|
+await fileInput.setInputFiles('web/tests/fixtures/images/sample-id-card.jpg');
|
|
|
|
|
+
|
|
|
|
|
+// 步骤5: 提交并验证
|
|
|
|
|
+const submitButton = page.getByRole('button', { name: /^(上传|确定|保存)$/ });
|
|
|
|
|
+await submitButton.click();
|
|
|
|
|
+
|
|
|
|
|
+// 步骤6: 验证附件列表
|
|
|
|
|
+const attachments = await orderPage.getAttachmentListFromDetail();
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 测试数据准备
|
|
|
|
|
+
|
|
|
|
|
+**Fixtures 文件** (位于 `web/tests/fixtures/images/`):
|
|
|
|
|
+- `sample-id-card.jpg` - 身份证照片(JPG 格式)
|
|
|
|
|
+- `sample-disability-card.jpg` - 残疾证照片(JPG 格式)
|
|
|
|
|
+- `id-card-front.jpg` - 身份证正面(JPG 格式)
|
|
|
|
|
+- `id-card-back.jpg` - 身份证反面(JPG 格式)
|
|
|
|
|
+- `disability-card.jpg` - 残疾证照片(JPG 格式)
|
|
|
|
|
+- `photo.jpg` - 个人照片(JPG 格式)
|
|
|
|
|
+- `photo.png` - 个人照片(PNG 格式)
|
|
|
|
|
+- `photo.webp` - 个人照片(WEBP 格式)
|
|
|
|
|
+- `large-file.jpg` - 大文件(用于测试文件大小限制)
|
|
|
|
|
+- `invalid.txt` - 无效格式文件(用于测试格式验证)
|
|
|
|
|
+
|
|
|
|
|
+**测试数据创建流程**:
|
|
|
|
|
+1. 使用 API 创建残疾人数据
|
|
|
|
|
+2. 创建测试订单
|
|
|
|
|
+3. 添加残疾人到订单(使用 Story 10.9 的方法)
|
|
|
|
|
+4. 上传附件到订单人员
|
|
|
|
|
+
|
|
|
|
|
+### 项目结构对齐
|
|
|
|
|
+
|
|
|
|
|
+**遵循 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"`
|
|
|
|
|
+
|
|
|
|
|
+**测试数据隔离:**
|
|
|
|
|
+- 使用 `createDisabledPersonViaAPI()` 创建残疾人数据
|
|
|
|
|
+- 使用 `orderManagementPage.createOrder()` 创建测试订单
|
|
|
|
|
+- 使用 `orderManagementPage.addPersonToOrder()` 添加人员到订单
|
|
|
|
|
+- 测试名称添加时间戳确保唯一性
|
|
|
|
|
+
|
|
|
|
|
+### Project Structure Notes
|
|
|
|
|
+
|
|
|
|
|
+**测试文件位置:**
|
|
|
|
|
+```
|
|
|
|
|
+web/tests/e2e/
|
|
|
|
|
+├── pages/admin/
|
|
|
|
|
+│ └── order-management.page.ts (已有附件方法)
|
|
|
|
|
+└── specs/admin/
|
|
|
|
|
+ └── order-attachment.spec.ts (新建)
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**测试 Fixtures 位置:**
|
|
|
|
|
+```
|
|
|
|
|
+web/tests/fixtures/
|
|
|
|
|
+└── images/
|
|
|
|
|
+ ├── sample-id-card.jpg
|
|
|
|
|
+ ├── sample-disability-card.jpg
|
|
|
|
|
+ ├── photo.jpg
|
|
|
|
|
+ ├── photo.png
|
|
|
|
|
+ ├── photo.webp
|
|
|
|
|
+ └── invalid.txt
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**与其他测试的关系:**
|
|
|
|
|
+- `order-create.spec.ts`: 创建订单测试(提供订单数据源)
|
|
|
|
|
+- `order-person.spec.ts`: 人员关联测试(提供人员数据源)
|
|
|
|
|
+- `order-detail.spec.ts`: 订单详情测试(验证附件列表显示)
|
|
|
|
|
+
|
|
|
|
|
+**本 Story 完成后的影响:**
|
|
|
|
|
+- 完成订单管理的最后一个核心功能测试
|
|
|
|
|
+- 为 Story 10.11(完整流程测试)提供附件上传功能
|
|
|
|
|
+- 为 Epic 10 的稳定性验证做好准备
|
|
|
|
|
+
|
|
|
|
|
+### References
|
|
|
|
|
+
|
|
|
|
|
+**Epic 需求来源:**
|
|
|
|
|
+- [Source: _bmad-output/planning-artifacts/epics.md](../planning-artifacts/epics.md) - Story 10.10 详细需求(行 2181-2205)
|
|
|
|
|
+
|
|
|
|
|
+**Page Object 现有实现:**
|
|
|
|
|
+- [Source: web/tests/e2e/pages/admin/order-management.page.ts](../../web/tests/e2e/pages/admin/order-management.page.ts) - 附件管理方法(行 1027-1067)
|
|
|
|
|
+
|
|
|
|
|
+**前序 Story 学习:**
|
|
|
|
|
+- [Source: _bmad-output/implementation-artifacts/10-8-order-detail-tests.md](10-8-order-detail-tests.md) - 订单详情对话框结构、附件列表获取
|
|
|
|
|
+- [Source: _bmad-output/implementation-artifacts/10-9-order-person-tests.md](10-9-order-person-tests.md) - API 数据创建、测试数据隔离、人员管理验证
|
|
|
|
|
+
|
|
|
|
|
+**项目上下文:**
|
|
|
|
|
+- [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
|
|
|
|
|
+
|
|
|
|
|
+**Story 创建完成 - 2026-01-13**
|
|
|
|
|
+
|
|
|
|
|
+1. **工作流执行**:
|
|
|
|
|
+ - ✅ 读取工作流配置: `create-story/workflow.yaml`
|
|
|
|
|
+ - ✅ 加载 Epic 10 信息: `epics.md` (Story 10.10 行 2181-2205)
|
|
|
|
|
+ - ✅ 加载 Story 10.9 参考: `10-9-order-person-tests.md`
|
|
|
|
|
+ - ✅ 加载项目上下文: `project-context.md`
|
|
|
|
|
+ - ✅ 分析订单管理 Page Object: `order-management.page.ts`
|
|
|
|
|
+
|
|
|
|
|
+2. **验收标准映射**:
|
|
|
|
|
+ - AC #1 "为订单添加附件" → 测试任务: 添加附件测试
|
|
|
|
|
+ - AC #2 "附件文件格式验证" → 测试任务: 文件格式验证测试
|
|
|
|
|
+
|
|
|
|
|
+3. **Page Object 方法验证**:
|
|
|
|
|
+ - ✅ `openAddAttachmentDialog()` - 已实现(行 1032-1036)
|
|
|
|
|
+ - ✅ `uploadAttachment(personName, fileName, mimeType)` - 已实现(行 1044-1067)
|
|
|
|
|
+ - ✅ `getAttachmentListFromDetail()` - 已实现(行 752-818)
|
|
|
|
|
+
|
|
|
|
|
+4. **测试 Fixtures 确认**:
|
|
|
|
|
+ - ✅ 图片文件: JPG, PNG, WEBP 格式可用
|
|
|
|
|
+ - ✅ 测试文件: `sample-id-card.jpg`, `photo.png`, `photo.webp`
|
|
|
|
|
+ - ✅ 无效文件: `invalid.txt` (用于格式验证)
|
|
|
|
|
+
|
|
|
|
|
+5. **依赖关系确认**:
|
|
|
|
|
+ - Story 10.1: ✅ 已完成(订单管理 Page Object)
|
|
|
|
|
+ - Story 10.8: ✅ 已完成(订单详情查看测试)
|
|
|
|
|
+ - Story 10.9: ✅ 已完成(人员关联功能测试)
|
|
|
|
|
+
|
|
|
|
|
+**待完成(开发阶段):**
|
|
|
|
|
+- [ ] 探索附件上传 UI 结构
|
|
|
|
|
+- [ ] 验证 Page Object 方法的 UI 选择器
|
|
|
|
|
+- [ ] 创建测试文件 `order-attachment.spec.ts`
|
|
|
|
|
+- [ ] 编写测试用例(添加附件、文件格式验证)
|
|
|
|
|
+- [ ] 运行测试并修复问题
|
|
|
|
|
+- [ ] 验证测试稳定性
|
|
|
|
|
+
|
|
|
|
|
+### File List
|
|
|
|
|
+
|
|
|
|
|
+**已创建的文件:**
|
|
|
|
|
+- `_bmad-output/implementation-artifacts/10-10-order-attachment-tests.md` - Story 文档
|
|
|
|
|
+
|
|
|
|
|
+**需创建的文件(开发阶段):**
|
|
|
|
|
+- `web/tests/e2e/specs/admin/order-attachment.spec.ts` - 附件管理测试文件
|
|
|
|
|
+
|
|
|
|
|
+**相关参考文件:**
|
|
|
|
|
+- `web/tests/e2e/pages/admin/order-management.page.ts` - 订单管理 Page Object(行 1027-1067: 附件方法)
|
|
|
|
|
+- `_bmad-output/implementation-artifacts/10-8-order-detail-tests.md` - 订单详情测试参考
|
|
|
|
|
+- `_bmad-output/implementation-artifacts/10-9-order-person-tests.md` - 人员关联测试参考
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+**sprint-status.yaml 更新说明:**
|
|
|
|
|
+
|
|
|
|
|
+由于 `sprint-status.yaml` 文件不存在,Story 10-10 的状态无法通过文件更新。
|
|
|
|
|
+建议运行 `bmad:bmm:workflows:sprint-status` 工作流来初始化或更新 sprint status 文件。
|
|
|
|
|
+
|
|
|
|
|
+手动更新指令(如果文件存在):
|
|
|
|
|
+```yaml
|
|
|
|
|
+# 在 sprint-status.yaml 中
|
|
|
|
|
+stories:
|
|
|
|
|
+ 10-10:
|
|
|
|
|
+ status: ready-for-dev # 从 backlog 改为 ready-for-dev
|
|
|
|
|
+```
|