Parcourir la source

docs(e2e): 创建 Story 10.6 - 删除订单测试

创建订单删除 E2E 测试的 story 文档,包含:
- 删除草稿状态订单测试场景
- 删除有关联人员的订单测试场景
- 取消删除测试场景
- Page Object 删除方法使用指南
- 前序 story 经验总结(10.2-10.5)

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

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
yourname il y a 1 semaine
Parent
commit
a757ebacef
1 fichiers modifiés avec 440 ajouts et 0 suppressions
  1. 440 0
      _bmad-output/implementation-artifacts/10-6-order-delete-tests.md

+ 440 - 0
_bmad-output/implementation-artifacts/10-6-order-delete-tests.md

@@ -0,0 +1,440 @@
+# Story 10.6: 编写删除订单测试
+
+Status: ready-for-dev
+
+<!-- Note: Validation is optional. Run validate-create-story for quality check before dev-story. -->
+
+## Story
+
+作为测试开发者,
+我想要编写删除订单的 E2E 测试,
+以便验证订单删除功能和相关约束。
+
+## Acceptance Criteria
+
+**Given** 编辑订单测试已通过
+**When** 编写删除订单测试用例
+**Then** 包含以下测试场景:
+
+1. **删除草稿状态订单**
+   - 删除草稿状态的订单
+   - 验证删除确认对话框显示
+   - 确认删除
+   - 验证删除成功后列表中不再显示
+
+2. **删除有关联人员的订单**
+   - 尝试删除已关联人员的订单
+   - 验证错误提示或级联删除行为
+   - 根据实际业务逻辑验证结果
+
+3. **取消删除**
+   - 点击删除按钮
+   - 在确认对话框中点击取消
+   - 验证订单未被删除
+
+**测试文件:** `web/tests/e2e/specs/admin/order-delete.spec.ts`
+
+## Tasks / Subtasks
+
+- [ ] 创建删除订单测试文件 (AC: When)
+  - [ ] 创建 `web/tests/e2e/specs/admin/order-delete.spec.ts`
+  - [ ] 导入必要的测试依赖(Playwright fixtures、OrderManagementPage)
+  - [ ] 配置测试文件的基本结构
+- [ ] 编写删除草稿订单测试 (AC: Then #1)
+  - [ ] 创建草稿状态的测试订单
+  - [ ] 测试打开删除确认对话框
+  - [ ] 测试确认删除操作
+  - [ ] 验证删除后订单不再存在于列表中
+  - [ ] 验证 Toast 成功消息显示
+- [ ] 编写删除有关联人员订单测试 (AC: Then #2)
+  - [ ] 创建订单并添加人员
+  - [ ] 测试删除有关联人员的订单
+  - [ ] 验证错误提示或级联删除行为
+  - [ ] 根据实际业务逻辑断言结果
+- [ ] 编写取消删除测试 (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 情报 (Story 10.1-10.5)
+
+**Page Object 已有的删除功能:**
+
+`web/tests/e2e/pages/admin/order-management.page.ts` 包含以下删除相关方法:
+
+1. **打开删除确认对话框:**
+   ```typescript
+   async openDeleteDialog(orderName: string): Promise<void>
+   ```
+   - 找到订单行并点击删除按钮
+   - 等待确认对话框出现(`role="alertdialog"`)
+
+2. **确认删除:**
+   ```typescript
+   async confirmDelete(): Promise<void>
+   ```
+   - 点击"确认删除"按钮
+   - 等待对话框关闭和网络请求完成
+
+3. **取消删除:**
+   ```typescript
+   async cancelDelete(): Promise<void>
+   ```
+   - 点击删除确认对话框中的"取消"按钮
+   - 等待对话框关闭
+
+4. **删除订单完整流程:**
+   ```typescript
+   async deleteOrder(orderName: string): Promise<boolean>
+   ```
+   - 组合方法:打开对话框 → 确认删除 → 检查 Toast 消息
+   - 返回是否成功删除(基于 Toast 消息)
+
+5. **验证订单存在:**
+   ```typescript
+   async orderExists(orderName: string): Promise<boolean>
+   ```
+   - 检查订单是否存在于列表中
+
+6. **创建订单:**
+   ```typescript
+   async createOrder(data: OrderData): Promise<FormSubmitResult>
+   ```
+   - 用于创建测试数据
+
+### 测试数据策略
+
+**创建测试订单:**
+删除测试需要先有可删除的订单。参考 Story 10.3、10.4、10.5 的测试数据策略:
+
+```typescript
+// 使用时间戳创建唯一订单名称
+const timestamp = Date.now();
+const testOrderName = `删除测试订单_${timestamp}`;
+
+// 先创建订单
+await orderManagementPage.createOrder({
+  name: testOrderName,
+  expectedStartDate: '2025-01-15',
+});
+```
+
+**创建有关联人员的订单(测试场景 2):**
+```typescript
+// 创建订单并添加人员
+await orderManagementPage.createOrder({
+  name: testOrderName,
+  expectedStartDate: '2025-01-15',
+});
+
+// 打开人员管理对话框
+await orderManagementPage.openPersonManagementDialog(testOrderName);
+
+// 添加人员
+await orderManagementPage.addPersonToOrder({
+  disabledPersonName: '测试人员',
+  hireDate: '2025-01-20',
+  salary: 5000,
+});
+```
+
+### 测试文件结构参考
+
+参考 Story 10.4(创建订单测试)和 Story 10.5(编辑订单测试)的测试结构:
+
+```typescript
+import { test, expect } from '../../utils/test-setup';
+import { OrderManagementPage } from '../../pages/admin/order-management.page';
+import { ORDER_STATUS } from '../../pages/admin/order-management.page';
+
+test.describe.serial('删除订单测试', () => {
+  let testOrderName: string;
+
+  test.beforeEach(async ({ adminLoginPage, orderManagementPage }) => {
+    await adminLoginPage.goto();
+    await adminLoginPage.login('admin', 'admin123');
+    await orderManagementPage.goto();
+
+    // 创建测试订单
+    const timestamp = Date.now();
+    testOrderName = `删除测试_${timestamp}`;
+    await orderManagementPage.createOrder({
+      name: testOrderName,
+      expectedStartDate: '2025-01-15',
+    });
+  });
+
+  test.describe('删除草稿状态订单', () => {
+    test('应该成功删除草稿订单', async ({ orderManagementPage }) => {
+      // 打开删除确认对话框
+      await orderManagementPage.openDeleteDialog(testOrderName);
+
+      // 确认删除
+      await orderManagementPage.confirmDelete();
+
+      // 验证订单不再存在
+      expect(await orderManagementPage.orderExists(testOrderName)).toBe(false);
+    });
+
+    test('应该在删除后显示成功提示', async ({ orderManagementPage }) => {
+      await orderManagementPage.deleteOrder(testOrderName);
+
+      // 验证 Toast 成功消息
+      const successToast = orderManagementPage.page.locator('[data-sonner-toast][data-type="success"]');
+      await expect(successToast).toBeVisible();
+    });
+  });
+
+  test.describe('取消删除', () => {
+    test('应该能在确认对话框中取消删除', async ({ orderManagementPage }) => {
+      // 打开删除确认对话框
+      await orderManagementPage.openDeleteDialog(testOrderName);
+
+      // 取消删除
+      await orderManagementPage.cancelDelete();
+
+      // 验证订单仍然存在
+      expect(await orderManagementPage.orderExists(testOrderName)).toBe(true);
+    });
+  });
+});
+```
+
+### 技术要求
+
+**导入依赖:**
+```typescript
+import { test, expect } from '../../utils/test-setup';
+import { OrderManagementPage, ORDER_STATUS } from '../../pages/admin/order-management.page';
+```
+
+**测试 Fixtures:**
+- 使用 `adminLoginPage` fixture 进行登录
+- 使用 `orderManagementPage` fixture 操作页面
+- 使用 `test.describe.serial()` 确保测试按顺序执行
+
+**断言策略:**
+- 验证删除确认对话框正确显示
+- 验证删除后订单不再存在于列表中
+- 验证 Toast 成功/错误消息显示
+- 对于有关联人员的订单,根据实际业务逻辑验证结果
+
+### 业务逻辑说明
+
+**删除订单的业务规则(需要验证):**
+
+1. **草稿状态订单**:
+   - 应该可以直接删除
+   - 删除后订单从列表中移除
+   - 显示成功提示消息
+
+2. **有关联人员的订单**:
+   - **场景 A - 禁止删除**: 显示错误提示,不允许删除
+   - **场景 B - 级联删除**: 删除订单及其关联的人员数据
+   - **需要根据实际业务逻辑实现对应测试**
+
+3. **删除确认对话框**:
+   - 使用 `role="alertdialog"` 定位
+   - 包含"确认删除"和"取消"按钮
+   - 点击取消后订单保持不变
+
+### 测试标准参考
+
+遵循以下测试标准文档:
+- `docs/standards/testing-standards.md` - 测试规范
+- `docs/standards/web-ui-testing-standards.md` - Web UI 测试规范
+- `docs/standards/e2e-radix-testing.md` - Radix UI E2E 测试标准
+
+**选择器优先级:**
+1. `data-testid` - 最高优先级
+2. `aria-label + role`
+3. `text content + role` - 兜底
+
+### Project Structure Notes
+
+**文件位置:**
+- 测试文件: `web/tests/e2e/specs/admin/order-delete.spec.ts`
+- Page Object: `web/tests/e2e/pages/admin/order-management.page.ts`
+- Fixtures 目录: `web/tests/e2e/fixtures/`
+
+**对齐统一项目结构:**
+- 遵循 `project-context.md` 中的 TypeScript 严格模式规则
+- 函数参数、返回值必须有明确类型注解
+- 禁止使用 `any` 类型
+- 公共 API 必须包含完整 JSDoc 注释
+
+### 测试运行命令
+
+```bash
+# 在 web 目录下运行单个测试文件
+cd web
+pnpm test:e2e:chromium order-delete
+
+# 快速失败模式(推荐调试时使用)
+timeout 60 pnpm test:e2e:chromium order-delete
+```
+
+### 测试注意事项
+
+**删除确认对话框交互:**
+- 删除按钮可能通过操作菜单访问(参考 Story 10.5 经验)
+- 需要先点击"打开菜单"按钮,再点击"删除"选项
+- 确认对话框使用 `role="alertdialog"` 定位
+
+**测试数据清理:**
+- 删除测试会实际删除数据
+- 每个测试应创建独立的测试订单
+- 使用时间戳确保订单名称唯一
+
+**断言策略:**
+- 验证 `confirmDelete()` 后列表中订单消失
+- 验证 `cancelDelete()` 后订单仍然存在
+- 验证 Toast 成功消息显示(用于删除操作)
+- 验证 Toast 错误消息显示(用于删除失败场景)
+
+**有关联人员订单的测试:**
+- 需要先创建订单并添加人员
+- 根据实际业务逻辑:
+  - 如果禁止删除:验证错误消息显示
+  - 如果允许删除:验证级联删除成功
+- 可能需要先查看后端 API 或 UI 行为确定业务规则
+
+### 测试覆盖场景清单
+
+**删除草稿状态订单:**
+- [ ] 打开删除确认对话框
+- [ ] 确认删除操作
+- [ ] 验证删除后列表中不再显示该订单
+- [ ] 验证 Toast 成功消息显示
+
+**删除有关联人员的订单:**
+- [ ] 创建订单并添加人员
+- [ ] 尝试删除有关联人员的订单
+- [ ] 验证错误提示或级联删除行为(根据实际业务逻辑)
+
+**取消删除:**
+- [ ] 打开删除确认对话框
+- [ ] 点击取消按钮
+- [ ] 验证订单仍然存在于列表中
+
+**边界条件测试(可选):**
+- [ ] 删除不存在的订单
+- [ ] 删除已完成状态的订单
+- [ ] 并发删除同一订单
+
+### 前序 Story 经验总结 (Story 10.2, 10.3, 10.4, 10.5)
+
+**从 Story 10.2(订单列表测试)学到的经验:**
+- 列表表格使用 `table tbody tr` 选择器定位行
+- 订单状态徽章使用 `getByText` 精确匹配
+- 工作状态徽章使用 `getByText` 精确匹配
+
+**从 Story 10.3(订单筛选测试)学到的经验:**
+- 对标签使用 `locator('label').filter({ hasText: ... })` 避免与表头冲突
+- 对操作添加 `waitForLoadState` 超时处理(可能不触发网络请求)
+- 使用 `selectRadixOption` 工具选择下拉选项
+- 日期处理使用本地时间格式
+
+**从 Story 10.4(创建订单测试)学到的经验:**
+- 使用 `createOrder()` 方法创建测试数据
+- 测试数据使用时间戳确保唯一性
+- 验证 Toast 消息确认操作结果
+
+**从 Story 10.5(编辑订单测试)学到的关键经验:**
+
+1. **订单操作菜单问题**: 编辑按钮不是直接在表格中,而是需要先点击"打开菜单"按钮才能看到编辑选项。删除操作可能也是类似的模式。
+
+2. **删除按钮位置**: 检查删除按钮是否也在操作菜单中,如果是,需要:
+   ```typescript
+   // 找到订单行并点击"打开菜单"按钮
+   const orderRow = this.orderTable.locator('tbody tr').filter({ hasText: orderName });
+   const menuButton = orderRow.getByRole('button', { name: '打开菜单' });
+   await menuButton.click();
+
+   // 等待菜单出现并点击"删除"选项
+   const deleteOption = this.page.getByRole('menuitem', { name: '删除' });
+   await deleteOption.click();
+   ```
+
+3. **网络等待超时问题**: `waitForLoadState('networkidle')` 可能超时,使用 try-catch 包裹处理。
+
+4. **测试数据管理**: 每个测试创建独立的测试订单,避免数据冲突。
+
+### 关键代码模式
+
+**订单数据接口:**
+```typescript
+interface OrderData {
+  name: string;
+  expectedStartDate?: string;
+  platformId?: number;
+  platformName?: string;
+  companyId?: number;
+  companyName?: string;
+  channelId?: number;
+  channelName?: string;
+  status?: OrderStatus;
+  workStatus?: WorkStatus;
+}
+```
+
+**订单人员数据接口:**
+```typescript
+interface OrderPersonData {
+  disabledPersonId: number;
+  disabledPersonName?: string;
+  hireDate?: string;
+  salary?: number;
+  workStatus?: WorkStatus;
+  actualHireDate?: string;
+  resignDate?: string;
+}
+```
+
+### References
+
+- [Source: _bmad-output/planning-artifacts/epics.md#Story 10.6](../planning-artifacts/epics.md)
+- [Source: _bmad-output/planning-artifacts/prd.md](../planning-artifacts/prd.md)
+- [Source: _bmad-output/planning-artifacts/architecture.md](../planning-artifacts/architecture.md)
+- [Source: web/tests/e2e/pages/admin/order-management.page.ts](../../web/tests/e2e/pages/admin/order-management.page.ts)
+- [Source: _bmad-output/implementation-artifacts/10-1-order-page-object.md](10-1-order-page-object.md)
+- [Source: _bmad-output/implementation-artifacts/10-2-order-list-tests.md](10-2-order-list-tests.md)
+- [Source: _bmad-output/implementation-artifacts/10-3-order-filter-tests.md](10-3-order-filter-tests.md)
+- [Source: _bmad-output/implementation-artifacts/10-4-order-create-tests.md](10-4-order-create-tests.md)
+- [Source: _bmad-output/implementation-artifacts/10-5-order-edit-tests.md](10-5-order-edit-tests.md)
+
+## Dev Agent Record
+
+### Agent Model Used
+
+claude-opus-4-5-20251101
+
+### Debug Log References
+
+### Completion Notes List
+
+### File List
+
+---