---
stepsCompleted: ['step-01-init', 'step-02-context', 'step-03-starter', 'step-04-decisions', 'step-05-patterns', 'step-06-structure', 'step-07-validation', 'step-08-complete']
inputDocuments:
  - name: PRD - E2E测试工具包
    path: _bmad-output/planning-artifacts/prd.md
    type: prd
    loadedAt: '2026-01-08T02:10:00.000Z'
  - name: 项目文档索引
    path: docs/index.md
    type: project-knowledge
    loadedAt: '2026-01-08T02:10:00.000Z'
  - name: Monorepo架构
    path: docs/architecture/monorepo.md
    type: project-doc
    loadedAt: '2026-01-08T02:10:00.000Z'
  - name: 模块组织结构
    path: docs/architecture/module-structure.md
    type: project-doc
    loadedAt: '2026-01-08T02:10:00.000Z'
  - name: 数据模型
    path: docs/architecture/data-models.md
    type: project-doc
    loadedAt: '2026-01-08T02:10:00.000Z'
  - name: API设计
    path: docs/architecture/api-design.md
    type: project-doc
    loadedAt: '2026-01-08T02:10:00.000Z'
  - name: 编码标准
    path: docs/standards/coding-standards.md
    type: project-doc
    loadedAt: '2026-01-08T02:10:00.000Z'
  - name: 后端模块开发规范
    path: docs/standards/backend-module-standards.md
    type: project-doc
    loadedAt: '2026-01-08T02:10:00.000Z'
  - name: UI包开发规范
    path: docs/standards/ui-package-standards.md
    type: project-doc
    loadedAt: '2026-01-08T02:10:00.000Z'
  - name: 测试规范
    path: docs/standards/testing-standards.md
    type: project-doc
    loadedAt: '2026-01-08T02:10:00.000Z'
workflowType: 'architecture'
project_name: '188-179-template-6'
user_name: 'Root'
date: '2026-01-08T02:10:00.000Z'
lastStep: 8
status: 'complete'
completedAt: '2026-01-08'
---

# Architecture Decision Document

_This document builds collaboratively through step-by-step discovery. Sections are appended as we work through each architectural decision together._

---

## Project Context Analysis

### Requirements Overview

**Functional Requirements (50 total):**

| 类别 | FR范围 | 架构含义 |
|------|--------|----------|
| Radix UI Select 测试 | FR1-FR6 | 需封装复杂的 Radix UI DOM 操作，区分静态/异步场景 |
| 文件上传测试 | FR7-FR10 | 需处理 fixtures 文件管理和多文件上传场景 |
| 表单交互测试 | FR11-FR15 | 需支持多步骤表单流程和滚动操作 |
| 动态列表测试 | FR16-FR20 | 需处理动态 DOM 更新和异步状态管理 |
| 对话框操作 | FR21-FR24 | 需统一的对话框打开/关闭/等待模式 |
| 工具包基础设施 | FR25-FR32 | 需 npm workspace 集成、TypeScript 类型安全 |
| 文档和开发支持 | FR33-FR40 | 需完整示例、迁移指南、快速入门 |
| 质量保障 | FR41-FR45 | 需稳定性保障（20次连续运行100%通过） |
| 可扩展性 | FR46-FR50 | 需配置化设计和版本升级兼容 |

**Non-Functional Requirements (46 total):**

| 类别 | NFR范围 | 架构驱动因素 |
|------|--------|-------------|
| 可靠性 | NFR1-NFR7 | 测试稳定性是核心，错误处理必须清晰 |
| 性能 | NFR8-NFR14 | 静态Select 2秒、异步Select 5秒的性能约束 |
| 集成性 | NFR15-NFR24 | Playwright 兼容、Monorepo workspace 集成 |
| 代码质量 | NFR25-NFR40 | 无 any 类型、≥80% 覆盖率、JSDoc 完整 |
| 兼容性 | NFR41-NFR46 | 跨浏览器、CI/CD 环境、版本升级兼容 |

**Scale & Complexity:**

- **Primary domain**: 开发者工具 / 测试基础设施
- **Complexity level**: Low（相对独立的工具函数 + 文档）
- **Estimated architectural components**: 6个核心工具函数 + 1个共享包

### Technical Constraints & Dependencies

**技术栈约束:**
- 纯 TypeScript 实现，目标 ES2020+
- 使用 pnpm workspace 协议进行本地开发
- Peer dependency: `@playwright/test`（由测试项目提供）
- 无运行时依赖，保持轻量

**架构约束:**
- 必须与现有 Page Object 模式集成
- 必须遵循 Monorepo 架构规范
- 必须兼容现有的测试基础设施（Vitest + Playwright）

**外部依赖:**
- Radix UI 组件库（DOM 结构变化风险）
- Playwright 框架版本兼容性
- 现有 `@d8d/shared-test-util`（后端集成测试，独立于本工具包）

### Cross-Cutting Concerns Identified

