prd.md 45 KB


stepsCompleted: ['step-01-init', 'step-02-discovery', 'step-03-success', 'step-04-journeys', 'step-07-project-type', 'step-08-scoping', 'step-09-functional', 'step-10-nonfunctional', 'step-11-complete', 'revision-2025-01-10', 'revision-2026-01-12', 'revision-2026-01-15-business-context', 'revision-2026-01-15-order-stats-fields'] inputDocuments:

  • name: 项目文档索引 path: docs/index.md type: project-knowledge loadedAt: '2026-01-07T12:00:00.000Z'
  • name: 测试策略 path: docs/standards/testing-standards.md type: testing-standards loadedAt: '2026-01-07T12:00:00.000Z'
  • name: Web UI测试规范 path: docs/standards/web-ui-testing-standards.md type: testing-standards loadedAt: '2026-01-07T12:00:00.000Z'
  • name: 残疾人管理组件 path: allin-packages/disability-person-management-ui/src/components/DisabilityPersonManagement.tsx type: source-code loadedAt: '2026-01-07T12:00:00.000Z'
  • name: 残疾人实体模型 path: allin-packages/disability-module/src/entities/disabled-person.entity.ts type: source-code loadedAt: '2026-01-07T12:00:00.000Z'
  • name: E2E测试示例 path: web/tests/e2e/specs/admin/users.spec.ts type: test-reference loadedAt: '2026-01-07T12:00:00.000Z' documentCounts: briefs: 0 research: 0 projectDocs: 3 testReferences: 1 workflowType: 'prd' lastStep: 6 revisedAt: '2026-01-15' revisionNotes: '添加订单统计字段说明:实际人数、本月打卡、工资视频、个税视频的业务含义和数据来源;原有修订:扩展业务上下文章节:补充残疾人招聘管理系统的业务需求分析,包括系统概述、业务目标、用户角色、业务流程和实体关系;修订范围:从"测试工具包开发"扩展为"Web E2E 测试覆盖",业务测试为主,工具包为支持手段;增加 Epic C: 订单管理 E2E 测试;新增 Epic D/E/F: 小程序相关测试(用户管理、跨端同步、基础配置)' ---

Product Requirements Document - Web 应用 E2E 测试覆盖

作者: Root 创建日期: 2026-01-07 修订日期: 2026-01-15


业务上下文 (Business Context)

系统概述

这是一个残疾人招聘管理系统,包含三个端:

名称 用途
管理后台 WEB 系统管理员和企业管理员使用,负责所有配置和数据管理
企业小程序 yongren 企业用户查看订单、人才、统计数据
人才小程序 rencai 残疾人查看个人信息、打卡、查看考勤薪资

核心价值:为残疾人提供就业机会,为企业提供合规的残疾人用工管理。

业务目标

本系统的核心业务目标是:

  1. 促进残疾人就业:连接残疾人与用工企业,提供完整的招聘管理流程
  2. 合规用工管理:确保企业用工符合残疾人用工相关法规要求
  3. 全流程数字化:从订单创建到薪资发放的全流程线上化管理
  4. 便捷信息查询:通过小程序实现便捷的信息查询和打卡操作

用户角色

系统包含三类主要用户角色:

1. 管理员(系统管理员)

使用端: 管理后台(WEB)

主要职责:

  • 平台(Platform)配置管理
  • 公司(Company)配置管理
  • 渠道(Channel)配置管理
  • 用户管理(创建企业用户和人才用户)
  • 订单分配和管理
  • 残疾人档案管理

权限特点: 拥有系统的最高权限,可以执行所有写操作。

2. 企业管理员(企业用户)

使用端: 管理后台 + 企业小程序(yongren)

主要职责:

  • 创建和管理订单(Order)
  • 查看分配到订单的残疾人
  • 查看企业统计数据
  • 发放薪资

权限特点:

  • 在管理后台:可以创建和管理订单
  • 在企业小程序:只读查看数据,无写操作

3. 残疾人/人才

使用端: 人才小程序(rencai)

主要职责:

  • 查看个人信息
  • 查看考勤记录
  • 查看薪资信息
  • 上下班打卡(小程序中唯一的写操作)

权限特点: 主要是只读操作,仅可进行打卡操作。

核心业务流程

┌─────────────────────────────────────────────────────────────────────┐
│                        残疾人招聘管理流程                              │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  1. 管理员配置基础数据                                               │
│     └─ 创建 Platform(平台)                                         │
│     └─ 创建 Company(公司),关联 Platform                           │
│     └─ 创建 Channel(渠道,可选)                                     │
│                                                                     │
│  2. 企业管理员创建订单                                               │
│     └─ 创建 Order,选择 Platform、Company、Channel                   │
│     └─ 订单状态:草稿 → 已确认 → 进行中 → 已完成                     │
│                                                                     │
│  3. 管理员分配残疾人到订单                                           │
│     └─ 为订单添加 DisabledPerson(残疾人)                           │
│     └─ 设置残疾人在订单中的工作状态                                   │
│                                                                     │
│  4. 人才通过小程序打卡上岗                                           │
│     └─ 使用人才小程序进行上下班打卡                                   │
│     └─ 打卡记录同步到 Attendance 表                                  │
│                                                                     │
│  5. 企业查看统计数据并发放薪资                                       │
│     └─ 通过企业小程序查看订单统计                                     │
│     └─ 发放薪资到人才银行卡                                           │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

核心实体关系

Platform (平台)
  │ 1:N
  ▼
Company (公司)
  │ 1:N (必须 platformId)
  ▼
Order (订单)
  │ 1:N (必须 companyId,可选 channelId)
  ▼
DisabledPerson (残疾人/人才)
  │ 关联
  ├─► Attendance (考勤打卡记录)
  └─► Salary (薪资记录)

实体说明:

实体 说明 关键字段
Platform 平台 平台名称、配置信息
Company 公司 公司名称、platformId(必选)
Channel 渠道 渠道名称、类型(可选)
Order 订单 订单标题、platformId、companyId、channelId、状态
DisabledPerson 残疾人/人才 姓名、身份证号、残疾类型、银行卡信息
Attendance 考勤打卡 关联人员、打卡时间、打卡类型(上班/下班)
Salary 薪资 关联人员、金额、发放时间

重要约束:

  • Company 必须关联一个 Platform
  • Order 必须关联一个 Platform 和一个 Company
  • Channel 是订单的可选项

订单统计字段

企业小程序的订单卡片中显示以下统计字段,用于企业了解订单执行情况:

实际人数

  • 业务含义:当前订单实际关联的残疾人人数
  • 数据来源order_person
  • 计算逻辑:统计 order_person 表中 order_id 等于当前订单 ID 的记录数量
  • 显示格式XX人

本月打卡

  • 业务含义:本月内残疾人上下班打卡的视频记录数量统计
  • 数据来源order_person_asset 表,asset_type='checkin_video'
  • 计算逻辑:统计本月内该订单关联人员的打卡视频数量,格式为 实际打卡数/订单总人数 百分比
  • 显示格式

    本月打卡
    24/30
    80%
    

工资视频

  • 业务含义:残疾人每月薪资确认视频,用于合规证明和薪资发放记录
  • 数据来源order_person_asset 表,asset_type='salary_video'
  • 计算逻辑:统计本月内该订单关联人员的工资确认视频数量
  • 显示格式

    工资视频
    22/24
    92%
    

个税视频

  • 业务含义:残疾人每月个税确认视频,用于税务合规证明
  • 数据来源order_person_asset 表,asset_type='tax_video'
  • 计算逻辑:统计本月内该订单关联人员的个税确认视频数量
  • 显示格式

    个税视频
    20/24
    83%
    

数据实体关系

OrderPersonAsset (人员资产/视频)
  ├─► CHECKIN_VIDEO (打卡视频) → 本月打卡统计
  ├─► SALARY_VIDEO (工资视频) → 工资视频统计
  └─► TAX_VIDEO (个税视频) → 个税视频统计

小程序与管理后台的分工

操作类型 管理后台 企业小程序 人才小程序
创建 全部创建权限
编辑/更新 全部编辑权限
删除 全部删除权限
查看 全部查看权限 订单、人才、统计 个人信息、考勤、薪资
打卡 - - 上班/下班打卡

数据同步机制:

  • 后台操作后,数据实时同步到小程序
  • 小程序通过 WebSocket 接收数据更新
    • 企业小程序:/mini-ws
    • 人才小程序:/talent-mini-ws
  • 人才打卡记录同步到后台

技术栈概览

层级 技术
前端 React 19
后端 Hono 4.x
数据库 PostgreSQL + TypeORM
E2E 测试 Playwright
项目结构 Monorepo

本 PRD 的范围

本 PRD 专注于 Web 管理后台的 E2E 测试覆盖,确保以下功能的质量:

  1. 残疾人管理(Epic A)- 已完成
  2. 区域管理(Epic B)- 待开发
  3. 订单管理(Epic C)- 待开发
  4. 用户管理与小程序登录(Epic D)- 待开发
  5. 跨端数据同步(Epic E)- 待开发
  6. 基础配置管理(Epic F)- 待开发

小程序端的测试(Epic D/E)作为扩展范围,验证完整的业务流程。


执行摘要

本项目旨在为 Web 管理后台的关键业务功能建立完整的 E2E 测试覆盖。在编写业务测试的过程中,将通用测试模式抽象到 @d8d/e2e-test-utils 包中,以加速后续功能的测试开发。

项目背景

188-179 招聘系统是一个大型企业级 Monorepo 招聘管理平台,采用 React 19 + Hono 4.x + TypeORM 技术栈。现有 E2E 测试使用 Playwright,遵循 Page Object 模式。

当前残疾人管理功能已经实现了完整的业务逻辑,包括:

  • 照片上传管理(身份证、残疾证、个人照片等)
  • 银行卡信息管理(支持多张卡)
  • 备注管理(支持特殊需求标记)
  • 回访记录管理

订单管理是招聘系统的核心业务功能,包括:

  • 订单 CRUD 操作(创建、查看、编辑、删除)
  • 订单状态管理(草稿、已确认、进行中、已完成、已取消)
  • 人员关联管理(添加残疾人到订单、管理工作状态)
  • 附件管理(添加订单相关资产文件)
  • 多维度筛选(按平台、公司、渠道、状态等)

但 E2E 测试覆盖不完整,需要补充这些功能的测试用例。

核心目标

主目标:为 Web 管理后台的业务功能建立完整的 E2E 测试覆盖

副目标:在测试过程中抽象可复用工具

工作方式:测试驱动 + 工具演进

  1. 编写业务 E2E 测试(主任务)

    • 优先完成业务功能的测试覆盖
    • 验证业务逻辑的正确性
    • 确保测试稳定性
  2. 抽象通用测试工具(自然演进)

    • 从业务测试中发现重复模式
    • 将通用模式抽象到 @d8d/e2e-test-utils
    • 持续完善工具函数
  3. 输出两种形式

    • 业务测试覆盖:完整的 E2E 测试用例
    • 共享测试工具包packages/e2e-test-utils

Epic 组织

本项目按业务功能组织为多个 Epic:

Epic 内容 状态
Epic A: 残疾人管理 E2E 测试 完整的残疾人管理功能测试覆盖 ✅ 已完成
Epic B: 区域管理 E2E 测试 区域管理(省市区街道)测试覆盖 🔄 待开发
Epic C: 订单管理 E2E 测试 订单管理(CRUD、状态流转、人员关联)测试覆盖 📋 待开发
Epic D: 用户管理与小程序登录测试 用户创建、小程序登录 E2E 测试 🆕 待开发
Epic E: 跨端数据同步测试 后台操作 → 小程序数据验证 🆕 待开发
Epic F: 基础配置管理测试 平台、公司、渠道配置管理测试 🆕 待开发
Epic G: e2e-test-utils 包维护 支持性任务:维护测试工具包 🌟 持续演进

说明

  • Epic A、B、C 是管理后台业务测试 Epic,直接交付业务价值
  • Epic D、E、F 是小程序相关测试 Epic,扩展测试覆盖到完整业务流程
  • Epic G 是支持性 Epic,为业务测试提供工具支持
  • 工具包的开发是自然演进的结果,不是预先规划的目标

特殊价值

这个项目的特殊之处在于:

  1. 业务价值优先:直接交付业务测试覆盖,确保产品质量

  2. 工具自然演进:不是"为了做工具而做工具",而是从实践中抽象

  3. 双重收益

    • 直接收益:完成业务功能的 E2E 测试覆盖
    • 长期收益:可复用的测试工具,加速后续开发
  4. 降低认知负担:新测试开发者不需要深入理解 Radix UI 内部机制,只需调用统一 API

  5. 提高测试稳定性:统一的等待策略、错误处理和重试逻辑

为什么现在做

  • 残疾人管理功能已实现,E2E 测试覆盖是质量保障的需要
  • 在编写残疾人管理测试时,发现可以抽象通用工具
  • 未来还有更多管理功能需要测试,提前建立工具能避免重复工作
  • 区域管理功能需要测试,是继续实践的好机会
  • 订单管理是招聘系统的核心业务功能,涵盖 CRUD、状态流转、人员关联等复杂场景,是测试工具演进的绝佳实践场

项目分类

技术类型: testing(E2E 测试覆盖)

领域: web_admin(Web 管理后台业务功能测试)

复杂度: medium(业务测试 + 工具抽象)

项目上下文: 棕地项目 - 为现有 Web 管理后台补充 E2E 测试覆盖,遵循现有 Page Object 模式


成功标准

用户成功

测试开发者视角的成功指标:

  1. 快速上手

    • 新测试开发者在 30 分钟内能写出第一个包含 Radix UI Select 的测试用例
    • 不需要深入研究 Radix UI 内部机制或 DOM 结构
  2. 一次成功

    • 第一次运行测试就通过,不需要反复调试时序问题
    • 测试连续运行 20 次全部通过,无 flaky 失败
  3. 易于维护

    • 其他团队成员接手测试时,能在 10 分钟内理解并修改测试代码
    • 测试代码清晰表达意图,不需要注释就能看懂
  4. 稳定的开发体验

    • 测试失败时能快速定位是产品问题还是测试问题
    • 有清晰的错误提示指向问题所在

业务成功

业务测试覆盖率(主指标):

业务功能 目标覆盖率 当前状态 测量方式
残疾人管理 关键流程 100% ✅ 已完成 代码覆盖率报告
区域管理 关键流程 100% 🔄 待开发 代码覆盖率报告
订单管理 关键流程 100% 📋 待开发 代码覆盖率报告
其他管理功能 按需补充 ⏳ 规划中 业务优先级

短期(1-3个月)

  • E2E 测试编写时间减少 50%(相比之前每次重新摸索)
  • 残疾人管理功能的测试覆盖率达到关键用户流程 100% ✅
  • 区域管理功能的测试覆盖率达到关键用户流程 100%
  • 订单管理功能的测试覆盖率达到关键用户流程 100%
  • 工具函数被业务测试自然复用

中期(3-6个月)

  • 新功能的 E2E 测试开发周期显著缩短
  • E2E 测试的 flaky 率降低到 5% 以下
  • 至少 4 个管理功能完成 E2E 测试覆盖(残疾人、区域、订单、其他)

长期(6-12个月)

  • 建立 E2E 测试规范成为团队标准
  • 新人 E2E 测试培训时间减少 70%
  • 测试工具函数成为项目的标准基础设施

技术成功

代码质量

  • 共享工具函数的测试覆盖率 ≥ 80%
  • TypeScript 类型安全,无 any 类型
  • 代码通过 ESLint 和 TypeScript 严格模式检查

可扩展性

  • 新增组件测试模式只需扩展,无需修改核心逻辑
  • 支持未来的 Radix UI 版本升级
  • 工具函数设计支持配置和自定义

文档完整性

  • 测试指南覆盖所有提取的模式
  • 每个模式至少提供 1 个实际使用示例
  • 文档清晰说明静态 vs 异步 Select 的区别

可衡量的结果

指标 当前状态 目标状态 测量方式
残疾人管理测试覆盖率 ✅ 关键流程 100% ✅ 已达成 代码覆盖率报告
区域管理测试覆盖率 0% 关键流程 100% 代码覆盖率报告
订单管理测试覆盖率 0% 关键流程 100% 代码覆盖率报告
Radix Select 测试编写时间 需要研究/摸索 5 分钟内完成 计时实验
测试稳定性(通过率) 良好 20 次连续运行 100% 通过 自动化运行
工具函数测试覆盖率 进行中 ≥ 80% 代码覆盖率报告
文档完整性 基础 覆盖所有工具 + 示例 文档检查清单

产品范围

MVP - Minimum Viable Product

核心:为 Web 管理后台的业务功能建立完整的 E2E 测试覆盖

1. Epic A: 残疾人管理 E2E 测试 ✅ 已完成

完整的残疾人管理功能测试覆盖:

  • 照片上传功能测试(身份证、残疾证、个人照片)
  • 银行卡管理功能测试(添加、编辑、删除)
  • 备注功能测试(添加、修改、删除)
  • 回访功能测试(记录创建、查看)
  • 完整流程测试(所有功能组合)

测试过程中抽象的工具:

  • Radix UI Select 测试工具(静态/异步)
  • 文件上传测试工具
  • 其他表单交互工具

2. Epic B: 区域管理 E2E 测试 🔄 当前目标

区域管理功能的完整测试覆盖:

  • 区域列表查看测试
  • 添加区域测试(省/市/区/街道)
  • 编辑区域测试
  • 删除区域测试
  • 级联选择测试(省市区街道四级联动)
  • 完整流程测试

可能需要抽象的工具:

  • 级联选择测试工具(如现有工具不满足需求)
  • 树形结构操作工具(如需要)

3. Epic C: 订单管理 E2E 测试 📋 待开发

订单管理功能的完整测试覆盖(核心业务功能):

  • 订单列表功能测试(查看、搜索、筛选、分页)
  • 订单 CRUD 测试(创建、编辑、删除订单)
  • 订单状态流转测试(激活订单、关闭订单)
  • 订单详情查看测试
  • 人员关联功能测试(添加人员到订单、管理工作状态)
  • 附件管理测试(添加附件)
  • 完整流程测试

可能需要抽象的工具(按需):

  • 复杂表单提交工具(订单表单包含多个选择器:平台、公司、渠道)
  • 状态流转测试工具(订单状态变更操作)
  • 资产附件操作工具

4. e2e-test-utils 包 🌟 支持性任务

作为业务测试的支持工具,自然演进:

packages/e2e-test-utils/
├── src/
│   ├── index.ts
│   ├── select.ts            # Radix UI Select 工具 ✅
│   ├── file-upload.ts       # 文件上传工具 🔄
│   └── ...                  # 其他工具(按需添加)
├── tests/
└── README.md

价值主张: 业务测试覆盖直接交付价值,工具包是自然演进的支持产物。

5. Epic D: 用户管理与小程序登录测试 🆕 待开发

用户管理和小程序登录的完整测试覆盖:

测试前置条件:

  • 管理员创建企业用户(EMPLOYER 类型),关联公司
  • 管理员创建人才用户(TALENT 类型),关联残疾人
  • 用户可登录到对应小程序

测试场景:

  • 用户管理 Page Object 开发
  • 后台创建企业用户测试
  • 后台创建人才用户测试
  • 企业小程序 Page Object 开发
  • 企业小程序登录测试
  • 人才小程序 Page Object 开发
  • 人才小程序登录测试
  • 用户权限验证测试(确保小程序无写操作)

