10-1-order-page-object.md 11 KB

Story 10.1: 创建订单管理 Page Object

Status: ready-for-dev

Story

作为测试开发者, 我想要创建订单管理的 Page Object, 以便组织订单管理相关的页面元素和操作。

Acceptance Criteria

Given Epic 9 的 Page Object 模式已验证 When 创建 web/tests/e2e/pages/admin/order-management.page.ts Then 定义订单列表页面的选择器和操作方法 And 定义创建订单表单的选择器和操作方法 And 定义编辑订单表单的选择器和操作方法 And 定义订单详情对话框的选择器和操作方法 And 定义人员关联相关的选择器和操作方法 And 定义附件上传相关的选择器和操作方法 And 遵循现有 Page Object 设计模式 And 所有方法有完整的 TypeScript 类型定义

参考:

  • web/tests/e2e/pages/admin/disability-person.page.ts 作为参考
  • web/tests/e2e/pages/admin/region-management.page.ts 作为参考
  • 遵循项目的 Page Object 设计模式

Tasks / Subtasks

  • 创建订单管理 Page Object 基础结构 (AC: Given, When, And)
    • 定义订单列表页面选择器(标题、新增按钮、搜索框、表格等)
    • 实现 goto() 方法导航到订单管理页面
    • 实现 expectToBeVisible() 方法验证关键元素可见
  • 定义订单列表相关方法和选择器 (AC: When)
    • 定义订单名称搜索输入框和搜索按钮
    • 定义订单筛选器(状态、平台、公司、渠道、日期范围)
    • 定义订单列表表格选择器
    • 实现搜索功能方法 searchByName()
    • 实现筛选功能方法
  • 定义订单 CRUD 相关方法和选择器 (AC: When)
    • 实现打开创建订单对话框方法 openCreateDialog()
    • 实现填写订单表单方法 fillOrderForm()
    • 实现提交表单方法 submitForm()
    • 实现打开编辑订单对话框方法 openEditDialog()
    • 实现打开删除确认对话框方法 openDeleteDialog()
    • 实现订单是否存在验证方法 orderExists()
  • 定义订单详情相关方法和选择器 (AC: When)
    • 实现打开订单详情对话框方法 openDetailDialog()
    • 定义详情对话框内的选择器(订单信息、人员列表、附件列表)
  • 定义人员关联相关方法和选择器 (AC: When)
    • 实现打开人员管理对话框方法 openPersonManagementDialog()
    • 实现添加人员方法 addPersonToOrder()
    • 实现修改工作状态方法 updatePersonWorkStatus()
  • 定义附件管理相关方法和选择器 (AC: When)
    • 实现打开添加附件对话框方法 openAddAttachmentDialog()
    • 实现上传附件方法 uploadAttachment()
  • 添加 TypeScript 类型定义和 JSDoc 注释 (AC: And)
    • 定义 OrderData 接口
    • 定义 OrderPersonData 接口
    • 定义 FormSubmitResult 接口
    • 为所有公共方法添加 JSDoc 注释

Dev Notes

Epic Context

Epic 10: 订单管理 E2E 测试 (Epic C - 业务测试 Epic)

  • 目标: 为订单管理功能编写完整的 E2E 测试,验证订单的 CRUD、状态流转、人员关联和附件管理功能
  • 业务分组: Epic C(业务测试 Epic)
  • 背景: 订单管理是招聘系统的核心业务功能,涉及复杂表单(多选择器联动)、状态流转、人员关联等场景
  • 模式: 业务测试为主,工具包支持为辅(遵循 Epic A 成功模式)

依赖:

  • Epic 1: ✅ 已完成(Select 工具基础框架)
  • Epic 2: ✅ 已完成(Select 工具在真实 E2E 测试中验证)
  • Epic 9: 🔄 进行中(残疾人管理完整 E2E 测试覆盖)

订单管理功能概述

根据 epics.md,订单管理涉及以下核心功能:

  1. 订单列表: 查看、搜索、筛选、分页
  2. 订单 CRUD: 创建、编辑、删除订单
  3. 订单状态流转: 草稿 → 已确认 → 进行中 → 已完成
  4. 订单详情: 查看订单完整信息、人员列表、附件列表
  5. 人员关联: 添加残疾人到订单、管理工作状态(未就业、待就业、已就业、已离职)
  6. 附件管理: 为订单人员添加附件

Page Object 设计模式参考

本项目已建立成熟的 Page Object 设计模式,参考以下文件:

1. disability-person.page.ts (残疾人管理 - 复杂表单示例)

  • 位置: web/tests/e2e/pages/admin/disability-person.page.ts
  • 特点: 多步骤表单、照片上传、动态列表(银行卡、备注、回访记录)
  • 关键模式:
    • 使用 @d8d/e2e-test-utilsselectRadixOptionselectProvinceCity
    • 网络响应监听和 Toast 消息验证
    • 表单调试使用 console.debug

2. region-management.page.ts (区域管理 - 业务模块示例)

  • 位置: web/tests/e2e/pages/admin/region-management.page.ts
  • 特点: 树形结构、CRUD 操作、状态切换
  • 关键模式:
    • 导出的类型定义(RegionData, RegionLevel, FormSubmitResult 等)
    • 完整的 JSDoc 注释
    • 网络响应监听(NetworkResponse 接口)
    • Toast 消息验证(data-sonner-toast)

技术要求

导入依赖:

import { Page, Locator } from '@playwright/test';
import { selectRadixOption, selectRadixOptionAsync } from '@d8d/e2e-test-utils';

选择器策略:

  • 优先使用 data-testid 属性
  • 其次使用 role + name 组合(如 getByRole('button', { name: '新增订单' })
  • 避免使用 CSS 类名(不稳定)
  • 文本匹配使用 exact: true 避免误匹配

网络响应监听模式:

// 收集网络响应
const responses: NetworkResponse[] = [];

// 监听所有网络请求
this.page.on('response', async (response: Response) => {
  const url = response.url();
  if (url.includes('/orders') || url.includes('order')) {
    // 收集响应数据
  }
});

// 执行操作后等待网络空闲
await this.page.waitForLoadState('networkidle', { timeout: 10000 });

Toast 消息验证:

const errorToast = this.page.locator('[data-sonner-toast][data-type="error"]');
const successToast = this.page.locator('[data-sonner-toast][data-type="success"]');

Project Structure Notes

文件位置:

  • Page Object 文件: web/tests/e2e/pages/admin/order-management.page.ts
  • 测试文件目录: web/tests/e2e/specs/admin/
  • Fixtures 目录: web/tests/e2e/fixtures/

对齐统一项目结构:

  • 遵循 project-context.md 中的 TypeScript 严格模式规则
  • 函数参数、返回值必须有明确类型注解
  • 禁止使用 any 类型
  • 公共 API 必须包含完整 JSDoc 注释

测试标准参考

遵循以下测试标准文档(来自 epics.md):

  • docs/standards/testing-standards.md - 测试规范
  • docs/standards/web-ui-testing-standards.md - Web UI 测试规范
  • docs/standards/e2e-radix-testing.md - Radix UI E2E 测试标准(核心)

选择器优先级(来自 e2e-radix-testing.md):

  1. data-testid - 最高优先级
  2. aria-label + role
  3. text content + role - 兜底

错误消息格式标准:

Error: 操作失败
  上下文信息
  💡 修复建议

类型定义参考

基于 region-management.page.ts 的类型定义模式:

/**
 * 订单状态常量
 */
export const ORDER_STATUS = {
  DRAFT: 'draft',
  CONFIRMED: 'confirmed',
  IN_PROGRESS: 'in_progress',
  COMPLETED: 'completed',
} as const;

/**
 * 工作状态常量
 */
export const WORK_STATUS = {
  NOT_EMPLOYED: 'not_employed',
  PENDING: 'pending',
  EMPLOYED: 'employed',
  RESIGNED: 'resigned',
} as const;

/**
 * 订单数据接口
 */
export interface OrderData {
  /** 订单名称 */
  name: string;
  /** 预计开始日期 */
  expectedStartDate?: string;
  /** 平台ID */
  platformId?: number;
  /** 公司ID */
  companyId?: number;
  /** 渠道ID */
  channelId?: number;
  /** 订单状态 */
  status?: typeof ORDER_STATUS[keyof typeof ORDER_STATUS];
  /** 工作状态 */
  workStatus?: typeof WORK_STATUS[keyof typeof WORK_STATUS];
}

/**
 * 订单人员数据接口
 */
export interface OrderPersonData {
  /** 残疾人ID */
  disabledPersonId: number;
  /** 入职日期 */
  hireDate?: string;
  /** 薪资 */
  salary?: number;
  /** 工作状态 */
  workStatus?: typeof WORK_STATUS[keyof typeof WORK_STATUS];
  /** 实际入职日期 */
  actualHireDate?: string;
  /** 离职日期 */
  resignDate?: string;
}

/**
 * 网络响应数据
 */
export interface NetworkResponse {
  url: string;
  method: string;
  status: number;
  ok: boolean;
  responseHeaders: Record<string, string>;
  responseBody: unknown;
}

/**
 * 表单提交结果
 */
export interface FormSubmitResult {
  /** 提交是否成功 */
  success: boolean;
  /** 是否有错误 */
  hasError: boolean;
  /** 是否有成功消息 */
  hasSuccess: boolean;
  /** 错误消息 */
  errorMessage?: string;
  /** 成功消息 */
  successMessage?: string;
  /** 网络响应列表 */
  responses?: NetworkResponse[];
}

订单管理页面元素(待验证)

注意: 以下元素基于 PRD 描述,实际实现时需要通过浏览器开发工具验证 DOM 结构。

订单列表页面:

  • 页面路径: /admin/orders(待确认)
  • 页面标题: "订单管理"
  • 新增订单按钮: "新增订单"
  • 搜索输入框: placeholder="搜索订单名称"
  • 搜索按钮: "搜索"
  • 筛选器: 订单状态、工作状态、平台、公司、渠道、日期范围
  • 订单列表表格: 显示订单名称、平台、公司、渠道、订单状态、工作状态等

订单表单:

  • 订单名称: 必填
  • 预计开始日期: 必填,日期选择器
  • 平台: 可选,下拉选择器
  • 公司: 可选,下拉选择器
  • 渠道: 可选,下拉选择器

订单详情对话框:

  • 显示订单基本信息
  • 显示关联人员列表
  • 显示附件列表

人员管理对话框:

  • 选择残疾人: 下拉选择器
  • 入职日期: 日期选择器
  • 薪资: 数字输入
  • 工作状态: 下拉选择器

附件上传对话框:

  • 选择订单人员: 下拉选择器
  • 上传附件: 文件上传组件

调试技巧

表单调试:

// 在 form.handleSubmit 的第二个参数中添加 console.debug
form.handleSubmit(handleSubmit, (errors) => console.debug('表单验证错误:', errors))

E2E 测试失败调试:

  • 查看 test-results/**/error-context.md
  • 使用 timeout 命令限制运行时间
  • timeout 60 pnpm test:e2e:chromium <测试文件名>

References

Dev Agent Record

Agent Model Used

claude-opus-4-5-20251101

Debug Log References

Completion Notes List

File List