1. **测试稳定性**: 统一等待策略、错误处理、重试逻辑
2. **开发体验**: 简洁 API、清晰错误提示、完整文档
3. **可扩展性**: 支持配置对象、预留钩子函数
4. **版本兼容性**: 使用 stable selectors（role、data-testid）应对 Radix UI 升级
5. **Monorepo 集成**: 通过 workspace 协议安装，支持本地开发迭代

---

## Starter Template Evaluation

### Primary Technology Domain

开发者工具 / 测试基础设施包

### Starter Options Considered

**不适用**：本项目是在现有 Monorepo 中创建的内部测试工具包（`packages/e2e-test-utils`），而非独立应用项目。

**技术栈已由现有项目确定：**
- 纯 TypeScript，目标 ES2020+
- Playwright 作为 peer dependency
- Vitest 用于工具函数自测
- 遵循现有 Monorepo 架构规范

**包结构需要遵循：**
- pnpm workspace 协议集成
- 与现有测试基础设施兼容
- 与现有包结构保持一致

---

## Core Architectural Decisions

### Decision Priority Analysis

**Critical Decisions (Block Implementation):**
- ✅ 包内部结构：按功能分组
- ✅ API 设计模式：3个必需参数 + 可选配置对象
- ✅ 类型系统策略：分层类型（共享+特定）
- ✅ 选择器策略：混合策略（testid → ARIA → 文本）

**Important Decisions (Shape Architecture):**
- ✅ 错误处理策略：结构化错误类 + 友好消息
- ✅ 测试配置：三层测试策略

**Deferred Decisions (Post-MVP):**
- VS Code snippets
- CLI 测试生成器
- AI 辅助测试生成

---

### Package Structure

**决策**: 按功能分组（选项B）

**目录结构**:
```
packages/e2e-test-utils/
├── src/
│   ├── index.ts              # 主导出
│   ├── types.ts              # 共享类型定义
│   ├── radix-select.ts       # Radix UI Select 工具
│   ├── file-upload.ts        # 文件上传工具
│   ├── form-helper.ts        # 表单辅助函数
│   ├── dialog.ts             # 对话框操作
│   └── dynamic-list.ts       # 动态列表管理
├── tests/
│   ├── unit/                 # 单元测试
│   ├── integration/          # 集成测试
│   └── stability/            # 稳定性测试
├── package.json
└── README.md
```

**理由**: 清晰的职责分离，便于测试和维护

---

### API Design Pattern

**决策**: 3个必需参数 + 可选配置对象

**核心原则**:
- 必需参数 ≤ 3 个
- 复杂配置通过可选对象传递
- 类型推断友好
- JSDoc 完整

**示例**:
```typescript
// 静态 Select - 简洁场景
export async function selectRadixOption(
  page: Page,
  label: string,
  value: string
): Promise<void>

// 异步 Select - 需要配置
export async function selectRadixOptionAsync(
  page: Page,
  label: string,
  value: string,
  options?: AsyncSelectOptions
): Promise<void>
```

---

### Type System Strategy

**决策**: 分层类型（选项C）

**类型分层**:
```
types.ts (共享/基础类型)
├── BaseOptions (超时等通用配置)
└── 导出 Playwright 类型

各模块文件 (特定类型)
├── radix-select.ts → AsyncSelectOptions
├── file-upload.ts → FileUploadOptions
└── ...
```

**优势**:
- 共享类型统一管理
- 特定类型就近定义
- 支持类型复用和扩展

---

### Selector Strategy

**决策**: 混合策略（testid → ARIA → 文本）

**优先级**:
1. `data-testid` - 最高优先级，需开发团队配合
2. `aria-label` + role - 无障碍标准
3. Text content + role - 兜底方案

**配套措施**:
- 推荐在 Radix 组件上添加 `data-testid`
- 提供迁移指南

---

### Error Handling Strategy

**决策**: 结构化错误类 + 友好消息

**错误结构**:
```typescript
export class E2ETestError extends Error {
  constructor(
    public readonly context: ErrorContext,
    message?: string
  ) { ... }
}

export interface ErrorContext {
  operation: string;      // 操作类型
  target: string;         // 目标
  expected?: string;      // 期望值
  actual?: string;        // 实际值
  available?: string[];   // 可用选项
  suggestion?: string;    // 修复建议
}
```

**示例输出**:
```
❌ selectOption failed
Target: 残疾类型
Expected: 视力残疾
Available: 听力残疾, 言语残疾, 肢体残疾
💡 Suggestion: Check if the option value matches exactly
```

---

### Testing Configuration

**决策**: 三层测试策略

| 测试类型 | 范围 | 工具 | 目标 |
|----------|------|------|------|
| 单元测试 | 单个函数逻辑 | **Vitest** | ≥80% 覆盖率 |
| 集成测试 | 与真实组件交互 | **Playwright** | 验证实际 DOM 结构 |
| 稳定性测试 | 20次连续运行 | **Playwright** | 100% 通过率 |

**⚠️ Epic 2 关键发现：**

单元测试**无法**发现真实 DOM 结构问题：
- 单元测试使用模拟 DOM，覆盖率 93.65% 仍然无法发现 DOM 问题
- Epic 2 的 listbox → option 问题只在真实 E2E 测试中暴露
- **必须添加集成测试级别，使用真实 Radix UI 组件验证**

**集成测试基础设施**：
- 创建独立的测试应用 `tests/test-app/`
- 使用 Vite + React
- **导入真实的 Radix UI 组件**（而非模拟）
- Playwright 配置自动启动测试应用服务器

**配置文件**:
```typescript
// vitest.config.ts - 单元测试
{
  coverage: { statements: 80, branches: 80, functions: 80, lines: 80 },
  testTimeout: 10000,
}

// playwright.config.ts - 集成/稳定性测试
{
  testDir: './tests/integration',
  webServer: {
    command: 'pnpm --filter @d8d/e2e-test-utils-test-app dev',
    url: 'http://localhost:5173',
    reuseExistingServer: !process.env.CI,
  },
}
```

---

### Decision Impact Analysis

**Implementation Sequence:**
1. 创建包结构 + package.json
2. 实现 types.ts + index.ts
3. 实现各工具函数（从简单到复杂）
4. 编写单元测试
5. 编写集成测试
6. 编写稳定性测试
7. 在残疾人管理中验证

**Cross-Component Dependencies:**
- 所有工具函数依赖 `types.ts`
- index.ts 依赖所有模块（tree-shakeable 导出）
- 测试依赖完整的函数实现

---

## Implementation Patterns & Consistency Rules

### Pattern Categories Defined

**Critical Conflict Points Identified:**
4 个类别，每个类别都可能导致 AI Agent 实现不一致

### Naming Patterns

**函数命名约定**：
- 风格：动词+名词，camelCase
- 示例：`selectRadixOption`、`uploadFileToField`、`fillMultiStepForm`
- 异步函数：添加 `Async` 后缀（如 `selectRadixOptionAsync`）

**类型命名约定**：
- 接口：PascalCase，`Options` 后缀
- 示例：`AsyncSelectOptions`、`FileUploadOptions`
- 基础类型：`BaseOptions` 作为所有配置的基类

**测试文件命名**：
- 单元测试：与源文件同名，`.test.ts` 后缀
- 集成测试：描述性名称，如 `select-scenarios.test.ts`
- 稳定性测试：`stability.test.ts`

### Structure Patterns

**测试目录结构**：
```
tests/
├── fixtures/           # 集中管理测试资源
│   ├── images/        # 测试图片
│   └── data/          # 测试数据
├── unit/              # 单元测试（无 Playwright）
├── integration/       # 集成测试（需要 Playwright）
└── stability/         # 稳定性测试
```

**源文件组织**：
- 每个工具函数独立文件
- `types.ts` 存放共享类型
- `index.ts` 作为主导出（tree-shakeable）

### Format Patterns

**JSDoc 格式**：
```typescript
/**
 * 函数描述（简洁说明）
 *
 * @param paramName - 参数描述
 * @param paramTwo - 参数描述
 * @throws {E2ETestError} 错误条件
 * @example
 * ```ts
 * await functionName(page, 'arg', 'value');
 * ```
 */
```

**配置对象格式**：
```typescript
// 所有可选配置都继承 BaseOptions
export interface XxxOptions extends BaseOptions {
  /** 特定选项描述 */
  specificOption?: boolean;
}

export interface BaseOptions {
  /** 超时时间（毫秒）*/
  timeout?: number;
}
```

**错误消息格式**：
- 标题：❌ 操作失败
- 上下文：目标、期望值、实际值
- 建议：💡 修复建议

### Process Patterns

**选择器查找流程**：
```typescript
const SELECTOR_STRATEGIES = [
  findByTestId,      // 1. data-testid
  findByAria,        // 2. aria-label + role
  findByText,        // 3. text content + role
] as const;
// 按优先级尝试，找到即返回
```

**等待策略常量**：
```typescript
export const DEFAULT_TIMEOUTS = {
  static: 2000,      // 静态选项
  async: 5000,       // 异步选项
  networkIdle: 10000, // 网络空闲
} as const;
```

**错误处理流程**：
```typescript
// 1. 捕获底层错误
// 2. 转换为 E2ETestError
// 3. 包含完整 ErrorContext
export function throwError(context: ErrorContext): never {
  throw new E2ETestError(context, formatErrorMessage(context));
}
```

### Enforcement Guidelines

**所有 AI Agent 必须：**

1. **遵循命名约定**：函数、类型、文件名按规范命名
2. **使用完整 JSDoc**：每个导出函数必须有完整文档
3. **统一错误处理**：使用 `E2ETestError` 和 `ErrorContext`
4. **按优先级查找选择器**：testid → ARIA → 文本
5. **使用常量定义超时**：从 `DEFAULT_TIMEOUTS` 获取
6. **配置对象继承 BaseOptions**：确保一致性

**强制执行方式：**
- ESLint 规则检查命名
- TypeScript 严格类型检查
- 测试覆盖率 ≥80%
- Code Review 验证模式

### Pattern Examples

**正确示例**：
```typescript
// ✅ 正确：遵循命名和格式约定
/**
 * 选择 Radix UI 下拉框的静态选项
 *
 * @param page - Playwright Page 对象
 * @param label - 下拉框标签文本
 * @param value - 要选择的选项值
 * @throws {E2ETestError} 当下拉框或选项未找到时
 */
export async function selectRadixOption(
  page: Page,
  label: string,
  value: string
): Promise<void> {
  try {
    // 实现逻辑
  } catch (error) {
    throwError({
      operation: 'selectRadixOption',
      target: label,
      expected: value,
    });
  }
}
```

**反模式（避免）**：
```typescript
// ❌ 错误：缺少 JSDoc
export async function select(p: any, l: string, v: string) {}

// ❌ 错误：使用 any 类型
export async function selectOption(
  page: Page,
  label: any,
  value: any
): Promise<void> {}

// ❌ 错误：自定义错误类型
throw new Error('Select failed');

// ❌ 错误：硬编码超时
await page.waitForTimeout(5000);
```

---

## TypeScript + Playwright 常见陷阱

> 本部分记录从 Epic 1 和 Epic 2 回顾中总结的 TypeScript + Playwright 陷阱和最佳实践。
> 参见: _bmad-output/implementation-artifacts/epic-1-retrospective.md, epic-2-retrospective.md

### 陷阱 1: DOM 结构假设必须验证 ⚠️ 关键

**问题（Epic 2 发现）：** 单元测试使用模拟 DOM 结构，无法发现真实组件的 DOM 问题。

**案例：** 工具假设 Select 组件包含 `[role="listbox"]` 元素，但 Radix UI Select v2.2.5 的实际结构是：
```
[role="combobox"]
  └── [role="option"]  ← 选项直接在 combobox 内部
```

**影响：** 单元测试覆盖率 93.65% 仍然无法发现此问题，因为单元测试的 DOM 是理想化的模拟结构。

**解决方案：**
1. **在真实组件上验证工具** - 使用真实的 Radix UI 组件进行集成测试
2. **添加集成测试级别** - 单元测试无法替代真实环境测试
3. **DOM 结构假设必须验证** - 不能基于理想模型开发工具

```typescript
// ❌ 假设 listbox 存在
await page.waitForSelector('[role="listbox"]', { state: 'visible' });

// ✅ 直接查找 option 元素
await page.waitForSelector('[role="option"]', { state: 'visible' });
// 或使用 getByRole
const option = page.getByRole('option', { name: value });
```

### 陷阱 2: DOM 类型问题

**问题：** 使用 `page.evaluate()` 获取文本内容会触发 TypeScript DOM 类型错误。

**原因：** Playwright 的类型定义与浏览器 DOM 环境不完全兼容，`page.evaluate()` 中的类型推断可能出现问题。

**解决方案：** 使用 Playwright API 而非 `page.evaluate()`：

```typescript
// ❌ 不推荐 - TypeScript 类型问题
const text = await page.evaluate(el => el.textContent, element);

// ✅ 推荐 - 使用 Playwright API
const text = await element.textContent();

// ✅ 推荐 - 使用 locator 获取多个文本
const texts = await page.locator(selector).allTextContents();
```

### 陷阱 2: 精确文本匹配

**问题：** 使用 `:has-text()` 选择器会进行部分匹配，可能导致误选错误选项。

**案例：** 期望选择 "广东省"，实际选择了 "广东省xx市"（因为包含 "广东省"）。

**解决方案：** 使用 `:text-is()` 进行精确匹配：

```typescript
// ❌ 部分匹配 - 可能误选
page.locator(`.option:has-text("广东省")`)

// ✅ 精确匹配 - 只匹配完全相等的文本
page.locator(`.option:text-is("广东省")`)
```

**影响：** 如果没有在代码审查中发现，测试可能会在错误选项上通过，导致假阳性 bug。

### 陷阱 3: 网络空闲等待超时配置

**问题：** 网络空闲等待使用了固定的 `networkIdle` 超时，而非用户自定义的超时值。

**案例（Story 1.6 单元测试中发现）：**

```typescript
// ❌ Bug - 网络空闲等待使用了默认的 networkIdle 超时
await page.waitForLoadState('networkidle', { timeout: DEFAULT_TIMEOUTS.networkIdle });

// ✅ 修复 - 使用用户自定义的 timeout
await page.waitForLoadState('networkidle', { timeout: options.timeout ?? DEFAULT_TIMEOUTS.async });
```

**经验：** 任何使用超时的 Playwright API 都应该尊重用户的自定义配置。

### 陷阱 4: 选择器策略优先级

**问题：** 直接使用文本选择器可能失败，因为 Radix UI 的 DOM 结构会随版本变化。

**解决方案：** 按优先级使用选择器策略：

```typescript
const SELECTOR_STRATEGIES = [
  findByTestId,      // 1. data-testid - 最稳定
  findByAria,        // 2. aria-label + role - 无障碍属性
  findByText,        // 3. text content - 兜底方案
] as const;
```

### 实现检查清单

基于 Epic 1 和 Epic 2 的经验，所有开发者应遵循以下检查清单：

**代码质量：**
- [ ] 所有导出函数都有完整的 JSDoc（@param, @returns, @throws, @example）
- [ ] 内部函数使用 `@internal` 标记
- [ ] 错误处理使用 `E2ETestError` 而非原生 `Error`

**选择器策略：**
- [ ] 文本选择器使用 `:text-is()` 而非 `:has-text()`
- [ ] DOM 结构假设必须基于真实组件验证，不能基于理想模型

**配置和超时：**
- [ ] 配置对象继承 `BaseOptions`
- [ ] 超时值使用 `DEFAULT_TIMEOUTS` 常量
- [ ] 网络空闲等待使用用户自定义的超时值

**DOM 操作：**
- [ ] 避免使用 `page.evaluate()` 处理 DOM 操作

**测试策略（Epic 2 关键发现）：**
- [ ] 单元测试无法发现真实 DOM 结构问题，必须添加集成测试
- [ ] 使用真实组件验证工具，而非仅依赖模拟 DOM

---

## Project Structure & Boundaries

### Complete Project Directory Structure

```
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/
│   │   ├── images/
│   │   │   ├── sample-id-card.jpg
│   │   │   └── sample-disability-card.jpg
│   │   └── data/
│   │       └── test-users.json
│   ├── test-app/                   # 独立测试应用
│   │   ├── package.json
│   │   ├── vite.config.ts
│   │   ├── index.html
│   │   ├── main.tsx
│   │   └── pages/
│   │       ├── select.tsx          # Select 测试页面
│   │       ├── dialog.tsx          # Dialog 测试页面
│   │       ├── file-upload.tsx     # 文件上传测试页面
│   │       ├── form.tsx            # 表单测试页面
│   │       └── dynamic-list.tsx    # 动态列表测试页面
│   ├── unit/                       # Vitest 单元测试
│   │   ├── radix-select.test.ts
│   │   ├── file-upload.test.ts
│   │   ├── form-helper.test.ts
│   │   ├── dialog.test.ts
│   │   └── dynamic-list.test.ts
│   ├── integration/                # Playwright 集成测试
│   │   ├── select-scenarios.spec.ts
│   │   ├── upload-scenarios.spec.ts
│   │   └── form-scenarios.spec.ts
│   └── stability/                  # Playwright 稳定性测试
│       └── repeat-run.spec.ts
├── package.json
├── tsconfig.json
├── vitest.config.ts                # 单元测试配置
├── playwright.config.ts            # 集成/稳定性测试配置
├── README.md
└── CHANGELOG.md
```

### Architectural Boundaries

**包边界**：
- **输入**: 接收 Playwright `Page` 对象作为参数
- **输出**: 返回 `Promise<void>` 或抛出 `E2ETestError`
- **依赖**: Peer dependency `@playwright/test`，无运行时依赖

**工具函数边界**：
- 每个工具函数独立运行，无共享状态
- 不依赖其他工具函数（避免循环依赖）
- 所有共享逻辑通过 `types.ts`、`errors.ts`、`constants.ts` 提供

### Requirements to Structure Mapping

**FR 类别 → 文件映射**：

| FR 类别 | 文件 | 说明 |
|---------|------|------|
| FR1-FR6 (Radix UI Select) | `radix-select.ts` | 静态和异步 Select 工具 |
| FR7-FR10 (文件上传) | `file-upload.ts` | 文件上传工具 |
| FR11-FR15 (表单交互) | `form-helper.ts` | 多步骤表单、滚动 |
| FR16-FR20 (动态列表) | `dynamic-list.ts` | 添加/删除列表项 |
| FR21-FR24 (对话框) | `dialog.ts` | 对话框操作 |
| FR25-FR32 (工具包基础设施) | `index.ts`, `package.json` | 包导出和配置 |
| FR41-FR45 (质量保障) | `tests/` | 所有测试文件 |

### Integration Points

**内部通信**：
- 工具函数通过 `types.ts` 共享类型定义
- 通过 `errors.ts` 统一错误处理
- 通过 `constants.ts` 共享配置常量

**外部集成**：
- **Playwright**: 通过 peer dependency 集成，提供 `Page` 对象
- **测试项目**: 通过 workspace 协议安装：`@d8d/e2e-test-utils@workspace:*`
- **现有 Page Object**: 可与现有 Page Object 模式共存

**数据流**：
```
测试代码 → 工具函数 → Playwright API → DOM 操作
                ↓
            E2ETestError (失败时)
```

### File Organization Patterns

**配置文件**：
- `package.json`: 包定义、workspace 协议配置
- `tsconfig.json`: TypeScript 严格模式配置
- `vitest.config.ts`: Vitest 单元测试配置、覆盖率目标
- `playwright.config.ts`: Playwright 集成/稳定性测试配置、测试应用服务器

**源码组织**：
- 按功能分组（每个工具函数一个文件）
- 共享代码集中在 `types.ts`、`errors.ts`、`constants.ts`
- `index.ts` 作为主导出点，支持 tree-shaking

**测试组织**：
- `tests/unit/`: Vitest 单元测试，测试单个函数逻辑
- `tests/integration/`: Playwright 集成测试，验证与真实 DOM 的交互
- `tests/stability/`: Playwright 稳定性测试，20次连续运行
- `tests/test-app/`: 独立测试应用，提供 @d8d/shared-ui-components 组件测试环境
- `tests/fixtures/`: 测试资源集中管理

---

## Architecture Validation Results

### Coherence Validation ✅

**Decision Compatibility:**

所有核心技术决策相互兼容，无冲突：
- ✅ TypeScript ES2020+ 与 Playwright peer dependency 兼容
- ✅ 按功能分组的包结构与分层类型系统一致
- ✅ 混合选择器策略支持错误处理中的上下文信息
- ✅ 三层测试策略与工具函数设计模式匹配

**Pattern Consistency:**

实现模式完全支持架构决策：
- ✅ 命名约定与 API 设计模式一致（动词+名词，camelCase）
- ✅ 配置对象继承 BaseOptions 与类型系统策略一致
- ✅ 错误处理流程使用结构化错误类
- ✅ 选择器查找流程遵循混合策略优先级

**Structure Alignment:**

项目结构完全支持所有架构决策：
- ✅ 测试目录结构分离单元测试和集成测试
- ✅ test-app 提供真实的 @d8d/shared-ui-components 测试环境
- ✅ 源文件组织支持按功能分组和独立模块
- ✅ 配置文件完整覆盖所有测试工具

### Requirements Coverage Validation ✅

**Epic/Feature Coverage:**

所有 50 个功能需求都有架构支持：

| FR 类别 | 架构支持 | 验证 |
|---------|----------|------|
| FR1-FR6 (Radix UI Select) | `radix-select.ts` + test-app/pages/select.tsx | ✅ |
| FR7-FR10 (文件上传) | `file-upload.ts` + test-app/pages/file-upload.tsx | ✅ |
| FR11-FR15 (表单交互) | `form-helper.ts` + test-app/pages/form.tsx | ✅ |
| FR16-FR20 (动态列表) | `dynamic-list.ts` + test-app/pages/dynamic-list.tsx | ✅ |
| FR21-FR24 (对话框) | `dialog.ts` + test-app/pages/dialog.tsx | ✅ |
| FR25-FR32 (工具包基础设施) | `index.ts` + `package.json` | ✅ |
| FR33-FR40 (文档和开发支持) | README.md + JSDoc 完整性要求 | ✅ |
| FR41-FR45 (质量保障) | 三层测试策略 + 稳定性测试 | ✅ |
| FR46-FR50 (可扩展性) | 配置对象设计 + BaseOptions 扩展 | ✅ |

**Functional Requirements Coverage:**

所有功能需求类别完全覆盖：
- ✅ Radix UI 组件测试：6个核心工具函数 + 独立测试应用
- ✅ 文件上传测试：fixtures 管理 + Playwright 文件上传 API
- ✅ 表单交互测试：多步骤表单支持 + 滚动操作常量
- ✅ 动态列表测试：添加/删除列表项工具函数
- ✅ 对话框操作：统一的打开/关闭/等待模式
- ✅ 工具包基础设施：workspace 协议 + TypeScript 类型安全
- ✅ 文档和开发支持：JSDoc 完整性 + README 模板
- ✅ 质量保障：80% 覆盖率 + 20次连续稳定性测试
- ✅ 可扩展性：配置对象 + 版本升级兼容性

**Non-Functional Requirements Coverage:**

所有 46 个非功能需求都已处理：

| NFR 类别 | 架构支持 | 验证 |
|---------|----------|------|
| NFR1-NFR7 (可靠性) | E2ETestError + ErrorContext + 友好错误消息 | ✅ |
| NFR8-NFR14 (性能) | DEFAULT_TIMEOUTS 常量 + 超时配置 | ✅ |
| NFR15-NFR24 (集成性) | Playwright peer dependency + workspace 协议 | ✅ |
| NFR25-NFR40 (代码质量) | 无 any 类型 + 80% 覆盖率 + JSDoc 完整 | ✅ |
| NFR41-NFR46 (兼容性) | 稳定选择器策略 + 跨浏览器测试 | ✅ |

### Implementation Readiness Validation ✅

**Decision Completeness:**

所有关键决策都已记录版本和理由：
- ✅ 包内部结构：按功能分组
- ✅ API 设计模式：3个必需参数 + 可选配置对象
- ✅ 类型系统策略：分层类型（共享+特定）
- ✅ 选择器策略：混合策略（testid → ARIA → 文本）
- ✅ 错误处理策略：结构化错误类 + 友好消息
- ✅ 测试配置：三层测试策略（Vitest + Playwright）

**Structure Completeness:**

项目结构完整且具体：
- ✅ 所有源文件和目录已定义
- ✅ 测试应用结构完整（test-app/）
- ✅ 集成点清晰指定（Playwright、测试项目）
- ✅ 组件边界明确定义

**Pattern Completeness:**

所有潜在冲突点都已解决：
- ✅ 命名约定：函数、类型、文件名
- ✅ 结构模式：测试目录、源文件组织
- ✅ 格式模式：JSDoc、配置对象、错误消息
- ✅ 流程模式：选择器查找、等待策略、错误处理

### Gap Analysis Results

**Critical Gaps:** 无

**Important Gaps:** 无

**Nice-to-Have Gaps:**
- 📝 VS Code snippets 代码片段（已推迟到 MVP 后）
- 📝 CLI 测试生成器（已推迟到 MVP 后）
- 📝 AI 辅助测试生成（已推迟到 MVP 后）

### Validation Issues Addressed

**集成测试基础设施问题（已解决）：**

**问题描述：**
原始架构将集成测试配置为使用 Vitest 运行 Playwright，这不符合 Playwright 的最佳实践。

**解决方案：**
- ✅ 分离单元测试和集成测试工具
- ✅ 单元测试使用 Vitest（测试纯函数逻辑）
- ✅ 集成测试和稳定性测试使用 Playwright（测试真实浏览器交互）
- ✅ 创建独立测试应用 `tests/test-app/` 提供 @d8d/shared-ui-components 测试环境
- ✅ Playwright 配置自动启动测试应用服务器

**架构影响：**
- 更新 `Testing Configuration` 部分
- 更新项目目录结构，添加 `tests/test-app/`
- 添加 `playwright.config.ts` 配置文件
- 更新测试文件命名约定（`.spec.ts` 用于 Playwright）

### Architecture Completeness Checklist

**✅ Requirements Analysis**
- [x] 项目上下文彻底分析
- [x] 规模和复杂度评估
- [x] 技术约束识别
- [x] 跨领域关注点映射

**✅ Architectural Decisions**
- [x] 关键决策文档化并记录版本
- [x] 技术栈完全指定
- [x] 集成模式定义
- [x] 性能考虑已处理

**✅ Implementation Patterns**
- [x] 命名约定建立
- [x] 结构模式定义
- [x] 通信模式指定
- [x] 流程模式文档化

**✅ Project Structure**
- [x] 完整目录结构定义
- [x] 组件边界建立
- [x] 集成点映射
- [x] 需求到结构映射完成

**✅ Testing Strategy**
- [x] 三层测试策略定义
- [x] 测试工具选择合理（Vitest + Playwright）
- [x] 集成测试基础设施完整
- [x] 稳定性测试方法明确

### Architecture Readiness Assessment

**Overall Status:** READY FOR IMPLEMENTATION

**Confidence Level:** HIGH

**Key Strengths:**
1. ✅ 清晰的模块化设计，按功能分组
2. ✅ 完整的类型系统策略，支持类型推断
3. ✅ 结构化的错误处理，提供友好错误消息
4. ✅ 灵活的选择器策略，应对 Radix UI 版本升级
5. ✅ 合理的测试分层，单元测试与集成测试分离
6. ✅ 独立的测试应用，支持真实组件交互测试
7. ✅ 完整的一致性规则，确保 AI Agent 实现一致性

**Areas for Future Enhancement:**
1. 📝 VS Code snippets 提升开发体验
2. 📝 CLI 测试生成器加速测试编写
3. 📝 AI 辅助测试生成降低学习曲线

### Implementation Handoff

**AI Agent Guidelines:**

1. **严格遵循所有架构决策**：按文档中的定义实现，不得偏离
2. **使用实现模式保持一致性**：所有 AI Agent 必须遵循命名、结构、格式、流程模式
3. **尊重项目结构和边界**：按定义的目录结构组织代码
4. **参考架构文档解决所有问题**：遇到不确定的情况时查阅此文档

**First Implementation Priority:**

```bash
# 1. 创建包基础结构
mkdir -p packages/e2e-test-utils/src
mkdir -p packages/e2e-test-utils/tests/{unit,integration,stability,fixtures/{images,data}}

# 2. 创建测试应用
mkdir -p packages/e2e-test-utils/tests/test-app/pages

# 3. 初始化 package.json（包含正确的 peer dependencies）
# 4. 实现 types.ts 和 index.ts
# 5. 从简单到复杂实现各工具函数
# 6. 编写单元测试（Vitest）
# 7. 编写集成测试（Playwright + test-app）
# 8. 在残疾人管理功能中验证
```

