stepsCompleted: ['step-01-validate-prerequisites', 'step-02-design-epics', 'step-03-create-stories', 'step-04-final-validation', 'revision-2025-01-10', 'step-01-revalidate-2025-01-10', 'revision-2026-01-12'] inputDocuments:
本文档提供了 188-179-template-6 的完整 Epic 和 Story 分解,将 PRD 和 Architecture 要求分解为可实现的 Story。
项目定位(修订后): 为 Web 管理后台的业务功能建立完整的 E2E 测试覆盖,在测试过程中将通用模式抽象到 @d8d/e2e-test-utils 包中。
Epic 组织:
Radix UI Select 组件测试支持 (FR1-FR6):
文件上传测试支持 (FR7-FR10):
表单交互测试支持 (FR11-FR15):
动态列表测试支持 (FR16-FR20):
对话框操作测试支持 (FR21-FR24):
测试工具包基础设施 (FR25-FR32):
文档和开发者支持 (FR33-FR40):
测试质量和稳定性保障 (FR41-FR45):
可扩展性和维护性 (FR46-FR50):
可靠性 (NFR1-NFR7):
性能 (NFR8-NFR14):
集成性 (NFR15-NFR24):
代码质量 (NFR25-NFR40):
any 类型兼容性 (NFR41-NFR46):
从 Architecture 文档提取的技术需求:
包结构需求:
packages/e2e-test-utils,与现有的 @d8d/shared-test-util(后端集成测试)分离src/ 分为 radix-select.ts, file-upload.ts, form-helper.ts, dialog.ts, dynamic-list.tstypes.ts, errors.ts, constants.tsindex.ts,支持 tree-shakingAPI 设计需求:
selectRadixOption)Async 后缀(如 selectRadixOptionAsync)Options 后缀(如 AsyncSelectOptions)类型系统需求:
types.ts 存放共享类型(BaseOptions),各模块文件存放特定类型BaseOptionsany 类型选择器策略需求:
data-testid错误处理需求:
E2ETestError + ErrorContext测试策略需求:
tests/test-app/ 使用 Vite + React@d8d/shared-ui-components 组件常量定义需求:
DEFAULT_TIMEOUTS.static = 2000, async = 5000, networkIdle = 10000SELECTOR_STRATEGIES 数组文档需求:
遵循项目标准:
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 UI 测试标准提取的详细需求:
核心工具函数签名(必须按此实现):
// Radix UI Select 工具
selectRadixOption(page: Page, label: string, value: string): Promise<void>
selectRadixOptionAsync(page: Page, label: string, value: string, options?: AsyncSelectOptions): Promise<void>
// 文件上传工具
uploadFileToField(page: Page, selector: string, fileName: string): Promise<void>
// 表单辅助工具
fillMultiStepForm(page: Page, steps: FormStep[]): Promise<void>
scrollToSection(page: Page, sectionName: string): Promise<void>
// 动态列表工具
addDynamicListItem(page: Page, itemType: string, data: Record<string, any>): Promise<void>
deleteDynamicListItem(page: Page, itemType: string, index: number): Promise<void>
// 对话框工具
handleDialog(page: Page, action: 'confirm' | 'cancel' | 'close'): Promise<void>
waitForDialogClosed(page: Page): Promise<void>
cancelDialog(page: Page): Promise<void>
DOM 结构理解需求:
data-radix-select-trigger 触发器,role="listbox" 选项列表,role="option" 单个选项role="dialog" 对话框容器data-value 用于选项值,data-state 用于状态跟踪选择器策略实现细节:
// 触发器选择器优先级
const TRIGGER_SELECTORS = [
`[data-testid="${label}-trigger"]`, // 最高优先级
`text="${label}"`, // 文本匹配
`[role="combobox"]` // 兜底
];
// 选项选择器优先级
const OPTION_SELECTORS = [
`[role="option"][data-value="${value}"]`, // data-testid + data-value
`[role="option"]:has-text("${value}")` // 文本匹配兜底
];
性能标准(来自测试标准文档): | 操作 | 目标时间 | 最大可接受时间 | |------|---------|---------------| | 静态 Select 选择 | < 1s | 2s | | 异步 Select 选择 | < 3s | 5s | | 文件上传 | < 2s | 5s | | 表单提交 | < 2s | 5s |
Fixtures 目录结构标准:
web/tests/
└── fixtures/
├── images/ # 测试图片(身份证照片、残疾证照片等)
└── documents/ # 测试文档(PDF 等)
错误消息格式标准:
Error: Radix Select 选项 "xxx" 未找到
标签: 残疾类型
期望值: xxx
可用选项: 视力残疾, 听力残疾, 肢体残疾, 智力残疾
Error: Radix Select 等待超时
标签: 省份
期望值: 广东省
超时时间: 5000ms
可能原因: 网络请求过慢或选项未加载
测试稳定性最佳实践:
waitForTimeoutdata-testid 选择器,谨慎使用文本选择器,避免使用不稳定的 CSS 类完整示例需求:
| FR 范围 | Epic | 描述 |
|---|---|---|
| FR1-FR6 | Epic 1 | Radix UI Select 测试支持(静态和异步) |
| FR25-FR32 | Epic 1 | 包基础设施(package.json、类型定义、配置) |
| FR7-FR10 | Epic 3 | 文件上传测试支持(文件上传工具与验证) |
| FR11-FR15 | Epic 4 | 表单交互测试支持(表单工具与验证) |
| FR16-FR24 | Epic 5 | 列表和对话框测试支持(列表和对话框工具与验证) |
| FR41-FR45 | Epic 2, 3, 4, 5, 6, 8 | 质量与稳定性(各工具验证、全面验证、稳定性测试) |
| FR33-FR40 | Epic 7 | 文档与开发者体验(README、示例、迁移指南) |
| FR46-FR50 | Epic 3, 4, 5, 8 | 可扩展性(各工具的配置和扩展支持) |
| FR1-FR50 | Epic 8 | 区域管理 E2E 测试(复用现有工具,必要时扩展级联选择/树形结构工具) |
Epic 规划变更说明(2026-01-11):
"先验证再扩展"策略: 基于 Epic 2 的成功经验,每个工具都遵循"开发 → E2E 验证 → 稳定性验证"的模式:
目标: 测试开发者可以安装 @d8d/e2e-test-utils 包,立即使用 Select 工具测试 Radix UI Select 组件(最常用、最关键的测试场景)。
状态: ✅ Done
交付物:
selectRadixOption() 和 selectRadixOptionAsync() 函数FRs covered: FR1-FR6, FR25-FR32
目标: 在 web/tests/e2e/ 的残疾人管理测试中使用 Select 工具,验证工具在真实场景中的可用性和稳定性。
状态: ✅ Done
交付物:
FRs covered: FR41-FR45 (部分)
关键经验:
目标: 遵循 Epic 2 成功模式,开发文件上传工具并在真实 E2E 测试中验证,解决当前测试超时阻塞问题。
状态: 🆕 Backlog
模式: 工具开发 → 真实 E2E 测试验证 → 问题修复 → 稳定性验证
交付物:
uploadFileToField() 文件上传工具FRs covered: FR7-FR10, FR46-FR50 (部分), FR41-FR45 (部分)
目标: 开发表单辅助工具并在真实 E2E 测试中验证。
状态: Backlog (等待 Epic 3 完成)
模式: 工具开发 → 真实 E2E 测试验证 → 稳定性验证
交付物:
fillMultiStepForm(), scrollToSection() - 表单辅助工具FRs covered: FR11-FR15, FR46-FR50 (部分), FR41-FR45 (部分)
目标: 开发动态列表和对话框工具并在真实 E2E 测试中验证。
状态: Backlog (等待 Epic 4 完成)
模式: 工具开发 → 真实 E2E 测试验证 → 稳定性验证
交付物:
addDynamicListItem(), deleteDynamicListItem() - 动态列表工具handleDialog(), waitForDialogClosed() - 对话框工具FRs covered: FR16-FR24, FR46-FR50 (部分), FR41-FR45 (部分)
目标: 工具包在真实的残疾人管理 E2E 测试中完整验证,证明所有工具函数可用且稳定。
状态: Backlog (等待 Epic 5 完成)
交付物:
FRs covered: FR38, FR41-FR45
目标: 测试开发者可以在 30 分钟内上手使用工具包,有完整的文档、示例和迁移指南。
状态: Backlog (等待 Epic 6 完成)
交付物:
FRs covered: FR33-FR40
目标: 测试开发者可以安装 @d8d/e2e-test-utils 包,立即使用 Select 工具测试 Radix UI Select 组件(最常用、最关键的测试场景)。
作为测试开发者,
我想要可以安装 @d8d/e2e-test-utils 包,
以便在项目中使用测试工具函数。
验收标准:
Given 项目是 Monorepo 结构
When 创建 packages/e2e-test-utils/ 目录
Then 目录结构包含 src/, tests/, package.json, tsconfig.json, vitest.config.ts
And package.json 包含正确的包名、版本、peer dependencies(@playwright/test)
And tsconfig.json 启用严格模式,目标 ES2020+
And 可以通过 pnpm add -D @d8d/e2e-test-utils@workspace:* 安装
作为测试开发者, 我想要工具包有完整的类型支持和统一的错误处理, 以便获得类型安全和清晰的错误提示。
验收标准:
Given 包结构已创建
When 实现 src/types.ts, src/errors.ts, src/constants.ts
Then types.ts 导出 BaseOptions, AsyncSelectOptions, FileUploadOptions 等
And errors.ts 导出 E2ETestError 类和 ErrorContext 接口
And constants.ts 定义 DEFAULT_TIMEOUTS(static: 2000, async: 5000)
And 所有类型使用 TypeScript 严格模式,无 any 类型
作为测试开发者,
我想要使用 selectRadixOption() 函数选择静态枚举型下拉框,
以便无需理解 Radix UI DOM 结构就能编写测试。
验收标准:
Given 类型定义已创建
When 实现 src/radix-select.ts 中的 selectRadixOption() 函数
Then 函数签名:selectRadixOption(page: Page, label: string, value: string): Promise<void>
And 选择器策略:data-testid → aria-label + role → text content
And 自动处理点击触发器、等待选项列表、点击选项
And 错误时抛出 E2ETestError,包含标签、期望值、可用选项
And 操作在 2 秒内完成(NFR8)
作为测试开发者,
我想要使用 selectRadixOptionAsync() 函数选择异步加载的下拉框,
以便测试省份、城市等动态加载的选项。
验收标准:
Given 静态 Select 函数已实现
When 实现 selectRadixOptionAsync(page, label, value, options?) 函数
Then 支持 AsyncSelectOptions 配置(timeout, waitForOption)
And 使用 waitForLoadState('networkidle') 等待异步加载
And 默认超时 5 秒,可配置
And 超时时提供清晰错误消息(标签、期望值、超时时间、可能原因)
作为测试开发者, 我想要可以导入工具函数并查看快速入门文档, 以便快速开始使用工具包。
验收标准:
Given Select 工具函数已实现
When 创建 src/index.ts 和 README.md
Then index.ts 导出所有公共函数和类型(tree-shakeable)
And README 包含:安装说明、快速入门、Select 使用示例
And 所有导出函数有完整的 JSDoc 注释
And 可以 import { selectRadixOption } from '@d8d/e2e-test-utils'
作为测试开发者, 我想要 Select 工具函数有充分的单元测试, 以便确保函数的正确性和稳定性。
验收标准:
Given Select 工具函数已实现
When 创建 tests/unit/radix-select.test.ts
Then 测试覆盖率 ≥ 80%(NFR29)
And 测试用例包括:成功选择、选项不存在、超时、错误处理
And 使用 Vitest 运行测试
And 所有测试通过
目标: 在 web/tests/e2e/ 的现有残疾人管理测试中使用 Select 工具,验证工具在真实场景中的可用性和稳定性,收集实际使用反馈,为后续工具设计提供指导。
背景: Epic 1 已完成 Select 工具的开发和单元测试,但尚未在真实 E2E 测试场景中验证。通过在现有测试中使用这些工具,我们可以:
范围:
web/tests/e2e/ 测试基础设施依赖:
验收标准:
作为测试开发者,
我想要在 web 目录安装 @d8d/e2e-test-utils 包,
以便在 E2E 测试中使用 Select 工具。
验收标准:
Given Epic 1 已完成,@d8d/e2e-test-utils 包已构建
When 在 web/package.json 中添加 workspace 依赖
Then 可以在 web/tests/e2e/ 中导入 Select 工具
And TypeScript 类型检查通过
And 运行时无依赖错误
实现要点:
pnpm add -D @d8d/e2e-test-utils@workspace:* 安装web/tests/e2e/ 中可以导入:import { selectRadixOption } from '@d8d/e2e-test-utils'作为测试开发者,
我想要使用 selectRadixOption() 替换 Page Object 中的 Select 操作,
以便验证工具在静态 Select 场景中的可用性。
验收标准:
Given @d8d/e2e-test-utils 已安装
When 修改 web/tests/e2e/pages/admin/disability-person.page.ts
Then fillBasicForm() 中的残疾类型选择使用 selectRadixOption()
And fillBasicForm() 中的残疾等级选择使用 selectRadixOption()
And 移除原有的 selectRadixOption() 方法
And 测试通过,功能正常
验证场景:
作为测试开发者,
我想要使用 selectRadixOptionAsync() 处理异步加载的 Select,
以便验证工具在异步 Select 场景中的可用性。
验收标准:
Given @d8d/e2e-test-utils 已安装
When 修改 web/tests/e2e/pages/admin/disability-person.page.ts
Then fillBasicForm() 中的省份选择使用 selectRadixOptionAsync()
And fillBasicForm() 中的城市选择使用 selectRadixOptionAsync()
And 移除 waitForTimeout(500) 等待城市加载的 hack
And 测试通过,功能正常
验证场景:
配置要点:
waitForOption: true 等待选项加载作为测试开发者, 我想要运行使用新工具的测试并收集反馈, 以便发现潜在问题并改进工具。
验收标准:
web/tests/e2e/specs/admin/disability-person-complete.spec.ts关注点:
作为测试开发者, 我想要修复 Story 2.4 中发现的问题, 以便工具可以正常使用。
验收标准:
优先级:
作为测试开发者, 我想要验证测试的稳定性, 以便确保工具可以可靠地使用。
验收标准:
Given 所有问题已修复 When 连续运行测试 10 次 Then 所有测试 100% 通过 And 无 flaky 失败 And 平均执行时间 < 5 分钟
测试场景:
pnpm test:e2e:chromium disability-person-complete.spec.ts 运行 10 次成功标准:
Epic 2 状态: ✅ Done
回顾文档: _bmad-output/implementation-artifacts/epic-2-retrospective.md
目标: 遵循 Epic 2 的成功模式,开发文件上传工具并在 web/tests/e2e/ 的真实测试中验证,解决当前测试超时阻塞问题。
背景:
范围:
uploadFileToField()web/tests/e2e/ 中验证工具模式: 工具开发 → 真实 E2E 测试验证 → 问题修复 → 稳定性验证
依赖:
验收标准:
作为测试开发者,
我想要使用 uploadFileToField() 函数上传文件,
以便测试照片上传、文档上传等功能。
验收标准:
Given Epic 1 的类型定义已存在
When 实现 src/file-upload.ts 中的 uploadFileToField(page, selector, fileName) 函数
Then 函数从 fixtures 目录加载测试文件
And 使用 Playwright 的 setInputFiles() API
And 支持相对路径(相对于 fixtures 目录)
And 错误时提供清晰消息(文件路径、选择器、失败原因)
And 操作在 5 秒内完成(NFR9)
And 配置对象继承 BaseOptions
函数签名:
export async function uploadFileToField(
page: Page,
selector: string,
fileName: string,
options?: FileUploadOptions
): Promise<void>
export interface FileUploadOptions extends BaseOptions {
/** fixtures 目录路径,默认为 'tests/fixtures' */
fixturesDir?: string;
/** 是否等待上传完成,默认为 true */
waitForUpload?: boolean;
}
参考架构决策:
docs/standards/e2e-radix-testing.md 中的文件上传规范DEFAULT_TIMEOUTS 常量定义超时E2ETestError 和 ErrorContext作为测试开发者, 我想要文件上传工具有充分的单元测试, 以便确保函数的正确性和稳定性。
验收标准:
Given 文件上传工具函数已实现
When 创建 tests/unit/file-upload.test.ts
Then 测试覆盖率 ≥ 80%(NFR29)
And 测试用例包括:成功上传、文件不存在、选择器无效、超时
And 使用 Vitest 运行测试
And 所有测试通过
⚠️ Epic 2 关键经验应用:
作为测试开发者,
我想要在 web/tests/e2e/ 的残疾人管理测试中使用文件上传工具,
以便验证工具在真实场景中的可用性。
验收标准:
Given 文件上传工具和单元测试已完成
When 在 web/tests/e2e/specs/admin/disability-person-complete.spec.ts 中使用工具
Then 至少迁移 3 处文件上传操作(身份证照片、残疾证照片)
And 移除原有的自定义文件上传方法
And 测试在真实浏览器中通过
And 无测试超时问题
验证场景:
参考 Epic 2.2-2.3 的迁移模式:
作为测试开发者, 我想要运行使用文件上传工具的测试并收集反馈, 以便发现潜在问题并改进工具。
验收标准:
Given 文件上传工具已在真实测试中使用 When 运行完整的 E2E 测试套件 Then 记录所有问题(失败的测试、错误消息、使用体验) Then 分类问题:工具 bug vs 使用错误 vs 改进建议 And 所有标记为"工具 bug"的问题已修复 And 测试连续运行 5 次通过 And 无 flaky 失败
优先级:
作为测试开发者,
我想要 uploadFileToField() 函数支持一次上传多个文件,
以便测试前端 <input type="file" multiple> 的多文件选择功能。
验收标准:
Given uploadFileToField() 函数已实现(单文件上传)
When 扩展函数支持多文件上传
Then 函数接受文件名数组或字符串
And 使用 Playwright 的 setInputFiles([path1, path2, ...]) API
And 支持相对路径数组(相对于 fixtures 目录)
And 错误时提供清晰消息(包含所有文件路径)
And 保持向后兼容(单文件上传仍然工作)
函数签名扩展:
// 支持单文件(向后兼容)
uploadFileToField(page, selector, fileName, options?): Promise<void>
// 支持多文件
uploadFileToField(page, selector, fileNames: string[], options?): Promise<void>
实现要点:
setInputFiles(filePathArray)测试用例:
作为测试开发者, 我想要验证文件上传工具的稳定性, 以便确保工具可以可靠地使用。
验收标准:
Given 所有问题已修复 When 连续运行文件上传相关测试 10 次 Then 所有测试 100% 通过 And 无超时失败 And 平均执行时间 ≤ 5 秒/文件
测试场景:
pnpm test:e2e:chromium disability-person-complete.spec.ts 运行 10 次成功标准:
Epic 3 回顾:
目标: 开发表单辅助工具并在 web/tests/e2e/ 的真实测试中验证。
说明: 遵循 Epic 2 和 Epic 3 的成功模式。
依赖: Epic 3 完成
模式: 工具开发 → 真实 E2E 测试验证 → 稳定性验证
作为测试开发者,
我想要使用 fillMultiStepForm() 和 scrollToSection() 函数,
以便测试多步骤表单和滚动操作。
验收标准:
Given 类型定义已存在
When 实现 src/form-helper.ts 中的表单辅助函数
Then fillMultiStepForm(page, steps) 支持分步填写表单
And scrollToSection(page, sectionName) 滚动到特定区域
And 支持常见字段类型(文本、选择器、日期等)
And 自动处理表单验证错误场景
作为测试开发者, 我想要表单工具有充分的单元测试, 以便确保函数的正确性和稳定性。
验收标准:
Given 表单辅助工具函数已实现
When 创建 tests/unit/form-helper.test.ts
Then 测试覆盖率 ≥ 80%(NFR29)
And 测试用例包括:成功填写、滚动操作、验证错误等
And 使用 Vitest 运行测试
And 所有测试通过
作为测试开发者, 我想要在残疾人管理测试中使用表单辅助工具, 以便验证工具在真实场景中的可用性。
验收标准:
Given 表单工具和单元测试已完成 When 在残疾人管理测试中使用工具 Then 验证多步骤表单填写 And 验证滚动操作 And 测试在真实浏览器中通过
作为测试开发者, 我想要验证表单工具的稳定性, 以便确保工具可以可靠地使用。
验收标准:
Given 所有问题已修复 When 连续运行表单相关测试 10 次 Then 所有测试 100% 通过
目标: 开发动态列表和对话框工具并在 web/tests/e2e/ 的真实测试中验证。
说明: 遵循 Epic 2-4 的成功模式。
依赖: Epic 4 完成
模式: 工具开发 → 真实 E2E 测试验证 → 稳定性验证
作为测试开发者,
我想要使用 addDynamicListItem()、deleteDynamicListItem() 和对话框工具,
以便测试银行卡管理、备注管理等动态列表功能。
验收标准:
Given 类型定义已存在
When 实现 src/dynamic-list.ts 和 src/dialog.ts 中的函数
Then addDynamicListItem(page, itemType, data) 添加新列表项
And deleteDynamicListItem(page, itemType, index) 删除指定索引的项
And handleDialog(page, action) 支持 confirm/cancel/close 操作
And waitForDialogClosed(page) 等待对话框完全关闭
And 支持不同类型列表项(银行卡、备注等)
作为测试开发者, 我想要列表和对话框工具有充分的单元测试, 以便确保函数的正确性和稳定性。
验收标准:
Given 列表和对话框工具函数已实现
When 创建 tests/unit/dynamic-list.test.ts 和 dialog.test.ts
Then 测试覆盖率 ≥ 80%(NFR29)
And 测试用例包括:添加、删除、打开/关闭对话框等
And 使用 Vitest 运行测试
And 所有测试通过
作为测试开发者, 我想要在残疾人管理测试中使用列表和对话框工具, 以便验证工具在真实场景中的可用性。
验收标准:
Given 列表和对话框工具及单元测试已完成 When 在残疾人管理测试中使用工具 Then 验证银行卡管理(添加、删除) And 验证备注管理 And 测试在真实浏览器中通过
作为测试开发者, 我想要验证列表和对话框工具的稳定性, 以便确保工具可以可靠地使用。
验收标准:
Given 所有问题已修复 When 连续运行列表和对话框相关测试 10 次 Then 所有测试 100% 通过
目标: 工具包在真实的残疾人管理 E2E 测试中完整验证,证明所有工具函数可用且稳定。
依赖: Epic 5 完成
作为测试开发者, 我想要在残疾人管理完整流程测试中使用所有工具, 以便演示所有工具函数的综合使用。
验收标准:
Given Epic 1-5 的所有工具已实现并验证
When 确保 disability-person-complete.spec.ts 使用所有工具
Then 基本信息:使用 selectRadixOption 和 selectRadixOptionAsync
And 照片上传:使用 uploadFileToField (来自 Epic 3)
And 表单操作:使用 fillMultiStepForm, scrollToSection (来自 Epic 4)
And 银行卡管理:使用 handleDialog, addDynamicListItem, deleteDynamicListItem (来自 Epic 5)
And 备注添加:使用 addDynamicListItem (来自 Epic 5)
And 所有测试通过
作为测试开发者, 我想要有稳定性测试验证工具包的可靠性, 以便确保工具函数连续运行 20 次 100% 通过。
验收标准:
Given 完整流程测试已编写 When 创建稳定性测试或运行现有测试 20 次 Then 测试连续运行 20 次完整流程 And 验证 100% 通过率(NFR1) And 测试执行时间符合性能标准(NFR8-NFR11) And 无 flaky 失败 And 使用 Playwright 运行稳定性测试
目标: 测试开发者可以在 30 分钟内上手使用工具包,有完整的文档、示例和迁移指南。
依赖: Epic 6 完成
作为测试开发者, 我想要有完整的 README 和 API 文档, 以便快速上手使用工具包。
验收标准:
Given Epic 1-6 的所有功能已实现
When 完善 README.md 和 API 文档
Then README 包含:项目简介、安装说明、快速入门、API 文档
And 每个工具函数都有完整的使用示例
And 说明静态 Select 和异步 Select 的区别和使用场景
And 包含迁移指南(从现有测试代码到工具函数)
And 包含常见问题和解决方案
And 残疾人管理测试作为完整示例
And 所有函数有完整的 JSDoc 注释
作为测试开发者, 我想要有 VS Code 代码片段, 以便加速测试开发。
验收标准:
Given README 和 API 文档已完成 When 创建 VS Code snippets 配置 Then 提供常用代码片段(selectRadixOption, uploadFileToField 等) And 片段有清晰的触发词和描述 And 文档说明如何安装和使用 snippets And 开发者可以在 30 分钟内使用工具包编写第一个测试
目标: 测试开发者可以为区域管理功能编写完整的 E2E 测试,验证省/市/区/街道的添加、编辑、删除和级联选择功能。
业务分组: Epic B(业务测试 Epic)
背景:
范围:
模式: 业务测试为主,工具包支持为辅(遵循 Epic A 成功模式)
依赖:
验收标准:
交付物:
FRs covered: FR1-FR50(复用现有工具,必要时扩展)
作为测试开发者, 我想要创建区域管理的 Page Object, 以便组织区域管理相关的页面元素和操作。
验收标准:
Given Epic 2 的 Page Object 模式已验证
When 创建 web/tests/e2e/pages/admin/region-management.page.ts
Then 定义区域列表页面的选择器和操作方法
And 定义添加区域对话框的选择器和操作方法
And 定义编辑区域对话框的选择器和操作方法
And 遵循现有 Page Object 设计模式
And 所有方法有完整的 TypeScript 类型定义
参考:
web/tests/e2e/pages/admin/disability-person.page.ts 作为参考作为测试开发者, 我想要编写区域列表查看的 E2E 测试, 以便验证区域列表的基本功能和数据展示。
验收标准:
Given 区域管理 Page Object 已创建 When 编写区域列表查看测试用例 Then 验证区域列表按预期加载 And 验证区域数据的正确展示(名称、层级、状态等) And 验证分页功能(如适用) And 验证搜索功能(如适用) And 测试在真实浏览器中通过
作为测试开发者, 我想要编写添加区域的 E2E 测试, 以便验证省/市/区/街道的添加功能。
验收标准:
Given 区域列表查看测试已通过
When 编写添加区域测试用例
Then 验证添加省级区域的流程
And 验证添加市级区域的流程(需选择父级省份)
And 验证添加区级区域的流程(需选择父级城市)
And 验证添加街道级区域的流程(需选择父级区域)
And 使用 selectRadixOption 或 selectRadixOptionAsync 选择父级区域
And 验证添加成功后列表中显示新区域
And 测试在真实浏览器中通过
级联选择测试点:
作为测试开发者, 我想要编写编辑区域的 E2E 测试, 以便验证区域信息的修改功能。
验收标准:
Given 添加区域测试已通过 When 编写编辑区域测试用例 Then 验证编辑区域名称的流程 And 验证修改区域状态的流程(如启用/禁用) And 验证编辑后列表中正确显示更新后的信息 And 验证必填字段的验证规则 And 测试在真实浏览器中通过
作为测试开发者, 我想要编写删除区域的 E2E 测试, 以便验证区域的删除功能和相关约束。
验收标准:
Given 编辑区域测试已通过 When 编写删除区域测试用例 Then 验证删除无子级区域的流程 And 验证删除有子级区域时的错误提示 And 验证删除确认对话框的正确操作 And 验证删除成功后列表中不再显示该区域 And 测试在真实浏览器中通过
作为测试开发者, 我想要编写完整的四级级联选择测试, 以便验证省/市/区/街道联动的完整场景。
验收标准:
Given 单独的区域操作测试已通过 When 编写完整的级联选择流程测试 Then 从选择省份开始,依次选择市、区、街道 And 验证每级选择后,下一级选项正确加载 And 验证上级变更时,下级选择被清空 And 验证完整的添加流程(省份→城市→区域→街道) And 测试在真实浏览器中通过
工具需求评估:
selectRadixOptionAsync 是否满足需求作为测试开发者, 我想要运行区域管理测试并收集反馈, 以便发现潜在问题并改进测试或工具。
验收标准:
Given 所有区域管理测试用例已编写 When 运行完整的区域管理 E2E 测试套件 Then 记录所有问题(失败的测试、错误消息、使用体验) Then 分类问题:业务逻辑 bug vs 测试代码问题 vs 工具不足 And 整理成问题清单 And 识别是否需要扩展 e2e-test-utils 工具包
关注点:
作为测试开发者, 我想要根据 Story 8.7 的发现扩展 e2e-test-utils 工具包, 以便更好地支持区域管理等业务模块的测试。
验收标准:
Given Story 8.7 已识别工具扩展需求
When 实现必要的工具扩展
Then 如需级联选择工具:实现 selectCascadeOptions() 函数
And 如需树形结构工具:实现 selectTreeNode() 函数
And 编写工具函数的单元测试
And 在区域管理测试中验证新工具
And 更新工具包文档
可能的工具扩展:
// 级联选择工具(示例)
export async function selectCascadeOptions(
page: Page,
levels: Array<{label: string, value: string}>
): Promise<void>
// 树形结构选择工具(示例)
export async function selectTreeNode(
page: Page,
treeLabel: string,
nodePath: string[]
): Promise<void>
依赖:
作为测试开发者, 我想要验证区域管理测试的稳定性, 以便确保测试可以可靠地使用。
验收标准:
Given 所有问题已修复(包括工具扩展) When 连续运行区域管理相关测试 10 次 Then 所有测试 100% 通过 And 无 flaky 失败 And 平均执行时间符合预期
测试场景:
pnpm test:e2e:chromium region-management.spec.ts 运行 10 次成功标准:
Epic 8 回顾:
目标: 为残疾人管理功能编写完整的、真正验证业务功能的 E2E 测试,并确保测试可以与未来的区域管理测试并行运行。
背景:
disability-person-complete.spec.ts 只是组件验证,没有真正测试业务功能范围:
模式: 业务测试优先,工具按需扩展(遵循新 PRD 方向)
依赖:
验收标准:
FRs covered: FR7-FR10(文件上传)、FR41-FR45(测试质量和稳定性)
业务功能覆盖清单:
| 业务功能 | 当前状态 | 目标状态 | 测试场景数 |
|---|---|---|---|
| 照片上传 | 组件验证 | 真实上传测试 | 5 |
| 银行卡管理 | 组件验证 | 增删改查测试 | 4 |
| 备注管理 | 组件验证 | 增删改测试 | 3 |
| 回访记录管理 | 组件验证 | 增删改查测试 | 4 |
| 残疾人信息 | 基础测试 | 完整 CRUD | 6 |
| 完整流程 | 组件验证 | 端到端测试 | 3 |
| 并行隔离 | 未验证 | 验证通过 | 1 |
总计: 26 个测试场景
作为测试开发者, 我想要编写照片上传功能的完整测试, 以便验证照片上传的真实业务逻辑。
验收标准:
Given 文件上传工具 (Epic 3) 已完成 When 编写照片上传功能测试 Then 包含以下测试场景:
单张照片上传
多张照片上传
照片格式支持
照片删除
照片大小限制
测试文件: web/tests/e2e/specs/admin/disability-person-photo.spec.ts
作为测试开发者, 我想要编写银行卡管理功能的测试, 以便验证银行卡的添加、编辑、删除功能。
验收标准:
Given 残疾人管理 Page Object 已存在 When 编写银行卡管理测试 Then 包含以下测试场景:
添加银行卡
编辑银行卡
删除银行卡
多张银行卡管理
测试文件: web/tests/e2e/specs/admin/disability-person-bankcard.spec.ts
作为测试开发者, 我想要编写备注管理功能的测试, 以便验证备注的添加、修改、删除功能。
验收标准:
Given 残疾人管理 Page Object 已存在 When 编写备注管理测试 Then 包含以下测试场景:
添加备注
修改备注
删除备注
测试文件: web/tests/e2e/specs/admin/disability-person-note.spec.ts
作为测试开发者, 我想要编写回访记录管理的测试, 以便验证回访记录的创建、查看、编辑功能。
验收标准:
Given 残疾人管理 Page Object 已存在 When 编写回访记录测试 Then 包含以下测试场景:
创建回访记录
查看回访历史
编辑回访记录
回访记录状态管理
测试文件: web/tests/e2e/specs/admin/disability-person-visit.spec.ts
作为测试开发者, 我想要编写残疾人信息的完整 CRUD 测试, 以便验证整个业务流程的正确性。
验收标准:
Given 所有子功能测试已完成 When 编写完整流程测试 Then 包含以下测试场景:
新增残疾人完整流程
编辑残疾人信息
删除残疾人
查看残疾人详情
列表查询与筛选
数据导出
测试文件: web/tests/e2e/specs/admin/disability-person-crud.spec.ts
作为测试开发者, 我想要确保测试隔离和并行执行, 以便残疾人管理和区域管理测试可以同时运行。
验收标准:
Given 所有业务测试已完成 When 验证测试隔离和并行执行 Then 包含以下验证:
数据隔离策略
并行执行验证
测试顺序独立性
测试隔离示例:
test.beforeEach(async ({ adminLoginPage, disabilityPersonPage }) => {
// 登录(全局状态,需谨慎)
await adminLoginPage.goto();
await adminLoginPage.login('admin', 'admin123');
});
test.afterEach(async ({ disabilityPersonPage }) => {
// 清理测试数据
await disabilityPersonPage.deleteTestData();
});
test('应该成功创建残疾人', async ({ disabilityPersonPage }) => {
// 使用时间戳确保数据唯一
const timestamp = Date.now();
const uniqueId = `test_${timestamp}`;
await disabilityPersonPage.create({
name: uniqueId,
idCard: generateUniqueIdCard(timestamp),
// ...
});
});
验证命令:
# 并行运行测试(使用 4 个 worker)
cd web
pnpm test:e2e:chromium --workers=4
# 验证测试顺序独立
pnpm test:e2e:chromium --shuffle
作为测试开发者, 我想要验证所有测试的稳定性, 以便确保测试可以可靠地运行。
验收标准:
Given 所有业务测试已完成并隔离 When 连续运行测试 10 次 Then 验收标准如下:
测试通过率 100%
性能指标达标
并行执行稳定
稳定性测试脚本:
#!/bin/bash
# run-stability-test.sh
PASSED=0
FAILED=0
TIMES=()
for i in {1..10}; do
echo "=== 运行 #$i ==="
START=$(date +%s)
if pnpm test:e2e:chromium --workers=4; then
PASSED=$((PASSED + 1))
echo "✅ 运行 #$i 通过"
else
FAILED=$((FAILED + 1))
echo "❌ 运行 #$i 失败"
fi
END=$(date +%s)
DURATION=$((END - START))
TIMES+=($DURATION)
echo "⏱️ 耗时: ${DURATION}s"
echo ""
done
echo "=== 稳定性测试结果 ==="
echo "通过: $PASSED/10"
echo "失败: $FAILED/10"
echo "平均时间: $(awk '{sum+=$1} END {print sum/NR}' <<< "${TIMES[@]}")s"
if [ $PASSED -eq 10 ]; then
echo "✅ 100% 稳定性通过!"
exit 0
else
echo "❌ 稳定性不足,需要修复"
exit 1
fi
成功标准:
Epic 9 回顾:
目标: 测试开发者可以为订单管理功能编写完整的 E2E 测试,验证订单的 CRUD、状态流转、人员关联和附件管理功能。
业务分组: Epic C(业务测试 Epic)
背景:
范围:
模式: 业务测试为主,工具包支持为辅(遵循 Epic A 成功模式)
依赖:
验收标准:
交付物:
FRs covered: FR1-FR50(复用现有工具,必要时扩展)
业务功能覆盖清单:
| 业务功能 | 测试场景数 | 描述 |
|---|---|---|
| 订单列表 | 4 | 查看、搜索、筛选、分页 |
| 创建订单 | 3 | 基本创建、多选择器、复杂表单 |
| 编辑订单 | 2 | 基本编辑、状态变更 |
| 删除订单 | 2 | 直接删除、级联删除验证 |
| 订单详情 | 2 | 基本详情、完整信息展示 |
| 状态流转 | 3 | 激活订单、关闭订单、状态限制 |
| 人员关联 | 3 | 添加人员、管理工作状态、人员列表 |
| 附件管理 | 2 | 添加附件、附件验证 |
| 完整流程 | 2 | 新增完整流程、编辑完整流程 |
总计: 23 个测试场景
作为测试开发者, 我想要创建订单管理的 Page Object, 以便组织订单管理相关的页面元素和操作。
验收标准:
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 作为参考作为测试开发者, 我想要编写订单列表查看的 E2E 测试, 以便验证订单列表的基本功能和数据展示。
验收标准:
Given 订单管理 Page Object 已创建 When 编写订单列表查看测试用例 Then 验证订单列表按预期加载 And 验证订单数据的正确展示(订单名称、平台、公司、渠道、状态等) And 验证订单状态徽章显示正确(草稿、已确认、进行中等) And 验证工作状态徽章显示正确(未就业、待就业、已就业、已离职) And 验证分页功能 And 测试在真实浏览器中通过
测试文件: web/tests/e2e/specs/admin/order-list.spec.ts
作为测试开发者, 我想要编写订单搜索和筛选的 E2E 测试, 以便验证多维度搜索和筛选功能。
验收标准:
Given 订单列表 Page Object 已创建 When 编写搜索和筛选测试用例 Then 包含以下测试场景:
订单名称搜索
订单状态筛选
工作状态筛选
平台筛选
selectRadixOption 或 selectRadixOptionAsync公司筛选
渠道筛选
日期范围筛选
重置筛选
测试文件: web/tests/e2e/specs/admin/order-filter.spec.ts
作为测试开发者, 我想要编写创建订单的 E2E 测试, 以便验证订单创建功能。
验收标准:
Given 订单管理 Page Object 已创建 When 编写创建订单测试用例 Then 包含以下测试场景:
基本创建订单
创建订单并选择平台
selectRadixOption 或 selectRadixOptionAsync创建订单并选择公司
创建订单并选择渠道
创建完整订单(所有字段)
表单验证测试
测试文件: web/tests/e2e/specs/admin/order-create.spec.ts
作为测试开发者, 我想要编写编辑订单的 E2E 测试, 以便验证订单编辑功能。
验收标准:
Given 创建订单测试已通过 When 编写编辑订单测试用例 Then 包含以下测试场景:
编辑订单基本信息
编辑订单关联信息
编辑后验证列表更新
测试文件: web/tests/e2e/specs/admin/order-edit.spec.ts
作为测试开发者, 我想要编写删除订单的 E2E 测试, 以便验证订单删除功能和相关约束。
验收标准:
Given 编辑订单测试已通过 When 编写删除订单测试用例 Then 包含以下测试场景:
删除草稿状态订单
删除有关联人员的订单
取消删除
测试文件: web/tests/e2e/specs/admin/order-delete.spec.ts
作为测试开发者, 我想要编写订单状态流转的 E2E 测试, 以便验证激活和关闭订单的功能。
验收标准:
Given 订单 CRUD 测试已通过 When 编写订单状态流转测试用例 Then 包含以下测试场景:
激活草稿订单
关闭进行中订单
状态限制验证
测试文件: web/tests/e2e/specs/admin/order-status.spec.ts
作为测试开发者, 我想要编写查看订单详情的 E2E 测试, 以便验证订单详情页面的完整信息展示。
验收标准:
Given 订单管理 Page Object 已创建 When 编写订单详情查看测试用例 Then 包含以下测试场景:
查看基本订单详情
查看订单人员列表
查看订单附件
测试文件: web/tests/e2e/specs/admin/order-detail.spec.ts
作为测试开发者, 我想要编写人员关联功能的 E2E 测试, 以便验证添加人员到订单和管理工作状态的功能。
验收标准:
Given 订单管理 Page Object 已创建 When 编写人员关联测试用例 Then 包含以下测试场景:
添加人员到订单
管理工作状态
设置实际入职日期
人员离职
测试文件: web/tests/e2e/specs/admin/order-person.spec.ts
作为测试开发者, 我想要编写订单附件管理的 E2E 测试, 以便验证添加订单附件的功能。
验收标准:
Given 订单管理 Page Object 已创建 When 编写附件管理测试用例 Then 包含以下测试场景:
为订单添加附件
附件文件格式验证
测试文件: web/tests/e2e/specs/admin/order-attachment.spec.ts
作为测试开发者, 我想要编写订单管理的完整流程 E2E 测试, 以便验证从创建到关闭的端到端场景。
验收标准:
Given 所有子功能测试已完成 When 编写完整流程测试 Then 包含以下测试场景:
新增订单完整流程
编辑订单完整流程
测试文件: web/tests/e2e/specs/admin/order-complete.spec.ts
作为测试开发者, 我想要运行订单管理测试并收集反馈, 以便发现潜在问题并改进测试或工具。
验收标准:
Given 所有订单管理测试用例已编写 When 运行完整的订单管理 E2E 测试套件 Then 记录所有问题(失败的测试、错误消息、使用体验) Then 分类问题:业务逻辑 bug vs 测试代码问题 vs 工具不足 And 整理成问题清单 And 识别是否需要扩展 e2e-test-utils 工具包
关注点:
作为测试开发者, 我想要根据 Story 10.12 的发现扩展 e2e-test-utils 工具包, 以便更好地支持订单管理等复杂业务模块的测试。
验收标准:
Given Story 10.12 已识别工具扩展需求
When 实现必要的工具扩展
Then 如需复杂表单提交工具:实现 fillComplexForm() 函数
And 如需状态流转测试工具:实现 transitionOrderStatus() 函数
And 如需资产附件工具:实现 attachAssetToOrder() 函数
And 编写工具函数的单元测试
And 在订单管理测试中验证新工具
And 更新工具包文档
可能的工具扩展:
// 复杂表单提交工具(示例)
export async function fillComplexForm(
page: Page,
fields: Record<string, any>
): Promise<void>
// 状态流转测试工具(示例)
export async function transitionOrderStatus(
page: Page,
fromStatus: string,
toStatus: string
): Promise<void>
// 资产附件操作工具(示例)
export async function attachAssetToOrder(
page: Page,
orderId: string,
assetFile: string
): Promise<void>
依赖:
作为测试开发者, 我想要验证订单管理测试的稳定性, 以便确保测试可以可靠地使用。
验收标准:
Given 所有问题已修复(包括工具扩展) When 连续运行订单管理相关测试 10 次 Then 所有测试 100% 通过 And 无 flaky 失败 And 平均执行时间符合预期
测试场景:
pnpm test:e2e:chromium order-*.spec.ts 运行 10 次成功标准:
Epic 10 回顾:
目标: 为平台、公司、渠道配置管理编写 E2E 测试,为后续用户管理和跨端测试提供必要的测试数据。
状态: 🆕 Backlog
背景:
实体关系链:
Platform (平台)
↓ 1:N
Company (公司) - 必须 platformId
↓ 1:N
Order (订单) - 必须 companyId
交付物:
Story 列表:
Epic 11 回顾:
目标: 为用户管理和小程序登录编写 E2E 测试,解锁小程序端的测试能力。
状态: 🆕 Backlog
依赖: Epic 11 完成(需要 Company 数据)
背景:
/mini 和 /talent-mini)交付物:
Story 列表:
技术要点:
http://localhost:8080/mini 和 /talent-miniEpic 12 回顾:
目标: 验证后台操作后小程序端的数据同步,覆盖完整的业务流程。
状态: 🆕 Backlog
依赖: Epic 10(订单管理)和 Epic 12(小程序登录)完成
背景:
交付物:
Story 列表:
技术要点:
/mini-ws、/talent-mini-ws)Epic 13 回顾: