|
@@ -0,0 +1,513 @@
|
|
|
|
|
+# Story 1.1: 创建包基础结构和配置
|
|
|
|
|
+
|
|
|
|
|
+Status: ready-for-dev
|
|
|
|
|
+
|
|
|
|
|
+<!-- Note: Validation is optional. Run validate-create-story for quality check before dev-story. -->
|
|
|
|
|
+
|
|
|
|
|
+## Story
|
|
|
|
|
+
|
|
|
|
|
+作为测试开发者,
|
|
|
|
|
+我想要可以安装 `@d8d/e2e-test-utils` 包,
|
|
|
|
|
+以便在项目中使用测试工具函数。
|
|
|
|
|
+
|
|
|
|
|
+## Acceptance Criteria
|
|
|
|
|
+
|
|
|
|
|
+**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:*` 安装
|
|
|
|
|
+
|
|
|
|
|
+## Tasks / Subtasks
|
|
|
|
|
+
|
|
|
|
|
+- [ ] 创建目录结构 (AC: 1)
|
|
|
|
|
+ - [ ] 创建 `packages/e2e-test-utils/` 根目录
|
|
|
|
|
+ - [ ] 创建 `src/` 源代码目录
|
|
|
|
|
+ - [ ] 创建 `tests/` 测试目录
|
|
|
|
|
+ - [ ] 创建 `tests/fixtures/` 测试资源目录
|
|
|
|
|
+ - [ ] 创建 `tests/unit/` 单元测试目录
|
|
|
|
|
+ - [ ] 创建 `tests/integration/` 集成测试目录
|
|
|
|
|
+ - [ ] 创建 `tests/stability/` 稳定性测试目录
|
|
|
|
|
+- [ ] 配置 package.json (AC: 2, 4)
|
|
|
|
|
+ - [ ] 设置包名 `@d8d/e2e-test-utils`
|
|
|
|
|
+ - [ ] 设置版本号 `1.0.0`
|
|
|
|
|
+ - [ ] 配置 peer dependency `@playwright/test`
|
|
|
|
|
+ - [ ] 配置开发依赖(TypeScript, Vitest)
|
|
|
|
|
+ - [ ] 添加必要的 scripts(build, dev, test, typecheck)
|
|
|
|
|
+ - [ ] 配置 exports 用于 tree-shaking
|
|
|
|
|
+- [ ] 配置 tsconfig.json (AC: 3)
|
|
|
|
|
+ - [ ] 启用严格模式(`strict: true`)
|
|
|
|
|
+ - [ ] 设置目标 ES2020+(`target: "ES2020"`)
|
|
|
|
|
+ - [ ] 配置模块系统(`module: "ESNext"`)
|
|
|
|
|
+ - [ ] 配置路径解析(`baseUrl: "."`, `paths`)
|
|
|
|
|
+- [ ] 配置 vitest.config.ts (AC: 1)
|
|
|
|
|
+ - [ ] 设置测试目录为 `tests/unit`
|
|
|
|
|
+ - [ ] 配置覆盖率目标 ≥80%
|
|
|
|
|
+ - [ ] 配置测试超时时间
|
|
|
|
|
+- [ ] 创建基础占位文件
|
|
|
|
|
+ - [ ] 创建 `src/index.ts` 导出入口
|
|
|
|
|
+ - [ ] 创建 `src/types.ts` 类型定义占位
|
|
|
|
|
+ - [ ] 创建 `src/errors.ts` 错误类占位
|
|
|
|
|
+ - [ ] 创建 `src/constants.ts` 常量占位
|
|
|
|
|
+ - [ ] 创建 `README.md` 基础文档
|
|
|
|
|
+- [ ] 验证包可被安装 (AC: 4)
|
|
|
|
|
+ - [ ] 在 monorepo 根目录运行 `pnpm install`
|
|
|
|
|
+ - [ ] 验证包可以被引用 `@d8d/e2e-test-utils@workspace:*`
|
|
|
|
|
+ - [ ] 运行 `pnpm typecheck` 验证类型检查通过
|
|
|
|
|
+
|
|
|
|
|
+## Dev Notes
|
|
|
|
|
+
|
|
|
|
|
+### Epic 1 背景
|
|
|
|
|
+
|
|
|
|
|
+**Epic 1 目标:** 测试开发者可以安装 `@d8d/e2e-test-utils` 包,立即使用 Select 工具测试 Radix UI Select 组件(最常用、最关键的测试场景)。
|
|
|
|
|
+
|
|
|
|
|
+**本故事在 Epic 中的位置:** 第一个故事,建立包基础设施,为后续所有工具函数提供基础。
|
|
|
|
|
+
|
|
|
|
|
+### 相关架构决策
|
|
|
|
|
+
|
|
|
|
|
+从架构文档中提取的关键架构决策:
|
|
|
|
|
+
|
|
|
|
|
+**包结构决策(按功能分组):**
|
|
|
|
|
+```
|
|
|
|
|
+packages/e2e-test-utils/
|
|
|
|
|
+├── src/
|
|
|
|
|
+│ ├── index.ts # 主导出,tree-shakeable
|
|
|
|
|
+│ ├── types.ts # 共享类型定义
|
|
|
|
|
+│ ├── errors.ts # 错误类和错误处理
|
|
|
|
|
+│ ├── constants.ts # 常量定义(超时、选择器策略等)
|
|
|
|
|
+│ ├── radix-select.ts # Radix UI Select 工具(后续故事)
|
|
|
|
|
+│ ├── file-upload.ts # 文件上传工具(后续故事)
|
|
|
|
|
+│ ├── form-helper.ts # 表单辅助函数(后续故事)
|
|
|
|
|
+│ ├── dialog.ts # 对话框操作(后续故事)
|
|
|
|
|
+│ └── dynamic-list.ts # 动态列表管理(后续故事)
|
|
|
|
|
+├── tests/
|
|
|
|
|
+│ ├── fixtures/ # 测试资源
|
|
|
|
|
+│ ├── unit/ # Vitest 单元测试
|
|
|
|
|
+│ ├── integration/ # Playwright 集成测试
|
|
|
|
|
+│ └── stability/ # 稳定性测试
|
|
|
|
|
+├── package.json
|
|
|
|
|
+├── tsconfig.json
|
|
|
|
|
+├── vitest.config.ts
|
|
|
|
|
+└── README.md
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**API 设计模式:** 3个必需参数 + 可选配置对象
|
|
|
|
|
+- 必需参数 ≤ 3 个
|
|
|
|
|
+- 复杂配置通过可选对象传递
|
|
|
|
|
+- 类型推断友好
|
|
|
|
|
+- JSDoc 完整
|
|
|
|
|
+
|
|
|
|
|
+**类型系统策略:** 分层类型(共享+特定)
|
|
|
|
|
+- `types.ts` 存放共享类型(`BaseOptions`)
|
|
|
|
|
+- 各模块文件存放特定类型(如 `AsyncSelectOptions`)
|
|
|
|
|
+
|
|
|
|
|
+**选择器策略:** 混合策略(testid → ARIA → 文本)
|
|
|
|
|
+1. `data-testid` - 最高优先级
|
|
|
|
|
+2. `aria-label` + role - 无障碍标准
|
|
|
|
|
+3. Text content + role - 兜底方案
|
|
|
|
|
+
|
|
|
|
|
+**错误处理策略:** 结构化错误类 + 友好消息
|
|
|
|
|
+```typescript
|
|
|
|
|
+export class E2ETestError extends Error {
|
|
|
|
|
+ constructor(
|
|
|
|
|
+ public readonly context: ErrorContext,
|
|
|
|
|
+ message?: string
|
|
|
|
|
+ ) { ... }
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 技术栈约束
|
|
|
|
|
+
|
|
|
|
|
+**语言与类型系统:**
|
|
|
|
|
+- 纯 TypeScript 实现,目标 ES2020+
|
|
|
|
|
+- 严格类型检查,无 `any` 类型
|
|
|
|
|
+- 完整的 JSDoc 注释用于 IDE 提示
|
|
|
|
|
+
|
|
|
|
|
+**依赖管理:**
|
|
|
|
|
+- **Peer dependency**: `@playwright/test`(由测试项目提供)
|
|
|
|
|
+- **无运行时依赖**,保持轻量
|
|
|
|
|
+- **开发依赖**: TypeScript, Vitest(用于自测)
|
|
|
|
|
+
|
|
|
|
|
+### package.json 配置要求
|
|
|
|
|
+
|
|
|
|
|
+**参考现有的 `@d8d/shared-test-util` 包结构:**
|
|
|
|
|
+
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "name": "@d8d/e2e-test-utils",
|
|
|
|
|
+ "version": "1.0.0",
|
|
|
|
|
+ "description": "E2E testing utilities for Radix UI components",
|
|
|
|
|
+ "type": "module",
|
|
|
|
|
+ "main": "src/index.ts",
|
|
|
|
|
+ "types": "src/index.ts",
|
|
|
|
|
+ "exports": {
|
|
|
|
|
+ ".": {
|
|
|
|
|
+ "import": "./src/index.ts",
|
|
|
|
|
+ "require": "./src/index.ts",
|
|
|
|
|
+ "types": "./src/index.ts"
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ "files": [
|
|
|
|
|
+ "src"
|
|
|
|
|
+ ],
|
|
|
|
|
+ "scripts": {
|
|
|
|
|
+ "build": "tsc",
|
|
|
|
|
+ "dev": "tsc --watch",
|
|
|
|
|
+ "test": "vitest",
|
|
|
|
|
+ "test:unit": "vitest run tests/unit/**/*.test.ts",
|
|
|
|
|
+ "test:coverage": "vitest --coverage",
|
|
|
|
|
+ "typecheck": "tsc --noEmit"
|
|
|
|
|
+ },
|
|
|
|
|
+ "peerDependencies": {
|
|
|
|
|
+ "@playwright/test": "^1.40.0"
|
|
|
|
|
+ },
|
|
|
|
|
+ "devDependencies": {
|
|
|
|
|
+ "typescript": "^5.8.3",
|
|
|
|
|
+ "vitest": "^3.2.4",
|
|
|
|
|
+ "@vitest/coverage-v8": "^3.2.4"
|
|
|
|
|
+ },
|
|
|
|
|
+ "keywords": [
|
|
|
|
|
+ "e2e",
|
|
|
|
|
+ "testing",
|
|
|
|
|
+ "playwright",
|
|
|
|
|
+ "radix-ui",
|
|
|
|
|
+ "test-utilities"
|
|
|
|
|
+ ]
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**关键点:**
|
|
|
|
|
+1. 使用 `type: "module"` 启用 ES 模块
|
|
|
|
|
+2. `main` 和 `types` 都指向 `src/index.ts`(源代码直接使用)
|
|
|
|
|
+3. `exports` 配置支持 tree-shaking
|
|
|
|
|
+4. `peerDependencies` 指定 Playwright 版本范围(兼容最新稳定版和上一个 LTS 版本)
|
|
|
|
|
+5. 添加测试脚本(单元测试、覆盖率)
|
|
|
|
|
+
|
|
|
|
|
+### tsconfig.json 配置要求
|
|
|
|
|
+
|
|
|
|
|
+**参考项目 TypeScript 严格模式配置:**
|
|
|
|
|
+
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "compilerOptions": {
|
|
|
|
|
+ "target": "ES2020",
|
|
|
|
|
+ "module": "ESNext",
|
|
|
|
|
+ "lib": ["ES2020"],
|
|
|
|
|
+ "moduleResolution": "bundler",
|
|
|
|
|
+ "strict": true,
|
|
|
|
|
+ "noImplicitAny": true,
|
|
|
|
|
+ "strictNullChecks": true,
|
|
|
|
|
+ "strictFunctionTypes": true,
|
|
|
|
|
+ "noUnusedLocals": true,
|
|
|
|
|
+ "noUnusedParameters": true,
|
|
|
|
|
+ "noImplicitReturns": true,
|
|
|
|
|
+ "noFallthroughCasesInSwitch": true,
|
|
|
|
|
+ "esModuleInterop": true,
|
|
|
|
|
+ "skipLibCheck": true,
|
|
|
|
|
+ "forceConsistentCasingInFileNames": true,
|
|
|
|
|
+ "resolveJsonModule": true,
|
|
|
|
|
+ "isolatedModules": true,
|
|
|
|
|
+ "declaration": true,
|
|
|
|
|
+ "declarationMap": true,
|
|
|
|
|
+ "sourceMap": true,
|
|
|
|
|
+ "outDir": "./dist",
|
|
|
|
|
+ "rootDir": "./src",
|
|
|
|
|
+ "baseUrl": ".",
|
|
|
|
|
+ "paths": {
|
|
|
|
|
+ "@d8d/e2e-test-utils": ["./src/index.ts"]
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ "include": ["src/**/*"],
|
|
|
|
|
+ "exclude": ["node_modules", "dist", "tests"]
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**关键点:**
|
|
|
|
|
+1. 启用所有严格模式选项(`strict: true` + 额外检查)
|
|
|
|
|
+2. 目标 ES2020+(`target: "ES2020"`)
|
|
|
|
|
+3. 启用声明文件生成(`declaration: true`)
|
|
|
|
|
+4. 配置正确的 `rootDir` 和 `outDir`
|
|
|
|
|
+
|
|
|
|
|
+### vitest.config.ts 配置要求
|
|
|
|
|
+
|
|
|
|
|
+```typescript
|
|
|
|
|
+import { defineConfig } from 'vitest/config';
|
|
|
|
|
+
|
|
|
|
|
+export default defineConfig({
|
|
|
|
|
+ test: {
|
|
|
|
|
+ dir: './tests/unit',
|
|
|
|
|
+ environment: 'node',
|
|
|
|
|
+ coverage: {
|
|
|
|
|
+ provider: 'v8',
|
|
|
|
|
+ reporter: ['text', 'json', 'html'],
|
|
|
|
|
+ statements: 80,
|
|
|
|
|
+ branches: 80,
|
|
|
|
|
+ functions: 80,
|
|
|
|
|
+ lines: 80,
|
|
|
|
|
+ exclude: [
|
|
|
|
|
+ 'node_modules/',
|
|
|
|
|
+ 'tests/',
|
|
|
|
|
+ '**/*.test.ts',
|
|
|
|
|
+ '**/*.spec.ts',
|
|
|
|
|
+ 'src/index.ts'
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ testTimeout: 10000,
|
|
|
|
|
+ globals: false
|
|
|
|
|
+ }
|
|
|
|
|
+});
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**关键点:**
|
|
|
|
|
+1. 测试目录指向 `tests/unit`
|
|
|
|
|
+2. 覆盖率目标 ≥80%(所有指标)
|
|
|
|
|
+3. 测试超时 10 秒
|
|
|
|
|
+4. 排除 `src/index.ts` 从覆盖率(主导出文件)
|
|
|
|
|
+
|
|
|
|
|
+### 源代码文件结构
|
|
|
|
|
+
|
|
|
|
|
+**`src/index.ts` - 主导出文件(tree-shakeable):**
|
|
|
|
|
+
|
|
|
|
|
+```typescript
|
|
|
|
|
+// 导出类型定义
|
|
|
|
|
+export * from './types';
|
|
|
|
|
+
|
|
|
|
|
+// 导出错误类
|
|
|
|
|
+export * from './errors';
|
|
|
|
|
+
|
|
|
|
|
+// 导出常量
|
|
|
|
|
+export * from './constants';
|
|
|
|
|
+
|
|
|
|
|
+// Radix UI Select 工具(后续故事实现)
|
|
|
|
|
+// export * from './radix-select';
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**`src/types.ts` - 共享类型定义:**
|
|
|
|
|
+
|
|
|
|
|
+```typescript
|
|
|
|
|
+import type { Page } from '@playwright/test';
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 基础配置选项,所有配置对象的基类
|
|
|
|
|
+ */
|
|
|
|
|
+export interface BaseOptions {
|
|
|
|
|
+ /** 超时时间(毫秒)*/
|
|
|
|
|
+ timeout?: number;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 错误上下文接口
|
|
|
|
|
+ */
|
|
|
|
|
+export interface ErrorContext {
|
|
|
|
|
+ /** 操作类型(如 'selectRadixOption')*/
|
|
|
|
|
+ operation: string;
|
|
|
|
|
+ /** 目标(如下拉框标签)*/
|
|
|
|
|
+ target: string;
|
|
|
|
|
+ /** 期望值 */
|
|
|
|
|
+ expected?: string;
|
|
|
|
|
+ /** 实际值 */
|
|
|
|
|
+ actual?: string;
|
|
|
|
|
+ /** 可用选项列表 */
|
|
|
|
|
+ available?: string[];
|
|
|
|
|
+ /** 修复建议 */
|
|
|
|
|
+ suggestion?: string;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 重新导出 Playwright 类型以便使用者使用
|
|
|
|
|
+export type { Page } from '@playwright/test';
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**`src/errors.ts` - 错误处理:**
|
|
|
|
|
+
|
|
|
|
|
+```typescript
|
|
|
|
|
+import type { ErrorContext } from './types';
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * E2E 测试专用错误类
|
|
|
|
|
+ * 提供结构化的错误上下文信息
|
|
|
|
|
+ */
|
|
|
|
|
+export class E2ETestError extends Error {
|
|
|
|
|
+ constructor(
|
|
|
|
|
+ public readonly context: ErrorContext,
|
|
|
|
|
+ message?: string
|
|
|
|
|
+ ) {
|
|
|
|
|
+ super(message || formatErrorMessage(context));
|
|
|
|
|
+ this.name = 'E2ETestError';
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 格式化错误消息
|
|
|
|
|
+ */
|
|
|
|
|
+function formatErrorMessage(context: ErrorContext): string {
|
|
|
|
|
+ const parts = [
|
|
|
|
|
+ `❌ ${context.operation} failed`,
|
|
|
|
|
+ `Target: ${context.target}`
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ if (context.expected) {
|
|
|
|
|
+ parts.push(`Expected: ${context.expected}`);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (context.actual) {
|
|
|
|
|
+ parts.push(`Actual: ${context.actual}`);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (context.available && context.available.length > 0) {
|
|
|
|
|
+ parts.push(`Available: ${context.available.join(', ')}`);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (context.suggestion) {
|
|
|
|
|
+ parts.push(`\n💡 ${context.suggestion}`);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return parts.join('\n');
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**`src/constants.ts` - 常量定义:**
|
|
|
|
|
+
|
|
|
|
|
+```typescript
|
|
|
|
|
+/**
|
|
|
|
|
+ * 默认超时配置(毫秒)
|
|
|
|
|
+ */
|
|
|
|
|
+export const DEFAULT_TIMEOUTS = {
|
|
|
|
|
+ /** 静态选项超时 */
|
|
|
|
|
+ static: 2000,
|
|
|
|
|
+ /** 异步选项超时 */
|
|
|
|
|
+ async: 5000,
|
|
|
|
|
+ /** 网络空闲超时 */
|
|
|
|
|
+ networkIdle: 10000
|
|
|
|
|
+} as const;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 选择器策略常量
|
|
|
|
|
+ */
|
|
|
|
|
+export const SELECTOR_STRATEGIES = [
|
|
|
|
|
+ 'data-testid',
|
|
|
|
|
+ 'aria-label + role',
|
|
|
|
|
+ 'text content + role'
|
|
|
|
|
+] as const;
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 目录创建命令参考
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+# 在项目根目录执行
|
|
|
|
|
+mkdir -p packages/e2e-test-utils/src
|
|
|
|
|
+mkdir -p packages/e2e-test-utils/tests/fixtures/images
|
|
|
|
|
+mkdir -p packages/e2e-test-utils/tests/fixtures/data
|
|
|
|
|
+mkdir -p packages/e2e-test-utils/tests/unit
|
|
|
|
|
+mkdir -p packages/e2e-test-utils/tests/integration
|
|
|
|
|
+mkdir -p packages/e2e-test-utils/tests/stability
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 验证步骤
|
|
|
|
|
+
|
|
|
|
|
+**1. 验证目录结构:**
|
|
|
|
|
+```bash
|
|
|
|
|
+ls -la packages/e2e-test-utils/
|
|
|
|
|
+# 应显示:src/, tests/, package.json, tsconfig.json, vitest.config.ts, README.md
|
|
|
|
|
+
|
|
|
|
|
+ls -la packages/e2e-test-utils/src/
|
|
|
|
|
+# 应显示:index.ts, types.ts, errors.ts, constants.ts
|
|
|
|
|
+
|
|
|
|
|
+ls -la packages/e2e-test-utils/tests/
|
|
|
|
|
+# 应显示:fixtures/, unit/, integration/, stability/
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**2. 验证 TypeScript 配置:**
|
|
|
|
|
+```bash
|
|
|
|
|
+cd packages/e2e-test-utils
|
|
|
|
|
+pnpm typecheck
|
|
|
|
|
+# 应无错误输出
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**3. 验证包可以被安装:**
|
|
|
|
|
+```bash
|
|
|
|
|
+# 在 monorepo 根目录
|
|
|
|
|
+pnpm install
|
|
|
|
|
+# 检查是否成功注册 workspace 包
|
|
|
|
|
+
|
|
|
|
|
+# 验证可以被引用(在 web/ 目录)
|
|
|
|
|
+pnpm add -D @d8d/e2e-test-utils@workspace:*
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**4. 验证 Vitest 配置:**
|
|
|
|
|
+```bash
|
|
|
|
|
+cd packages/e2e-test-utils
|
|
|
|
|
+pnpm test:unit
|
|
|
|
|
+# 应显示 Vitest 成功启动(即使没有测试)
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### Project Structure Notes
|
|
|
|
|
+
|
|
|
|
|
+**对齐项目 Monorepo 架构:**
|
|
|
|
|
+- 使用 `pnpm workspace` 协议
|
|
|
|
|
+- 包命名遵循 `@d8d/` 命名空间
|
|
|
|
|
+- 与现有 `@d8d/shared-test-util`(后端集成测试)分离
|
|
|
|
|
+- `@d8d/e2e-test-utils` 专门用于 Playwright E2E 测试
|
|
|
|
|
+
|
|
|
|
|
+**与项目标准对齐:**
|
|
|
|
|
+- 遵循 `docs/standards/testing-standards.md` 中的测试规范
|
|
|
|
|
+- 遵循 `docs/standards/coding-standards.md` 中的编码标准
|
|
|
|
|
+- 遵循 `docs/standards/e2e-radix-testing.md` 中的 Radix UI E2E 测试标准(核心标准文档)
|
|
|
|
|
+
|
|
|
|
|
+### References
|
|
|
|
|
+
|
|
|
|
|
+**PRD 来源:**
|
|
|
|
|
+- [PRD - E2E测试工具包](_bmad-output/planning-artifacts/prd.md) - 项目需求概述
|
|
|
|
|
+- [PRD - 包结构需求](_bmad-output/planning-artifacts/prd.md#包结构需求) - 详细的包结构设计
|
|
|
|
|
+
|
|
|
|
|
+**Architecture 来源:**
|
|
|
|
|
+- [Architecture - 包结构决策](_bmad-output/planning-artifacts/architecture.md#package-structure) - 按功能分组的决策
|
|
|
|
|
+- [Architecture - API 设计模式](_bmad-output/planning-artifacts/architecture.md#api-design-pattern) - 3参数+配置对象模式
|
|
|
|
|
+- [Architecture - 类型系统策略](_bmad-output/planning-artifacts/architecture.md#type-system-strategy) - 分层类型设计
|
|
|
|
|
+- [Architecture - 项目目录结构](_bmad-output/planning-artifacts/architecture.md#complete-project-directory-structure) - 完整目录结构
|
|
|
|
|
+
|
|
|
|
|
+**标准文档来源:**
|
|
|
|
|
+- [E2E Radix UI 测试标准](docs/standards/e2e-radix-testing.md) - 核心测试标准文档
|
|
|
|
|
+- [测试规范](docs/standards/testing-standards.md) - 项目测试规范
|
|
|
|
|
+- [编码标准](docs/standards/coding-standards.md) - 编码标准
|
|
|
|
|
+
|
|
|
|
|
+**Epic 来源:**
|
|
|
|
|
+- [Epic 1 - Story 1.1](_bmad-output/planning-artifacts/epics.md#story-11-创建包基础结构和配置) - 原始用户故事和验收标准
|
|
|
|
|
+
|
|
|
|
|
+**参考包:**
|
|
|
|
|
+- [@d8d/shared-test-util](packages/shared-test-util/package.json) - 现有的共享测试工具包(后端集成测试)
|
|
|
|
|
+
|
|
|
|
|
+## Dev Agent Record
|
|
|
|
|
+
|
|
|
|
|
+### Agent Model Used
|
|
|
|
|
+
|
|
|
|
|
+Claude (d8d-model) via create-story workflow
|
|
|
|
|
+
|
|
|
|
|
+### Debug Log References
|
|
|
|
|
+
|
|
|
|
|
+### Completion Notes List
|
|
|
|
|
+
|
|
|
|
|
+- 故事创建时间: 2026-01-08
|
|
|
|
|
+- 基于 PRD、Architecture、E2E Radix 测试标准文档创建
|
|
|
|
|
+- 包含完整的目录结构、配置文件模板、验证步骤
|
|
|
|
|
+- 为后续故事提供基础设施
|
|
|
|
|
+
|
|
|
|
|
+### File List
|
|
|
|
|
+
|
|
|
|
|
+**创建的文件:**
|
|
|
|
|
+- `packages/e2e-test-utils/package.json`
|
|
|
|
|
+- `packages/e2e-test-utils/tsconfig.json`
|
|
|
|
|
+- `packages/e2e-test-utils/vitest.config.ts`
|
|
|
|
|
+- `packages/e2e-test-utils/README.md`
|
|
|
|
|
+- `packages/e2e-test-utils/src/index.ts`
|
|
|
|
|
+- `packages/e2e-test-utils/src/types.ts`
|
|
|
|
|
+- `packages/e2e-test-utils/src/errors.ts`
|
|
|
|
|
+- `packages/e2e-test-utils/src/constants.ts`
|
|
|
|
|
+
|
|
|
|
|
+**创建的目录:**
|
|
|
|
|
+- `packages/e2e-test-utils/src/`
|
|
|
|
|
+- `packages/e2e-test-utils/tests/fixtures/images/`
|
|
|
|
|
+- `packages/e2e-test-utils/tests/fixtures/data/`
|
|
|
|
|
+- `packages/e2e-test-utils/tests/unit/`
|
|
|
|
|
+- `packages/e2e-test-utils/tests/integration/`
|
|
|
|
|
+- `packages/e2e-test-utils/tests/stability/`
|