Status: done
作为测试开发者, 我想要可以导入工具函数并查看快速入门文档, 以便快速开始使用工具包。
Given Select 工具函数已实现(Story 1.3、1.4 完成)
When 创建/更新 src/index.ts 和 README.md
Then index.ts 导出所有公共函数和类型(tree-shakeable)
And README 包含:安装说明、快速入门、Select 使用示例
And README 说明静态 Select 和异步 Select 的区别和使用场景
And 所有导出函数有完整的 JSDoc 注释(已在 Story 1.3、1.4 完成)
And 可以 import { selectRadixOption } from '@d8d/e2e-test-utils'
src/index.ts 导出结构 (AC: 1)
README.md 添加 Select 工具使用文档 (AC: 2, 3, 4)
selectRadixOption 完整说明selectRadixOptionAsync 完整说明import { selectRadixOption } from '@d8d/e2e-test-utils' 可用Epic 1 目标: 测试开发者可以安装 @d8d/e2e-test-utils 包,立即使用 Select 工具测试 Radix UI Select 组件。
本故事在 Epic 中的位置: 第五个故事,完成主导出文档和 README,使工具包可以被外部项目使用和理解。
已完成的工作(Story 1.1-1.4):
Story 1.1 - 包基础结构
package.json 配置(peer dependencies: @playwright/test)tsconfig.json 严格模式配置vitest.config.ts 测试配置Story 1.2 - 类型定义和错误处理
src/types.ts - BaseOptions, AsyncSelectOptions, ErrorContextsrc/errors.ts - E2ETestError 类src/constants.ts - DEFAULT_TIMEOUTS, SELECTOR_STRATEGIESStory 1.3 - 静态 Select 工具
selectRadixOption(page, label, value) 函数Story 1.4 - 异步 Select 工具
selectRadixOptionAsync(page, label, value, options?) 函数当前 src/index.ts 状态:
// 当前使用显式导出(正确,支持 tree-shaking)
export {
selectRadixOption,
selectRadixOptionAsync
} from './radix-select';
// 通配符导出类型(也正确)
export * from './types';
export * from './errors';
export * from './constants';
当前 README.md 状态:
任务 1:审查 index.ts 导出结构
当前导出结构已经正确:
可能需要的改进(可选):
任务 2:更新 README.md 添加 Select 工具文档
需要在 README 中添加以下内容:
从架构文档中必须遵循的决策:
文档结构需求(Architecture - Documentation Requirements):
Tree-shaking 需求(Architecture - Bundle Optimization):
API 文档标准(Architecture - API Documentation):
src/index.ts 审查指南:
当前导出结构(已正确):
/**
* @d8d/e2e-test-utils
*
* E2E 测试工具集 - 专门用于测试 Radix UI 组件的 Playwright 工具函数
*
* @packageDocumentation
*/
// 导出类型定义(通配符导出可以,类型不增加运行时开销)
export * from './types';
// 导出错误类(通配符导出可以)
export * from './errors';
// 导出常量(通配符导出可以)
export * from './constants';
// Radix UI Select 工具(显式导出,支持 tree-shaking)
export {
selectRadixOption,
selectRadixOptionAsync
} from './radix-select';
审查清单:
export * from './radix-select')无需修改当前结构,除非发现以下问题:
export * from './radix-select',需要改为显式导出README.md 创建指南:
必须包含的章节:
项目简介(1-2 段话)
安装说明
# 使用 pnpm workspace 协议(Monorepo 内)
pnpm add -D @d8d/e2e-test-utils@workspace:*
# 使用 npm(发布后)
npm install --save-dev @d8d/e2e-test-utils
快速入门(本故事核心任务)
import { selectRadixOption, selectRadixOptionAsync } from '@d8d/e2e-test-utils';
// 静态 Select 示例
await selectRadixOption(page, '残疾类型', '视力残疾');
// 异步 Select 示例
await selectRadixOptionAsync(page, '省份', '广东省');
API 文档(本故事核心任务)
selectRadixOption - 静态 Select 工具selectRadixOptionAsync - 异步 Select 工具静态 vs 异步 Select(本故事核心任务)
类型定义(已存在,保持)
错误处理(已存在,保持)
常量(已存在,保持)
Story 1.4 已完成的工作:
selectRadixOption() 已实现并导出selectRadixOptionAsync() 已实现并导出本故事需要做的:
src/index.ts 导出结构正确(可能无需修改)README.md 添加 Select 工具使用文档和示例从 Story 1.3、1.4 中学习到的经验:
JSDoc 注释标准:
@description 标签添加详细描述@param 标签说明每个参数@throws 标签说明可能抛出的错误@example 标签提供实际使用示例错误处理模式:
E2ETestError 类提供结构化错误信息选择器策略:
data-testid → aria-label + role → text contentdata-testid 属性| 特性 | 静态 Select (selectRadixOption) |
异步 Select (selectRadixOptionAsync) |
|---|---|---|
| 选项加载时机 | 页面加载时已存在 DOM 中 | 点击触发器后 API 加载 |
| 使用场景 | 枚举类型(残疾类型、性别等) | 动态数据(省份、城市、银行等) |
| 等待策略 | 立即查找选项 | 等待网络请求 + 选项出现 |
| 默认超时 | 2000ms | 5000ms |
| 配置对象 | 无 | AsyncSelectOptions |
| 网络空闲等待 | 不需要 | 默认启用 |
| 函数签名 | selectRadixOption(page, label, value) |
selectRadixOptionAsync(page, label, value, options?) |
选择建议:
selectRadixOption()selectRadixOptionAsync()快速入门章节建议内容:
## 快速入门
### 安装
\`\`\`bash
# Monorepo 内使用 workspace 协议
pnpm add -D @d8d/e2e-test-utils@workspace:*
# 或使用 npm(发布后)
npm install --save-dev @d8d/e2e-test-utils
\`\`\`
### 基本使用
\`\`\`typescript
import { selectRadixOption, selectRadixOptionAsync } from '@d8d/e2e-test-utils';
// 选择静态下拉框选项(如残疾类型)
await selectRadixOption(page, '残疾类型', '视力残疾');
// 选择异步加载的下拉框选项(如省份)
await selectRadixOptionAsync(page, '省份', '广东省');
\`\`\`
### 选择器策略
工具函数按以下优先级查找下拉框触发器:
1. `data-testid="标签-trigger"` - 推荐,最稳定
2. `aria-label="标签"` + `role="combobox"` - 无障碍属性
3. `text="标签"` - 文本匹配(兜底)
**推荐做法:** 在测试代码或应用中为 Radix Select 添加 `data-testid` 属性。
API 文档章节建议内容:
## API 文档
### selectRadixOption()
选择静态枚举型 Radix UI Select 选项。
**函数签名:**
\`\`\`typescript
function selectRadixOption(
page: Page,
label: string,
value: string
): Promise<void>
\`\`\`
**参数:**
| 参数 | 类型 | 说明 |
|------|------|------|
| `page` | `Page` | Playwright Page 对象 |
| `label` | `string` | 下拉框的标签文本 |
| `value` | `string` | 要选择的选项值 |
**示例:**
\`\`\`typescript
// 选择残疾类型
await selectRadixOption(page, '残疾类型', '视力残疾');
// 选择性别
await selectRadixOption(page, '性别', '男');
\`\`\`
---
### selectRadixOptionAsync()
选择异步加载的 Radix UI Select 选项。
**函数签名:**
\`\`\`typescript
function selectRadixOptionAsync(
page: Page,
label: string,
value: string,
options?: AsyncSelectOptions
): Promise<void>
\`\`\`
**参数:**
| 参数 | 类型 | 说明 |
|------|------|------|
| `page` | `Page` | Playwright Page 对象 |
| `label` | `string` | 下拉框的标签文本 |
| `value` | `string` | 要选择的选项值 |
| `options` | `AsyncSelectOptions` | 可选配置对象 |
| `options.timeout` | `number` | 超时时间(毫秒),默认 5000 |
| `options.waitForOption` | `boolean` | 是否等待选项加载,默认 true |
| `options.waitForNetworkIdle` | `boolean` | 是否等待网络空闲,默认 true |
**示例:**
\`\`\`typescript
// 选择省份(使用默认配置)
await selectRadixOptionAsync(page, '省份', '广东省');
// 选择城市(自定义超时)
await selectRadixOptionAsync(page, '城市', '深圳市', {
timeout: 10000
});
// 禁用网络空闲等待(网络不稳定时)
await selectRadixOptionAsync(page, '地区', '华南', {
waitForNetworkIdle: false
});
\`\`\`
与项目标准对齐:
docs/standards/testing-standards.md 中的测试规范docs/standards/e2e-radix-testing.md 中的 Radix UI E2E 测试标准docs/standards/coding-standards.md 中的编码标准文档标准:
TypeScript 配置:
strict: true)从 NFR 提取的性能要求:
README 设计考虑:
必须遵循的文件结构:
packages/e2e-test-utils/
├── src/
│ ├── index.ts # 主导出(审查,可能无需修改)
│ ├── types.ts # 共享类型定义
│ ├── errors.ts # 错误类
│ ├── constants.ts # 常量定义
│ └── radix-select.ts # Radix UI Select 工具
├── README.md # 包文档(本故事创建)
├── package.json # 包配置
├── tsconfig.json # TypeScript 配置
└── vitest.config.ts # 测试配置
禁止事项(Anti-Patterns):
export default)文档验证方法:
import { selectRadixOption } from '@d8d/e2e-test-utils' 可用集成测试(在 Epic 3 中实现):
对齐项目 Monorepo 架构:
packages/e2e-test-utils/@d8d/e2e-test-utils@workspace:*@d8d/shared-test-util(后端集成测试)分离与项目标准对齐:
docs/standards/testing-standards.md 中的测试规范docs/standards/web-ui-testing-standards.md 中的 Web UI 测试规范docs/standards/e2e-radix-testing.md 中的 Radix UI E2E 测试标准(核心标准文档)PRD 来源:
Architecture 来源:
标准文档来源:
Epic 来源:
前一个故事:
Claude (d8d-model) via create-story workflow
实现完成 (2026-01-09):
src/index.ts 导出结构审查完成 - 无需修改,结构已正确selectRadixOption() 完整说明selectRadixOptionAsync() 完整说明代码审查完成 (2026-01-09):
src/index.ts:31 - 修复占位符 URLREADME.md:478 - 更新工具状态描述(radix-select.ts 已完成)README.md:145-170 - 修复 Fixtures 使用说明src/types.ts:82-145 - 为未实现类型添加 @beta 标签README.md - 添加 TypeScript 配置说明README.md:538-539 - 移除相对路径链接实现建议:
src/index.ts 当前结构已经正确,可能无需修改README.md 添加 Select 工具使用文档关键检查点:
src/index.ts 使用显式命名导出(支持 tree-shaking)本故事修改的文件:
packages/e2e-test-utils/README.md - 添加 Select 工具使用文档和静态 vs 异步 Select 对比说明审查但未修改的文件:
packages/e2e-test-utils/src/index.ts - 导出结构审查确认正确,无需修改相关文件(已在 Story 1.1-1.4 中完成,本故事使用):
packages/e2e-test-utils/src/radix-select.ts - Select 工具函数实现packages/e2e-test-utils/src/types.ts - 类型定义packages/e2e-test-utils/src/errors.ts - 错误类packages/e2e-test-utils/src/constants.ts - 常量定义只读参考文件:
_bmad-output/implementation-artifacts/1-3-static-select-tool.md - 静态 Select 实现_bmad-output/implementation-artifacts/1-4-async-select-tool.md - 异步 Select 实现_bmad-output/planning-artifacts/epics.md - Epic 和故事定义_bmad-output/planning-artifacts/architecture.md - 架构决策和模式docs/standards/e2e-radix-testing.md - E2E Radix UI 测试标准