**Success Criteria:**
- ✅ 所有 50 个功能需求实现
- ✅ 所有 46 个非功能需求满足
- ✅ 单元测试覆盖率 ≥80%
- ✅ 稳定性测试 20 次连续运行 100% 通过
- ✅ 在残疾人管理功能中成功使用

---

## Architecture Completion Summary

### Workflow Completion

**Architecture Decision Workflow:** COMPLETED ✅
**Total Steps Completed:** 8
**Date Completed:** 2026-01-08
**Document Location:** _bmad-output/planning-artifacts/architecture.md

### Final Architecture Deliverables

**📋 Complete Architecture Document**

- 所有架构决策已文档化，包含明确的技术选择
- 确保一致性：AI 实现模式和规则完整定义
- 项目结构完整：所有文件和目录都已定义
- 需求映射清晰：从 FR/NFR 到具体文件的映射
- 验证通过：架构一致性和完整性已确认

**🏗️ Implementation Ready Foundation**

- 6 个核心架构决策（包结构、API 设计、类型系统、选择器策略、错误处理、测试配置）
- 4 个一致性规则类别（命名、结构、格式、流程）
- 6 个核心工具函数 + 1 个共享测试应用
- 50 个功能需求 + 46 个非功能需求完全支持

**📚 AI Agent Implementation Guide**

- 技术栈：TypeScript ES2020+、Playwright、Vitest
- 一致性规则：防止 AI Agent 实现冲突
- 项目结构：清晰的边界和集成点
- 集成模式：workspace 协议、peer dependencies

### Implementation Handoff

**For AI Agents:**
本架构文档是实现 E2E 测试工具包的完整指南。严格遵循所有决策、模式和结构。

**First Implementation Priority:**

```bash
# 1. 创建包基础结构
mkdir -p packages/e2e-test-utils/src
mkdir -p packages/e2e-test-utils/tests/{unit,integration,stability,fixtures/{images,data}}

# 2. 创建测试应用
mkdir -p packages/e2e-test-utils/tests/test-app/pages

# 3. 初始化 package.json
{
  "name": "@d8d/e2e-test-utils",
  "version": "1.0.0",
  "type": "module",
  "peerDependencies": {
    "@playwright/test": "^1.40.0"
  },
  "devDependencies": {
    "vitest": "^3.2.4",
    "vite": "^6.0.11",
    "react": "^19.2.0",
    "react-dom": "^19.2.0"
  }
}

# 4. 实现 types.ts 和 index.ts
# 5. 从简单到复杂实现各工具函数
# 6. 编写单元测试（Vitest）
# 7. 编写集成测试（Playwright + test-app）
# 8. 在残疾人管理功能中验证
```

**Development Sequence:**

1. 初始化包结构和配置文件
2. 实现类型定义和主导出
3. 实现核心工具函数（radix-select → dialog → file-upload → form-helper → dynamic-list）
4. 编写单元测试（Vitest）
5. 创建测试应用并编写集成测试（Playwright）
6. 编写稳定性测试（20次连续运行）
7. 在残疾人管理功能中验证

### Quality Assurance Checklist

**✅ Architecture Coherence**

- [x] 所有决策无冲突，协同工作
- [x] 技术选择完全兼容
- [x] 模式支持架构决策
- [x] 结构与所有选择一致

**✅ Requirements Coverage**

- [x] 所有功能需求都有支持
- [x] 所有非功能需求都已处理
- [x] 跨领域关注点已解决
- [x] 集成点已明确定义

**✅ Implementation Readiness**

- [x] 决策具体且可执行
- [x] 模式防止 Agent 冲突
- [x] 结构完整且无歧义
- [x] 提供清晰示例

### Project Success Factors

**🎯 Clear Decision Framework**
每个技术选择都是协作完成的，有清晰的理由，确保所有利益相关者理解架构方向。

**🔧 Consistency Guarantee**
实现模式和规则确保多个 AI Agent 将产生兼容、一致的代码。

**📋 Complete Coverage**
所有项目需求都有架构支持，从业务需求到技术实现的清晰映射。

**🏗️ Solid Foundation**
选择的测试策略和架构模式提供了生产就绪的基础。

---

**Architecture Status:** READY FOR IMPLEMENTATION ✅

**Next Phase:** 开始实现阶段，使用文档化的架构决策和模式。

**Document Maintenance:** 当实现过程中做出重大技术决策时，更新此架构文档。

---

**🎉 架构工作流程完成！**

你的 E2E 测试工具包架构已经全面完成，经过验证，可以开始实现了。

**✅ 交付内容：**

- 完整的架构文档，包含所有决策和模式
- 为 AI Agent 实现准备好的项目结构
- 验证确认所有部分协同工作
- 开发阶段的实施指导

**📍 文档位置：**
`_bmad-output/planning-artifacts/architecture.md`

**🚀 下一步：**

1. 查看完整的架构文档
2. 创建包结构开始实现
3. 为 AI Agent 创建实现任务，遵循架构决策

你的架构将确保所有开发工作的一致、高质量实现。恭喜完成这些重要的架构决策！