技术要点:

  • 小程序通过 H5 URL 访问(/mini/talent-mini
  • 使用 Playwright 测试 H5 页面
  • 登录后存储 token 进行后续操作

6. Epic E: 跨端数据同步测试 🆕 待开发

验证后台操作后小程序端的数据同步:

测试场景:

  • 后台创建订单 → 企业小程序验证订单显示
  • 后台编辑订单 → 企业小程序验证订单更新
  • 后台添加残疾人到订单 → 人才小程序验证人员显示
  • 后台更新工作状态 → 双小程序验证状态同步
  • 跨端测试稳定性验证

技术要点:

  • 多 Page 对象管理(后台 + 小程序)
  • 数据同步等待策略
  • WebSocket 通信验证(/mini-ws/talent-mini-ws
  • 测试隔离和清理

7. Epic F: 基础配置管理测试 🆕 待开发

平台、公司、渠道配置管理的测试覆盖:

实体关系链:

Platform (平台)
  ↓ 1:N
Company (公司) - 必须 platformId
  ↓ 1:N
Order (订单) - 必须 companyId

测试场景:

  • Platform 管理测试
    • 创建测试平台
    • 验证平台列表显示
  • Company 管理测试(重点)
    • 创建测试公司(需要先有平台)
    • 验证公司列表显示
    • 验证平台关联
  • Channel 管理测试(可选)
    • 创建测试渠道
    • 验证渠道列表显示
  • 配置数据验证
    • 验证订单可以选择平台和公司
    • 验证用户可以关联公司

重要性说明:

  • Platform 是订单创建的必要条件
  • Company 是订单和企业用户的必要条件(关联 Platform)
  • Channel 是订单的可选条件

Epic 优先级建议:

Phase 1(当前进行中):

  1. Epic B: 区域管理 - 相对简单,可作为工具演进实践
  2. Epic C: 订单管理 - 核心业务功能,复杂场景

Phase 2(小程序测试):

  1. Epic F: 基础配置管理 - 为后续 Epic 提供测试数据
    • 必须先完成:Platform 和 Company 测试
  2. Epic D: 用户管理与小程序登录 - 小程序测试的入口
    • 依赖:Epic F(需要 Company 数据)
  3. Epic E: 跨端数据同步测试 - 验证完整业务流程
    • 依赖:Epic D 和 Epic C

Growth Features (Post-MVP)

更多业务功能的 E2E 测试覆盖:

  • 其他管理功能的测试(按业务优先级)
  • 用户权限管理测试
  • 系统配置管理测试
  • 报表功能测试

工具包持续演进(按需):

  • 在编写新业务测试时,如发现重复模式则抽象新工具
  • Date Picker、Slider、Tabs 等 Radix 组件测试模式(如业务需要)
  • 表单验证错误处理测试模式(如业务需要)

开发体验增强:

  • VS Code snippets 快速插入测试代码
  • 测试模板和最佳实践文档
  • 更完善的错误提示和调试信息

Vision (Future)

完整的 E2E 测试覆盖:

  • Web 管理后台所有关键功能的测试覆盖
  • 自动化测试作为 CI/CD 的标准环节
  • 测试覆盖率可视化仪表盘

智能化测试开发:

  • AI 辅助测试编写(描述行为自动生成测试)
  • 自动发现页面组件并生成测试骨架
  • 智能等待策略(根据组件特性自动调整)

团队测试文化:

  • 测试驱动开发成为团队标准实践
  • 新人培训包含 E2E 测试开发
  • 测试模式库和最佳实践分享

用户旅程

旅程 1:张伟 - 赶时间的测试开发者

人物设定:

  • 姓名: 张伟
  • 角色: 全栈开发者,需要为新功能编写 E2E 测试
  • 情境: 产品经理刚刚要求他为残疾人管理功能补充完整的 E2E 测试
  • 痛点: 之前每次写测试都要花大量时间研究 Radix UI 的 DOM 结构,测试经常因为时序问题失败
  • 目标: 快速完成测试任务,测试要稳定可靠

他的故事:

周一早上,张伟接到任务:"残疾人管理功能需要补充照片上传、银行卡管理等功能的 E2E 测试,周三前完成。"

张伟叹了口气。上次写测试时,他花了整整一下午研究 Radix UI Select 的测试方法,还要处理各种时序问题。测试写完后还经常 flaky,团队 CI 管道里经常因为这个功能失败。

他打开项目,注意到有个新包 packages/e2e-test-utils。他好奇地点开 README,发现里面正好有他需要的 Radix UI Select 测试工具。

他决定试一试。只需要导入工具函数,然后调用 selectRadixOption(page, '残疾类型', '视力残疾') 就可以了。不需要研究 DOM 结构,不需要处理复杂的等待逻辑。

第一个小时: 张伟轻松完成了照片上传和银行卡管理的测试。这些功能之前他一直觉得很难测试,现在居然这么简单。

第二个小时: 他继续添加备注和回访功能的测试。遇到异步加载的省份选择器时,他发现工具函数已经处理了等待逻辑,直接用 selectRadixOptionAsync 就可以了。

第三个小时: 张伟写完最后一个测试,点击运行。所有测试一次性通过!他有些不敢相信,又运行了 5 次,全部稳定通过。

结果: 周二下午,张伟不仅完成了所有测试,还把工具函数推荐给了团队其他成员。他甚至有时间优化测试代码,让测试更清晰易懂。


旅程需求总结

这些用户旅程揭示了以下核心需求:

测试开发者(张伟)的需求:

  • 简单易用的 API,不需要深入理解 Radix UI
  • 自动处理等待和时序问题
  • 清晰的错误提示和调试信息
  • 完整的使用文档和示例
  • 工具函数开箱即用,快速集成

新手测试开发者的需求:

  • 快速入门指南,降低学习曲线
  • 渐进式的学习路径(从简单到复杂)
  • 丰富的实际代码示例
  • 常见问题和解决方案文档

QA 工程师的需求:

  • 测试工具函数的可靠性保障
  • 测试覆盖率和质量报告
  • 测试最佳实践指南
  • 团队协作和代码审查支持

Tech Lead 的需求:

  • 代码质量和可维护性标准
  • 测试模式的一致性和规范性
  • 技术决策文档和架构说明
  • 团队培训和知识传递材料

Developer Tool Specific Requirements

Project-Type Overview

188-179 E2E 测试工具包是一个开发者工具库,专注于简化 Playwright E2E 测试中对 Radix UI 组件的测试。作为内部工具包,它需要提供清晰的 API、完整的类型安全和易用的开发体验。

Technical Architecture Considerations

语言与类型系统:

  • 纯 TypeScript 实现,目标 ES2020+
  • 严格类型检查,无 any 类型
  • 完整的 JSDoc 注释用于 IDE 提示

包结构:

packages/e2e-test-utils/
├── package.json
├── src/
│   ├── index.ts              # 主导出
│   ├── radix-select.ts       # Radix UI Select 工具
│   ├── file-upload.ts        # 文件上传工具
│   ├── form-helper.ts        # 表单辅助函数
│   ├── dialog.ts             # 对话框操作
│   └── dynamic-list.ts       # 动态列表管理
├── tests/                    # 工具函数的单元测试
└── README.md

依赖管理:

  • Peer dependency: @playwright/test (由测试项目提供)
  • 无运行时依赖,保持轻量
  • 开发依赖: TypeScript, Vitest (用于自测)

Language & API Matrix

组件类型 工具函数 参数 返回值
Radix UI Select (静态) selectRadixOption(page, label, value) Page, 标签文本, 选项值 Promise<void>
Radix UI Select (异步) selectRadixOptionAsync(page, label, value, options) Page, 标签文本, 选项值, 等待配置 Promise<void>
文件上传 uploadFileToField(page, selector, fileName) Page, 选择器, 文件名 Promise<void>
多步骤表单 fillMultiStepForm(page, steps) Page, 步骤数组 Promise<void>
动态列表 addDynamicListItem(page, itemType, data) Page, 项类型, 数据 Promise<void>
对话框操作 handleDialog(page, action) Page, 操作类型 Promise<void>

Installation Methods

在测试项目中安装:

# 在 web/ 目录下
pnpm add -D @d8d/e2e-test-utils@workspace:*

在测试文件中导入:

import { selectRadixOption, uploadFileToField } from '@d8d/e2e-test-utils';

API Surface

核心工具函数签名:

/**
 * 选择 Radix UI 下拉框的静态选项
 * @param page Playwright Page 对象
 * @param label 下拉框标签文本
 * @param value 要选择的选项值
 */
export async function selectRadixOption(
  page: Page,
  label: string,
  value: string
): Promise<void>

/**
 * 选择 Radix UI 下拉框的异步加载选项
 * @param page Playwright Page 对象
 * @param label 下拉框标签文本
 * @param value 要选择的选项值
 * @param options 等待配置 (超时、重试等)
 */
export async function selectRadixOptionAsync(
  page: Page,
  label: string,
  value: string,
  options?: AsyncSelectOptions
): Promise<void>

/**
 * 上传文件到指定字段
 * @param page Playwright Page 对象
 * @param selector 文件输入选择器
 * @param fileName 要上传的文件名(相对于 fixtures 目录)
 */
export async function uploadFileToField(
  page: Page,
  selector: string,
  fileName: string
): Promise<void>

Code Examples

示例 1:选择静态枚举型下拉框

import { selectRadixOption } from '@d8d/e2e-test-utils';

// 选择残疾类型
await selectRadixOption(page, '残疾类型', '视力残疾');

示例 2:选择异步加载的下拉框

import { selectRadixOptionAsync } from '@d8d/e2e-test-utils';

// 选择省份(异步加载)
await selectRadixOptionAsync(page, '省份', '广东省', {
  timeout: 5000,
  waitForOption: true
});

示例 3:上传照片

import { uploadFileToField } from '@d8d/e2e-test-utils';

// 上传身份证照片
await uploadFileToField(page, '[data-testid="id-card-photo-input"]', 'sample-id-card.jpg');

Migration Guide

从现有的内联测试代码迁移到工具函数:

之前(内联代码):

// 需要手动处理 Radix UI 的复杂 DOM 结构和时序
await page.click(`text=残疾类型`);
await page.waitForSelector('[role="option"]');
await page.click(`[role="option"]:has-text("视力残疾")`);

之后(使用工具函数):

import { selectRadixOption } from '@d8d/e2e-test-utils';

await selectRadixOption(page, '残疾类型', '视力残疾');

迁移步骤:

  1. 安装工具包:pnpm add -D @d8d/e2e-test-utils@workspace:*
  2. 导入需要的工具函数
  3. 替换内联的 Radix UI 操作代码
  4. 验证测试通过

Implementation Considerations

等待策略:

  • 使用 waitForLoadState('networkidle') 处理异步加载
  • 为静态选项设置合理默认超时(2秒)
  • 为异步选项提供可配置超时

错误处理:

  • 提供清晰的错误消息,指出具体失败点
  • 区分"元素未找到"和"超时"错误
  • 包含上下文信息(选择器、标签、期望值)

测试稳定性:

  • 使用 Playwright 的 auto-waiting 机制
  • 添加显式等待防止时序问题
  • 支持重试机制处理 flaky 网络请求

可扩展性:

  • 工具函数支持配置对象参数
  • 预留钩子函数用于自定义行为
  • 设计支持未来 Radix UI 版本升级

Project Scoping & Phased Development

MVP Strategy & Philosophy

MVP 方法: 测试驱动 + 工具演进

核心理念:优先完成业务功能的 E2E 测试覆盖,在测试过程中自然抽象可复用工具。工具包是支持手段,不是目标本身。

资源需求:

  • 团队规模:1-2 名开发者
  • 技能要求:TypeScript、Playwright、业务理解
  • 时间估算:每个业务功能 1-2 周

MVP Feature Set (Phase 1)

核心用户旅程支持:

  • ✅ 张伟的快速测试开发旅程(残疾人管理测试)
  • 🔄 张伟继续旅程(区域管理测试)
  • 📋 张伟再出发(订单管理测试)

Epic A: 残疾人管理 E2E 测试 ✅ 已完成

业务测试覆盖:

  • 照片上传功能测试
  • 银行卡管理功能测试
  • 备注功能测试
  • 回访功能测试
  • 完整流程测试

测试过程中抽象的工具:

  • selectRadixOption() - 静态枚举型下拉框
  • selectRadixOptionAsync() - 异步加载型下拉框
  • uploadFileToField() - 文件上传
  • 其他表单辅助函数

Epic B: 区域管理 E2E 测试 🔄 当前目标

业务测试覆盖:

  • 区域列表查看
  • 添加区域(省/市/区/街道)
  • 编辑区域
  • 删除区域
  • 级联选择测试
  • 完整流程测试

可能需要抽象的工具(按需):

  • 级联选择工具(如现有 selectCascade 不满足需求)
  • 树形结构操作工具(如需要)

Epic C: 订单管理 E2E 测试 📋 待开发

业务测试覆盖:

  • 订单列表功能(查看、搜索、筛选、分页)
  • 订单 CRUD 操作(创建、编辑、删除)
  • 订单状态流转(激活订单、关闭订单)
  • 订单详情查看
  • 人员关联功能(添加人员、管理工作状态)
  • 附件管理(添加附件)
  • 完整流程测试

可能需要抽象的工具(按需):

  • 复杂表单提交工具(平台、公司、渠道等多选择器)
  • 状态流转测试工具(订单状态变更)
  • 资产附件操作工具

e2e-test-utils 包维护 🌟 持续演进

  • 工具函数测试覆盖率 ≥ 80%
  • 完善文档和使用示例
  • 按业务需求添加新工具

MVP 排除的功能(留给后续版本):

  • VS Code snippets
  • CLI 测试生成器
  • AI 辅助测试生成
  • 跨项目的工具包开源

Post-MVP Features

Phase 2 (Post-MVP) - 业务测试扩展:

更多业务功能测试:

  • 其他管理功能的 E2E 测试覆盖
  • 按业务优先级和风险评估确定测试顺序
  • 每个功能的完整测试用例

工具包按需演进:

  • 在编写新业务测试时,如发现重复模式则抽象新工具
  • Date Picker、Slider、Tabs 等(如业务需要)
  • 表单验证错误处理模式(如业务需要)

开发体验增强:

  • VS Code snippets 快速插入
  • 测试模板和最佳实践文档
  • 更完善的错误提示和调试信息

质量保障:

  • CI/CD 集成测试报告
  • 测试覆盖率趋势追踪
  • Flaky 测试检测和报告

Risk Mitigation Strategy

技术风险:

  • 风险: Radix UI DOM 结构变化导致工具函数失效
  • 缓解:
    • 使用稳定的选择器策略(role、data-testid)
    • 设计可扩展的函数签名,支持自定义选择器
    • 工具函数自测,快速发现问题

业务测试风险:

  • 风险: 业务功能变更导致测试用例失效
  • 缓解:
    • 测试用例与业务实现解耦
    • 使用 Page Object 模式提高可维护性
    • 定期审查和更新测试用例

市场/采用风险:

  • 风险: 团队成员不愿意使用新工具,继续用老方法
  • 缓解:
    • 通过实际业务测试证明价值
    • 渐进式推广:让早期使用者推荐给团队
    • 完善文档:降低学习成本

资源风险:

  • 风险: 测试开发时间超出预期
  • 缓解:
    • 按业务优先级排序,先做高价值功能
    • 每个业务功能独立时间盒(1-2 周)
    • 降级方案:优先保证关键路径的测试覆盖

质量风险:

  • 风险: 测试不稳定,经常 flaky 失败
  • 缓解:
    • 工具函数编写单元测试
    • 20 次连续运行稳定性验证
    • 代码审查确保质量

Scope Decision Rationale

为什么 MVP 范围这样设计:

  1. 业务价值优先:直接交付业务测试覆盖,确保产品质量

  2. 工具自然演进:不预设工具需求,从实践中抽象

  3. 渐进式扩展:每个业务功能独立 Epic,可并行或串行

  4. 可测量成果:每个 Epic 都有明确的成功标准(覆盖率、稳定性)

  5. 风险可控:范围明确,时间盒限制,有降级方案

MVP 成功标志:

  • ✅ 残疾人管理 E2E 测试覆盖关键流程 100%
  • ✅ 测试连续运行 20 次,100% 通过
  • ✅ 从测试中抽象可复用工具
  • 🔄 区域管理 E2E 测试覆盖关键流程 100%
  • 📋 订单管理 E2E 测试覆盖关键流程 100%

Functional Requirements

Radix UI Select 组件测试支持

  • FR1: 测试开发者可以使用工具函数选择静态枚举型 Radix UI Select 下拉框的选项
  • FR2: 测试开发者可以使用工具函数选择异步加载型 Radix UI Select 下拉框的选项
  • FR3: 工具函数可以自动处理 Radix UI Select 的 DOM 结构和交互流程
  • FR4: 工具函数可以等待异步加载的选项出现在下拉列表中
  • FR5: 工具函数可以提供清晰的错误提示,包含标签、期望值等上下文信息
  • FR6: 工具函数可以区分"元素未找到"和"超时"错误类型

文件上传测试支持

  • FR7: 测试开发者可以使用工具函数上传文件到指定的文件输入字段
  • FR8: 工具函数可以从 fixtures 目录加载测试文件
  • FR9: 工具函数可以支持多文件上传场景
  • FR10: 工具函数可以验证文件上传是否成功完成

表单交互测试支持

  • FR11: 测试开发者可以使用工具函数填写多步骤表单
  • FR12: 工具函数可以滚动页面到特定的表单区域
  • FR13: 工具函数可以处理表单验证错误场景
  • FR14: 测试开发者可以使用工具函数提交表单并等待响应
  • FR15: 工具函数可以支持常见的表单字段类型(文本、选择器、日期等)

动态列表测试支持

  • FR16: 测试开发者可以使用工具函数向动态列表中添加新项
  • FR17: 测试开发者可以使用工具函数从动态列表中删除项
  • FR18: 工具函数可以支持不同类型的动态列表项(银行卡、备注等)
  • FR19: 工具函数可以验证动态列表项添加或删除后的状态
  • FR20: 工具函数可以处理动态列表的异步更新场景

对话框操作测试支持

  • FR21: 测试开发者可以使用工具函数统一操作对话框(确认、取消、关闭)
  • FR22: 工具函数可以等待对话框完全关闭后再继续执行
  • FR23: 工具函数可以处理对话框内的表单填写和提交
  • FR24: 工具函数可以验证对话框是否按预期打开或关闭

测试工具包基础设施

  • FR25: 测试开发者可以通过 npm workspace 协议安装测试工具包
  • FR26: 工具包可以作为 peer dependency 依赖 Playwright,不增加运行时依赖
  • FR27: 工具包提供完整的 TypeScript 类型定义和类型提示
  • FR28: 工具包的所有导出函数都有完整的 JSDoc 注释
  • FR29: 工具包使用严格类型检查,不使用 any 类型
  • FR30: 工具包支持目标 ES2020+ 的 JavaScript 环境
  • FR31: 工具包的每个工具函数都可以独立导入和使用
  • FR32: 工具包可以与其他测试工具和库兼容使用

文档和开发者支持

  • FR33: 测试开发者可以通过 README 快速了解工具包的用途和安装方法
  • FR34: 文档提供每个工具函数的详细使用示例
  • FR35: 文档提供静态 Select 和异步 Select 的区别说明
  • FR36: 文档提供从现有测试代码迁移到工具函数的指南
  • FR37: 文档提供常见问题和解决方案
  • FR38: 文档提供残疾人管理测试作为完整的使用示例
  • FR39: 测试开发者可以在 30 分钟内使用工具函数编写第一个测试
  • FR40: 工具包的使用示例覆盖所有 6 个核心工具函数

测试质量和稳定性保障

  • FR41: 工具函数使用 Playwright 的 auto-waiting 机制防止时序问题
  • FR42: 工具函数为静态选项设置合理的默认超时配置
  • FR43: 工具函数为异步选项提供可配置的超时参数
  • FR44: 工具函数可以支持重试机制处理不稳定的网络请求
  • FR45: 工具函数可以在测试连续运行 20 次时保持 100% 通过率

可扩展性和维护性

  • FR46: 工具函数支持配置对象参数,允许自定义行为
  • FR47: 工具函数设计支持未来的 Radix UI 版本升级
  • FR48: 工具函数使用稳定的选择器策略(role、data-testid)
  • FR49: 工具包预留扩展接口,支持新增其他 Radix 组件测试模式
  • FR50: 工具包的代码结构清晰,便于团队贡献和维护

Non-Functional Requirements

可靠性

测试稳定性(最关键):

  • NFR1: 工具函数在相同条件下连续运行 20 次,必须保持 100% 通过率,无 flaky 失败
  • NFR2: 工具函数能够正确处理异步加载场景,避免时序问题导致的测试失败
  • NFR3: 当 DOM 元素暂时不可用时,工具函数提供清晰的错误消息,而不是超时无响应
  • NFR4: 工具函数能够区分产品 bug 和测试代码问题,帮助开发者快速定位问题根源

错误处理和诊断:

  • NFR5: 当选择操作失败时,错误消息包含以下信息:
    • 下拉框标签名称
    • 期望选择的值
    • 实际可用的选项列表
    • 失败原因(元素未找到、超时、选项不存在等)
  • NFR6: 当文件上传失败时,错误消息包含文件路径、选择器、失败原因
  • NFR7: 错误消息格式统一,便于日志分析和问题定位

性能

测试执行效率:

  • NFR8: 单个 Radix UI Select 选择操作(静态)应在 2 秒内完成
  • NFR9: 单个 Radix UI Select 选择操作(异步)应在 5 秒内完成(默认超时)
  • NFR10: 工具函数本身的开销不超过 100ms(不包括 Playwright 操作时间)
  • NFR11: 使用工具函数的测试比手动编写 DOM 操作的测试执行时间差异 < 10%

等待策略优化:

  • NFR12: 静态选项使用合理的默认超时(2 秒),避免不必要的等待
  • NFR13: 异步选项提供可配置的超时参数,默认值为 5 秒
  • NFR14: 工具函数使用 Playwright 的 auto-waiting 机制,减少显式等待的需要

集成性

Playwright 兼容性:

  • NFR15: 工具包兼容 Playwright 最新稳定版本和上一个 LTS 版本
  • NFR16: 工具包可以作为 peer dependency 引用,不增加运行时依赖
  • NFR17: 工具函数接受标准 Playwright Page 对象作为参数
  • NFR18: 工具包不依赖特定版本的 Playwright,使用灵活的版本范围

测试框架集成:

  • NFR19: 工具函数可以在任何使用 Playwright 的测试框架中运行(Vitest、Jest 等)
  • NFR20: 工具包不修改全局配置,不需要额外的测试框架配置
  • NFR21: 工具函数可以与现有的 Page Object 模式无缝集成

Monorepo 集成:

  • NFR22: 工具包通过 pnpm workspace 协议安装,支持本地开发
  • NFR23: 工具包的构建产物与项目的 TypeScript 配置兼容
  • NFR24: 工具包的类型定义可以自动被 IDE 识别和提示

代码质量

类型安全:

  • NFR25: 工具包使用 TypeScript 严格模式,无 any 类型
  • NFR26: 所有导出函数都有完整的参数类型和返回值类型
  • NFR27: 类型定义支持 IDE 自动补全和类型检查
  • NFR28: 类型错误在编译时被捕获,不在运行时暴露

代码可维护性:

  • NFR29: 工具包的代码覆盖率 ≥ 80%
  • NFR30: 每个工具函数都有对应的单元测试
  • NFR31: 代码遵循项目的 ESLint 和 Prettier 配置
  • NFR32: 函数复杂度保持在低水平(圈复杂度 < 10)

文档质量:

  • NFR33: 每个导出函数都有完整的 JSDoc 注释
  • NFR34: README 包含快速入门、安装说明、基本用法
  • NFR35: 每个工具函数至少有 1 个实际使用示例
  • NFR36: 文档说明静态 Select 和异步 Select 的区别和使用场景

开发者体验:

  • NFR37: 新测试开发者可以在 30 分钟内使用工具函数编写第一个测试
  • NFR38: 工具函数的命名清晰直观,不需要频繁查看文档
  • NFR39: 函数参数设计简洁,必需参数 ≤ 3 个
  • NFR40: 错误消息对新手友好,包含问题诊断和建议修复步骤

兼容性

浏览器和环境:

  • NFR41: 工具函数在 Playwright 支持的所有浏览器中正常工作(Chromium、Firefox、WebKit)
  • NFR42: 工具函数在 headless 和 headed 模式下都能正常工作
  • NFR43: 工具函数在 CI/CD 环境中稳定运行

版本兼容性:

  • NFR44: 工具包支持 Node.js 当前 LTS 版本和上一个 LTS 版本
  • NFR45: 工具包的设计考虑未来 Radix UI 版本升级,使用稳定的选择器策略
  • NFR46: 重大版本变更时提供迁移指南