# Story 10.7: 编写订单状态流转测试 Status: ready-for-dev ## Story 作为测试开发者, 我想要编写订单状态流转的 E2E 测试, 以便验证激活和关闭订单的功能。 ## Acceptance Criteria **Given** 订单 CRUD 测试已通过 **When** 编写订单状态流转测试用例 **Then** 包含以下测试场景: 1. **激活草稿订单** - 创建草稿状态订单 - 点击激活订单按钮 - 验证确认对话框显示 - 确认激活 - 验证订单状态变为进行中 2. **关闭进行中订单** - 激活订单后 - 点击关闭订单按钮 - 验证确认对话框显示 - 确认关闭 - 验证订单状态变为已完成 3. **状态限制验证** - 尝试激活非草稿状态的订单 - 验证按钮禁用或操作被阻止 - 尝试关闭非进行中状态的订单 - 验证操作限制正确 **测试文件:** `web/tests/e2e/specs/admin/order-status.spec.ts` ## Tasks / Subtasks - [ ] 补充 Page Object 状态流转方法 (AC: When) - [ ] 在 `OrderManagementPage` 中添加 `activateOrder()` 方法 - [ ] 在 `OrderManagementPage` 中添加 `closeOrder()` 方法 - [ ] 在 `OrderManagementPage` 中添加 `getOrderStatus()` 方法 - [ ] 添加验证状态按钮状态的方法 - [ ] 创建状态流转测试文件 (AC: When) - [ ] 创建 `web/tests/e2e/specs/admin/order-status.spec.ts` - [ ] 导入必要的测试依赖和 Page Object - [ ] 编写激活草稿订单测试 (AC: Then #1) - [ ] 测试创建草稿订单 - [ ] 测试打开激活确认对话框 - [ ] 测试确认激活操作 - [ ] 验证订单状态从草稿变为进行中 - [ ] 验证 Toast 成功消息显示 - [ ] 编写关闭进行中订单测试 (AC: Then #2) - [ ] 测试创建并激活订单(准备进行中状态) - [ ] 测试打开关闭确认对话框 - [ ] 测试确认关闭操作 - [ ] 验证订单状态从进行中变为已完成 - [ ] 验证 Toast 成功消息显示 - [ ] 编写状态限制验证测试 (AC: Then #3) - [ ] 测试不能激活已确认/进行中/已完成状态的订单 - [ ] 测试不能关闭草稿/已确认/已完成状态的订单 - [ ] 验证按钮禁用状态 - [ ] 确保所有测试通过 (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 情报 (Story 10.6) **从 Story 10.6 学到的经验:** 1. **Page Object 菜单操作模式**: - 编辑和删除操作都通过"打开菜单"按钮进入 - 状态流转按钮可能也在菜单中,或者在行操作按钮区域 - 需要先探索实际 UI 结构来确定按钮位置 2. **灵活的选择器策略**: - 使用正则表达式匹配多种可能的按钮名称 - 示例:`/^(确认删除|删除|确定|确认)$/` 匹配确认按钮 3. **测试隔离优化**: - 每个测试套件创建独立的测试订单 - 避免测试之间的状态干扰 - 使用时间戳确保订单名称唯一 4. **Toast 消息验证**: - 使用正则表达式匹配关键词而非精确匹配 - 示例:`/删除/` 匹配删除相关的成功消息 ### Page Object 已有功能 **订单状态常量定义** (`web/tests/e2e/pages/admin/order-management.page.ts`): ```typescript // 订单状态常量 export const ORDER_STATUS = { DRAFT: 'draft', CONFIRMED: 'confirmed', IN_PROGRESS: 'in_progress', COMPLETED: 'completed', } as const; export type OrderStatus = typeof ORDER_STATUS[keyof typeof ORDER_STATUS]; // 订单状态显示名称映射 export const ORDER_STATUS_LABELS: Record = { draft: '草稿', confirmed: '已确认', in_progress: '进行中', completed: '已完成', } as const; ``` **已有的相关方法:** | 方法 | 说明 | 状态流转测试用途 | |------|------|-----------------| | `createOrder(data)` | 创建订单 | 创建草稿订单作为测试起点 | | `editOrder(orderName, data)` | 编辑订单 | 可通过 `status` 字段修改状态(但不是真实的状态流转操作) | | `openDetailDialog(orderName)` | 打开订单详情 | 验证详情中的状态显示 | | `getOrderDetailInfo()` | 获取订单详情 | 获取当前订单状态信息 | | `openEditDialog(orderName)` | 打开编辑菜单 | 参考菜单操作模式 | ### 需要补充的 Page Object 方法 **状态流转操作方法(需要添加):** 1. **激活订单方法:** ```typescript /** * 打开激活订单确认对话框 * @param orderName 订单名称 */ async openActivateDialog(orderName: string): Promise /** * 确认激活订单 */ async confirmActivate(): Promise /** * 激活订单(完整流程) * @param orderName 订单名称 * @returns 是否成功激活 */ async activateOrder(orderName: string): Promise ``` 2. **关闭订单方法:** ```typescript /** * 打开关闭订单确认对话框 * @param orderName 订单名称 */ async openCloseDialog(orderName: string): Promise /** * 确认关闭订单 */ async confirmClose(): Promise /** * 关闭订单(完整流程) * @param orderName 订单名称 * @returns 是否成功关闭 */ async closeOrder(orderName: string): Promise ``` 3. **状态获取方法:** ```typescript /** * 获取订单的当前状态(从列表页面) * @param orderName 订单名称 * @returns 订单状态值 */ async getOrderStatus(orderName: string): Promise /** * 验证订单状态 * @param orderName 订单名称 * @param expectedStatus 期望的状态 */ async expectOrderStatus(orderName: string, expectedStatus: OrderStatus): Promise ``` 4. **按钮状态验证方法:** ```typescript /** * 检查激活按钮是否可用 * @param orderName 订单名称 * @returns 按钮是否可用 */ async isActivateButtonEnabled(orderName: string): Promise /** * 检查关闭按钮是否可用 * @param orderName 订单名称 * @returns 按钮是否可用 */ async isCloseButtonEnabled(orderName: string): Promise ``` ### 测试覆盖场景清单 **激活草稿订单:** - [ ] 创建草稿状态订单 - [ ] 打开激活确认对话框 - [ ] 确认激活操作 - [ ] 验证订单状态从草稿变为进行中 - [ ] 验证 Toast 成功消息显示 **关闭进行中订单:** - [ ] 创建并激活订单(准备进行中状态) - [ ] 打开关闭确认对话框 - [ ] 确认关闭操作 - [ ] 验证订单状态从进行中变为已完成 - [ ] 验证 Toast 成功消息显示 **状态限制验证:** - [ ] 尝试激活已确认状态的订单 → 按钮禁用或操作失败 - [ ] 尝试激活进行中状态的订单 → 按钮禁用或操作失败 - [ ] 尝试激活已完成状态的订单 → 按钮禁用或操作失败 - [ ] 尝试关闭草稿状态的订单 → 按钮禁用或操作失败 - [ ] 尝试关闭已确认状态的订单 → 按钮禁用或操作失败 - [ ] 尝试关闭已完成状态的订单 → 按钮禁用或操作失败 **状态流转图参考:** ``` 草稿 (draft) --[激活]--> 进行中 (in_progress) --[关闭]--> 已完成 (completed) ↑ [确认] (从草稿) ``` ### UI 结构探索要点 **状态流转按钮位置假设(需要验证):** 1. **在操作菜单中**(与编辑/删除类似): - 点击"打开菜单"按钮 - 菜单中可能包含"激活"、"关闭"等选项 2. **作为行操作按钮**: - 直接在订单行显示激活/关闭按钮 - 按钮可能根据订单状态显示/隐藏 3. **在详情页面中**: - 打开订单详情后显示状态操作按钮 **测试时优先探索的顺序:** 1. 先检查操作菜单中是否有状态流转选项 2. 检查行中是否有独立的激活/关闭按钮 3. 检查详情页面中的状态操作按钮 ### 项目结构对齐 **遵循 Epic 9.6 并行执行决策:** - ✅ 不使用 `test.describe.serial` - ✅ 每个测试创建独立的测试数据 - ✅ 使用时间戳确保订单名称唯一 **遵循项目的类型规范:** - ✅ 使用 TypeScript 严格模式 - ✅ 使用 `ORDER_STATUS` 和 `ORDER_STATUS_LABELS` 常量 - ✅ 状态类型使用 `OrderStatus` 类型别名 **遵循项目的测试模式:** - ✅ 使用 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-status.spec.ts (新建) ``` **与其他测试的关系:** - `order-list.spec.ts`: 验证列表中状态徽章显示 - `order-create.spec.ts`: 创建草稿订单(测试起点) - `order-edit.spec.ts`: 编辑订单(可能涉及状态修改) - `order-delete.spec.ts`: 删除订单(参考菜单操作模式) **潜在冲突:** - 状态流转测试可能创建多种状态的订单,需要确保数据隔离 - 建议使用唯一的订单名称前缀:`状态流转测试_${timestamp}` ### References **Epic 需求来源:** - [Source: _bmad-output/planning-artifacts/epics.md](epics.md) - Story 10.7 详细需求 **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-6-order-delete-tests.md](10-6-order-delete-tests.md) - 菜单操作模式、灵活选择器、测试隔离 **项目上下文:** - [Source: _bmad-output/project-context.md](project-context.md) - 技术栈、测试规范、类型系统 ## Dev Agent Record ### Agent Model Used 待开发 agent 填写 ### Debug Log References 待开发 agent 填写 ### Completion Notes List 待开发 agent 填写 ### File List 待开发 agent 填写 ---