|
@@ -0,0 +1,474 @@
|
|
|
|
|
+# Story 8.1: 创建区域管理 Page Object
|
|
|
|
|
+
|
|
|
|
|
+Status: ready-for-dev
|
|
|
|
|
+
|
|
|
|
|
+<!-- Note: Validation is optional. Run validate-create-story for quality check before dev-story. -->
|
|
|
|
|
+
|
|
|
|
|
+## Story
|
|
|
|
|
+
|
|
|
|
|
+作为测试开发者,
|
|
|
|
|
+我想要创建区域管理的 Page Object,
|
|
|
|
|
+以便组织区域管理相关的页面元素和操作。
|
|
|
|
|
+
|
|
|
|
|
+## Acceptance Criteria
|
|
|
|
|
+
|
|
|
|
|
+**Given** Epic 2 的 Page Object 模式已验证
|
|
|
|
|
+**When** 创建 `web/tests/e2e/pages/admin/region-management.page.ts`
|
|
|
|
|
+**Then** 定义区域列表页面的选择器和操作方法
|
|
|
|
|
+**And** 定义添加区域对话框的选择器和操作方法
|
|
|
|
|
+**And** 定义编辑区域对话框的选择器和操作方法
|
|
|
|
|
+**And** 遵循现有 Page Object 设计模式
|
|
|
|
|
+**And** 所有方法有完整的 TypeScript 类型定义
|
|
|
|
|
+
|
|
|
|
|
+**Given** 区域管理 Page Object 已创建
|
|
|
|
|
+**When** 编写区域列表查看测试用例
|
|
|
|
|
+**Then** 验证区域列表按预期加载
|
|
|
|
|
+**And** 验证区域数据的正确展示(名称、层级、状态等)
|
|
|
|
|
+**And** 验证分页功能(如适用)
|
|
|
|
|
+**And** 验证搜索功能(如适用)
|
|
|
|
|
+**And** 测试在真实浏览器中通过
|
|
|
|
|
+
|
|
|
|
|
+## Tasks / Subtasks
|
|
|
|
|
+
|
|
|
|
|
+- [ ] 创建 RegionManagementPage 类基础结构 (AC: #)
|
|
|
|
|
+ - [ ] 定义页面选择器(页面标题、新增按钮、表格等)
|
|
|
|
|
+ - [ ] 实现构造函数和初始化逻辑
|
|
|
|
|
+- [ ] 实现页面导航方法 (AC: #)
|
|
|
|
|
+ - [ ] 实现 goto() 方法导航到区域管理页面
|
|
|
|
|
+ - [ ] 实现 expectToBeVisible() 验证页面元素可见性
|
|
|
|
|
+- [ ] 实现区域列表相关方法 (AC: #)
|
|
|
|
|
+ - [ ] 定义列表表格、搜索输入框、搜索按钮等选择器
|
|
|
|
|
+ - [ ] 实现 searchByName() 搜索方法
|
|
|
|
|
+ - [ ] 实现 regionExists() 验证区域是否存在
|
|
|
|
|
+- [ ] 实现添加区域对话框方法 (AC: #)
|
|
|
|
|
+ - [ ] 定义添加区域对话框选择器
|
|
|
|
|
+ - [ ] 实现 openAddDialog() 打开添加对话框
|
|
|
|
|
+ - [ ] 实现 fillRegionForm() 填写区域表单
|
|
|
|
|
+ - [ ] 实现 submitForm() 提交表单
|
|
|
|
|
+- [ ] 实现编辑区域对话框方法 (AC: #)
|
|
|
|
|
+ - [ ] 定义编辑区域对话框选择器
|
|
|
|
|
+ - [ ] 实现 openEditDialog() 打开编辑对话框
|
|
|
|
|
+ - [ ] 实现区域信息编辑方法
|
|
|
|
|
+- [ ] 实现删除区域相关方法 (AC: #)
|
|
|
|
|
+ - [ ] 定义删除确认对话框选择器
|
|
|
|
|
+ - [ ] 实现 confirmDelete() 确认删除
|
|
|
|
|
+ - [ ] 实现 cancelDelete() 取消删除
|
|
|
|
|
+- [ ] 添加 TypeScript 类型定义 (AC: #)
|
|
|
|
|
+ - [ ] 定义 RegionData 接口
|
|
|
|
|
+ - [ ] 定义所有方法的参数和返回值类型
|
|
|
|
|
+- [ ] 遵循现有 Page Object 设计模式 (AC: #)
|
|
|
|
|
+ - [ ] 参考 disability-person.page.ts 的代码风格
|
|
|
|
|
+ - [ ] 使用一致的命名约定
|
|
|
|
|
+ - [ ] 使用 e2e-test-utils 工具函数
|
|
|
|
|
+
|
|
|
|
|
+## Dev Notes
|
|
|
|
|
+
|
|
|
|
|
+### Epic 8 背景和上下文
|
|
|
|
|
+
|
|
|
|
|
+**Epic 8: 区域管理 E2E 测试 (Epic B - 业务测试 Epic)**
|
|
|
|
|
+
|
|
|
|
|
+这是 Epic B(区域管理业务测试)的第一个 Story。Epic 8 的目标是为区域管理功能建立完整的 E2E 测试覆盖,验证省/市/区/街道的添加、编辑、删除和级联选择功能。
|
|
|
|
|
+
|
|
|
|
|
+**依赖:**
|
|
|
|
|
+- Epic 1: ✅ 已完成(Select 工具基础框架)
|
|
|
|
|
+- Epic 2: ✅ 已完成(Select 工具在真实 E2E 测试中验证)
|
|
|
|
|
+- Epic 3: ✅ 已完成(文件上传工具、级联选择工具)
|
|
|
|
|
+
|
|
|
|
|
+**业务分组:**
|
|
|
|
|
+- Epic A(残疾人管理)- 已完成基础工具验证
|
|
|
|
|
+- Epic B(区域管理)- 当前目标
|
|
|
|
|
+- Epic C(e2e-test-utils 包维护)- 支持性任务
|
|
|
|
|
+
|
|
|
|
|
+### Page Object 设计模式参考
|
|
|
|
|
+
|
|
|
|
|
+基于 `web/tests/e2e/pages/admin/disability-person.page.ts` 的成功经验,区域管理 Page Object 应遵循以下设计模式:
|
|
|
|
|
+
|
|
|
|
|
+**1. 类结构模式:**
|
|
|
|
|
+```typescript
|
|
|
|
|
+export class RegionManagementPage {
|
|
|
|
|
+ readonly page: Page;
|
|
|
|
|
+ // 页面级选择器
|
|
|
|
|
+ readonly pageTitle: Locator;
|
|
|
|
|
+ readonly addButton: Locator;
|
|
|
|
|
+ // ...其他选择器
|
|
|
|
|
+
|
|
|
|
|
+ constructor(page: Page) {
|
|
|
|
|
+ this.page = page;
|
|
|
|
|
+ // 初始化所有选择器
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 导航方法
|
|
|
|
|
+ async goto() { }
|
|
|
|
|
+
|
|
|
|
|
+ // 表单操作方法
|
|
|
|
|
+ async openAddDialog() { }
|
|
|
|
|
+ async fillRegionForm(data: RegionData) { }
|
|
|
|
|
+ async submitForm() { }
|
|
|
|
|
+
|
|
|
|
|
+ // 列表操作方法
|
|
|
|
|
+ async searchByName(name: string) { }
|
|
|
|
|
+ async regionExists(name: string): Promise<boolean> { }
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**2. 选择器定义模式:**
|
|
|
|
|
+- 使用 `page.getByRole()` 优先(无障碍属性)
|
|
|
|
|
+- 使用 `page.getByLabel()` 表单字段
|
|
|
|
|
+- 使用 `page.getByText()` 或 `page.locator()` 作为兜底
|
|
|
|
|
+- 所有选择器定义为 `readonly Locator` 类型
|
|
|
|
|
+
|
|
|
|
|
+**3. 方法命名约定:**
|
|
|
|
|
+- 导航方法: `goto()`
|
|
|
|
|
+- 断言方法: `expectToBeVisible()`, `expectSuccess()`
|
|
|
|
|
+- 操作方法: 动词开头,如 `openAddDialog()`, `fillRegionForm()`
|
|
|
|
|
+- 查询方法: 返回 boolean,如 `regionExists()`
|
|
|
|
|
+
|
|
|
|
|
+### 区域管理功能分析
|
|
|
|
|
+
|
|
|
|
|
+基于现有项目架构和残疾人管理功能的经验,区域管理页面可能包含以下元素:
|
|
|
|
|
+
|
|
|
|
|
+**页面元素(需要验证实际 DOM 结构):**
|
|
|
|
|
+- 页面标题: "区域管理"
|
|
|
|
|
+- 新增按钮: "新增区域" 或类似文本
|
|
|
|
|
+- 搜索输入框: 占位符可能为 "搜索区域名称"
|
|
|
|
|
+- 搜索按钮: "搜索" 或图标按钮
|
|
|
|
|
+- 数据表格: 显示区域列表
|
|
|
|
|
+ - 列: 区域名称、区域代码、层级(省/市/区/街道)、状态、操作
|
|
|
|
|
+
|
|
|
|
|
+**表单字段(需要验证实际 DOM 结构):**
|
|
|
|
|
+- 区域名称: 文本输入框
|
|
|
|
|
+- 区域代码: 文本输入框
|
|
|
|
|
+- 区域层级: Radix UI Select(省/市/区/街道)
|
|
|
|
|
+- 父级区域: 级联 Radix UI Select(选择上级区域)
|
|
|
|
|
+- 状态: Radix UI Select 或 Switch(启用/禁用)
|
|
|
|
|
+- 备注: 文本域
|
|
|
|
|
+
|
|
|
|
|
+**对话框元素(需要验证实际 DOM 结构):**
|
|
|
|
|
+- 添加区域对话框
|
|
|
|
|
+- 编辑区域对话框
|
|
|
|
|
+- 删除确认对话框
|
|
|
|
|
+
|
|
|
|
|
+### 可用的 e2e-test-utils 工具
|
|
|
|
|
+
|
|
|
|
|
+根据 `packages/e2e-test-utils/src/index.ts`,以下工具可用于区域管理测试:
|
|
|
|
|
+
|
|
|
|
|
+```typescript
|
|
|
|
|
+// Radix UI Select 工具
|
|
|
|
|
+import { selectRadixOption, selectRadixOptionAsync } from '@d8d/e2e-test-utils';
|
|
|
|
|
+
|
|
|
|
|
+// 省市区级联选择工具(非常适合区域管理)
|
|
|
|
|
+import { selectCascade, selectProvinceCity } from '@d8d/e2e-test-utils';
|
|
|
|
|
+
|
|
|
|
|
+// 文件上传工具(如果区域有图标上传)
|
|
|
|
|
+import { uploadFileToField } from '@d8d/e2e-test-utils';
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**关键工具 - selectCascade:**
|
|
|
|
|
+```typescript
|
|
|
|
|
+/**
|
|
|
|
|
+ * 级联选择工具
|
|
|
|
|
+ * 用于省市区四级级联选择
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param page - Playwright Page 对象
|
|
|
|
|
+ * @param selections - 选择项数组 [{label: '省份', value: '广东省'}, ...]
|
|
|
|
|
+ * @param options - 配置选项
|
|
|
|
|
+ */
|
|
|
|
|
+async function selectCascade(
|
|
|
|
|
+ page: Page,
|
|
|
|
|
+ selections: Array<{label: string, value: string}>,
|
|
|
|
|
+ options?: CascadeSelectOptions
|
|
|
|
|
+): Promise<void>
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 项目结构笔记
|
|
|
|
|
+
|
|
|
|
|
+**目标文件位置:**
|
|
|
|
|
+```
|
|
|
|
|
+web/tests/e2e/pages/admin/region-management.page.ts
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**导入路径:**
|
|
|
|
|
+```typescript
|
|
|
|
|
+import { Page, Locator } from '@playwright/test';
|
|
|
|
|
+import { selectRadixOption, selectCascade } from '@d8d/e2e-test-utils';
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**测试文件位置(后续 Story):**
|
|
|
|
|
+```
|
|
|
|
|
+web/tests/e2e/specs/admin/region-management.spec.ts
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### TypeScript 类型定义
|
|
|
|
|
+
|
|
|
|
|
+推荐定义以下类型:
|
|
|
|
|
+
|
|
|
|
|
+```typescript
|
|
|
|
|
+/**
|
|
|
|
|
+ * 区域数据接口
|
|
|
|
|
+ */
|
|
|
|
|
+export interface RegionData {
|
|
|
|
|
+ /** 区域名称 */
|
|
|
|
|
+ name: string;
|
|
|
|
|
+ /** 区域代码 */
|
|
|
|
|
+ code?: string;
|
|
|
|
|
+ /** 区域层级(省/市/区/街道) */
|
|
|
|
|
+ level: 'province' | 'city' | 'district' | 'street';
|
|
|
|
|
+ /** 父级区域名称 */
|
|
|
|
|
+ parentRegion?: string;
|
|
|
|
|
+ /** 状态 */
|
|
|
|
|
+ status?: 'enabled' | 'disabled';
|
|
|
|
|
+ /** 备注 */
|
|
|
|
|
+ remark?: string;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 表单提交结果
|
|
|
|
|
+ */
|
|
|
|
|
+export interface FormSubmitResult {
|
|
|
|
|
+ success: boolean;
|
|
|
|
|
+ message?: string;
|
|
|
|
|
+ errorMessage?: string;
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### DOM 结构探索步骤
|
|
|
|
|
+
|
|
|
|
|
+在实现 Page Object 之前,需要探索实际 DOM 结构:
|
|
|
|
|
+
|
|
|
|
|
+1. **启动开发服务器**(如果未运行):
|
|
|
|
|
+ ```bash
|
|
|
|
|
+ cd web && pnpm dev
|
|
|
|
|
+ ```
|
|
|
|
|
+
|
|
|
|
|
+2. **导航到区域管理页面**:
|
|
|
|
|
+ - URL: `/admin/regions` 或类似路径
|
|
|
|
|
+
|
|
|
|
|
+3. **使用 Playwright Inspector 或浏览器开发者工具**:
|
|
|
|
|
+ - 检查页面元素的 `data-testid`, `role`, `aria-label`
|
|
|
|
|
+ - 记录表单字段的选择器策略
|
|
|
|
|
+ - 验证 Radix UI Select 的 DOM 结构
|
|
|
|
|
+
|
|
|
|
|
+4. **记录发现**:
|
|
|
|
|
+ - 对话框触发器的选择器
|
|
|
|
|
+ - 表单字段的 label 文本
|
|
|
|
|
+ - 表格的 CSS 类或结构
|
|
|
|
|
+ - Toast 消息的选择器
|
|
|
|
|
+
|
|
|
|
|
+### 与残疾人管理 Page Object 的主要差异
|
|
|
|
|
+
|
|
|
|
|
+| 方面 | 残疾人管理 | 区域管理 |
|
|
|
|
|
+|------|-----------|----------|
|
|
|
|
|
+| 主要实体 | 残疾人个人 | 区域(省市区街道) |
|
|
|
|
|
+| 树形结构 | 否 | 是(四级层级) |
|
|
|
|
|
+| 级联选择 | 省市区三级 | 可能需要四级 |
|
|
|
|
|
+| 图片上传 | 身份证、残疾证照片 | 可能无或区域图标 |
|
|
|
|
|
+| 动态列表 | 银行卡、备注、回访 | 可能无 |
|
|
|
|
|
+| 删除约束 | 较少 | 有子级区域不能删除 |
|
|
|
|
|
+
|
|
|
|
|
+### 测试隔离策略
|
|
|
|
|
+
|
|
|
|
|
+为支持未来的并行执行(Epic 9),考虑测试数据隔离:
|
|
|
|
|
+
|
|
|
|
|
+```typescript
|
|
|
|
|
+/**
|
|
|
|
|
+ * 生成唯一区域名称(用于测试隔离)
|
|
|
|
|
+ */
|
|
|
|
|
+function generateUniqueRegionName(prefix: string = '测试区域'): string {
|
|
|
|
|
+ const timestamp = Date.now();
|
|
|
|
|
+ const random = Math.floor(Math.random() * 1000);
|
|
|
|
|
+ return `${prefix}_${timestamp}_${random}`;
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 常见陷阱和注意事项
|
|
|
|
|
+
|
|
|
|
|
+**基于 Architecture.md 的 TypeScript + Playwright 陷阱:**
|
|
|
|
|
+
|
|
|
|
|
+1. **DOM 结构假设必须验证 ⚠️**
|
|
|
|
|
+ - 不能基于理想模型开发选择器
|
|
|
|
|
+ - 必须在真实组件上验证 DOM 结构
|
|
|
|
|
+ - Radix UI Select 的 DOM 可能随版本变化
|
|
|
|
|
+
|
|
|
|
|
+2. **选择器策略优先级:**
|
|
|
|
|
+ - `data-testid` → `aria-label` + role → text content
|
|
|
|
|
+ - 推荐在组件上添加 `data-testid`
|
|
|
|
|
+
|
|
|
|
|
+3. **精确文本匹配:**
|
|
|
|
|
+ - 使用 `:text-is()` 而非 `:has-text()`
|
|
|
|
|
+ - 避免部分匹配导致误选
|
|
|
|
|
+
|
|
|
|
|
+4. **超时配置:**
|
|
|
|
|
+ - 使用 `DEFAULT_TIMEOUTS` 常量
|
|
|
|
|
+ - 网络空闲等待使用用户自定义超时值
|
|
|
|
|
+
|
|
|
|
|
+5. **避免使用 page.evaluate():**
|
|
|
|
|
+ - 优先使用 Playwright API
|
|
|
|
|
+ - 使用 `element.textContent()` 而非 `page.evaluate()`
|
|
|
|
|
+
|
|
|
|
|
+## Dev Agent Record
|
|
|
|
|
+
|
|
|
|
|
+### Agent Model Used
|
|
|
|
|
+
|
|
|
|
|
+Claude Opus 4 (claude-opus-4-5-20251101)
|
|
|
|
|
+
|
|
|
|
|
+### Debug Log References
|
|
|
|
|
+
|
|
|
|
|
+### Completion Notes List
|
|
|
|
|
+
|
|
|
|
|
+### File List
|
|
|
|
|
+
|
|
|
|
|
+## Project Context Reference
|
|
|
|
|
+
|
|
|
|
|
+### 关键项目规则摘要
|
|
|
|
|
+
|
|
|
|
|
+**技术栈:**
|
|
|
|
|
+- Playwright 1.55.0 - E2E 测试框架
|
|
|
|
|
+- TypeScript 5.9.3 - 严格模式
|
|
|
|
|
+- @d8d/e2e-test-utils - 内部测试工具包
|
|
|
|
|
+
|
|
|
|
|
+**测试命令:**
|
|
|
|
|
+```bash
|
|
|
|
|
+# 运行所有 E2E 测试
|
|
|
|
|
+pnpm test:e2e:chromium
|
|
|
|
|
+
|
|
|
|
|
+# 运行单个测试文件
|
|
|
|
|
+pnpm test:e2e:chromium region-management
|
|
|
|
|
+
|
|
|
|
|
+# 快速失败模式(调试时使用)
|
|
|
|
|
+timeout 60 pnpm test:e2e:chromium region-management
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**包管理:**
|
|
|
|
|
+- 使用 pnpm(版本 10.18.3)
|
|
|
|
|
+- 内部包使用 workspace 协议: `@d8d/e2e-test-utils@workspace:*`
|
|
|
|
|
+
|
|
|
|
|
+**命名约定:**
|
|
|
|
|
+- 文件名: kebab-case (如: `region-management.page.ts`)
|
|
|
|
|
+- 类名: PascalCase (如: `RegionManagementPage`)
|
|
|
|
|
+- 函数/变量: camelCase (如: `goto()`, `searchByName()`)
|
|
|
|
|
+
|
|
|
|
|
+### 必须遵循的架构决策
|
|
|
|
|
+
|
|
|
|
|
+**来自 Architecture.md 的关键决策:**
|
|
|
|
|
+
|
|
|
|
|
+1. **选择器策略(混合策略优先级):**
|
|
|
|
|
+ - `data-testid` - 最高优先级
|
|
|
|
|
+ - `aria-label` + role - 无障碍标准
|
|
|
|
|
+ - Text content + role - 兜底方案
|
|
|
|
|
+
|
|
|
|
|
+2. **错误处理策略:**
|
|
|
|
|
+ - 使用 `E2ETestError` 类(来自 e2e-test-utils)
|
|
|
|
|
+ - 包含完整 ErrorContext
|
|
|
|
|
+
|
|
|
|
|
+3. **类型系统:**
|
|
|
|
|
+ - 所有方法必须有完整的 TypeScript 类型定义
|
|
|
|
|
+ - 禁止使用 `any` 类型
|
|
|
|
|
+
|
|
|
|
|
+4. **测试基础设施:**
|
|
|
|
|
+ - 测试文件位置: `web/tests/e2e/specs/admin/`
|
|
|
|
|
+ - Page Object 位置: `web/tests/e2e/pages/admin/`
|
|
|
|
|
+ - Fixtures 位置: `web/tests/e2e/fixtures/`
|
|
|
|
|
+
|
|
|
|
|
+### TypeScript + Playwright 陷阱预防
|
|
|
|
|
+
|
|
|
|
|
+**来自 Architecture.md "TypeScript + Playwright 常见陷阱" 部分:**
|
|
|
|
|
+
|
|
|
|
|
+⚠️ **DOM 结构假设必须验证**
|
|
|
|
|
+- 不能基于理想模型开发选择器
|
|
|
|
|
+- 必须在真实组件上验证 DOM 结构
|
|
|
|
|
+- 单元测试无法发现真实 DOM 问题
|
|
|
|
|
+
|
|
|
|
|
+✅ **正确做法:**
|
|
|
|
|
+```typescript
|
|
|
|
|
+// 使用 Playwright API 而非 page.evaluate()
|
|
|
|
|
+const text = await element.textContent();
|
|
|
|
|
+
|
|
|
|
|
+// 使用精确文本匹配
|
|
|
|
|
+page.locator(`.option:text-is("广东省")`)
|
|
|
|
|
+
|
|
|
|
|
+// 使用 data-testid 作为首选
|
|
|
|
|
+page.getByTestId('region-name-input')
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+❌ **避免:**
|
|
|
|
|
+```typescript
|
|
|
|
|
+// 避免使用 page.evaluate()
|
|
|
|
|
+const text = await page.evaluate(el => el.textContent, element);
|
|
|
|
|
+
|
|
|
|
|
+// 避免部分文本匹配
|
|
|
|
|
+page.locator(`.option:has-text("广东省")`)
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 代码质量检查清单
|
|
|
|
|
+
|
|
|
|
|
+基于 Architecture.md 的实现检查清单:
|
|
|
|
|
+
|
|
|
|
|
+**代码质量:**
|
|
|
|
|
+- [ ] 所有导出方法都有完整的 JSDoc
|
|
|
|
|
+- [ ] 内部方法使用 `@internal` 标记
|
|
|
|
|
+- [ ] 错误处理提供友好消息
|
|
|
|
|
+
|
|
|
|
|
+**选择器策略:**
|
|
|
|
|
+- [ ] 优先使用 `data-testid` 或 `getByRole()`
|
|
|
|
|
+- [ ] 文本选择器使用精确匹配
|
|
|
|
|
+- [ ] DOM 结构基于真实组件验证
|
|
|
|
|
+
|
|
|
|
|
+**配置和超时:**
|
|
|
|
|
+- [ ] 超时值使用合理配置
|
|
|
|
|
+- [ ] 网络操作使用 `waitForLoadState('networkidle')`
|
|
|
|
|
+
|
|
|
|
|
+**DOM 操作:**
|
|
|
|
|
+- [ ] 避免使用 `page.evaluate()`
|
|
|
|
|
+- [ ] 优先使用 Playwright API
|
|
|
|
|
+
|
|
|
|
|
+### 参考文档位置
|
|
|
|
|
+
|
|
|
|
|
+| 文档 | 路径 |
|
|
|
|
|
+|------|------|
|
|
|
|
|
+| PRD | `_bmad-output/planning-artifacts/prd.md` |
|
|
|
|
|
+| Architecture | `_bmad-output/planning-artifacts/architecture.md` |
|
|
|
|
|
+| Epics | `_bmad-output/planning-artifacts/epics.md` |
|
|
|
|
|
+| Project Context | `_bmad-output/project-context.md` |
|
|
|
|
|
+| 参考Page Object | `web/tests/e2e/pages/admin/disability-person.page.ts` |
|
|
|
|
|
+| e2e-test-utils | `packages/e2e-test-utils/src/index.ts` |
|
|
|
|
|
+
|
|
|
|
|
+### 相关 Epic 和 Story
|
|
|
|
|
+
|
|
|
|
|
+**前置 Epic:**
|
|
|
|
|
+- Epic 1: ✅ 完成 - Select 工具基础框架
|
|
|
|
|
+- Epic 2: ✅ 完成 - Select 工具在真实 E2E 测试中验证
|
|
|
|
|
+- Epic 3: ✅ 完成 - 文件上传工具、级联选择工具
|
|
|
|
|
+
|
|
|
|
|
+**当前 Epic (Epic 8):**
|
|
|
|
|
+- Story 8.1: 📝 当前 - 创建区域管理 Page Object
|
|
|
|
|
+- Story 8.2: ⏳ 待开始 - 编写区域列表查看测试
|
|
|
|
|
+- Story 8.3: ⏳ 待开始 - 编写添加区域测试
|
|
|
|
|
+- Story 8.4: ⏳ 待开始 - 编写编辑区域测试
|
|
|
|
|
+- Story 8.5: ⏳ 待开始 - 编写删除区域测试
|
|
|
|
|
+- Story 8.6: ⏳ 待开始 - 编写级联选择完整流程测试
|
|
|
|
|
+
|
|
|
|
|
+**后续 Epic:**
|
|
|
|
|
+- Epic 9: 🔄 进行中 - 残疾人管理完整 E2E 测试覆盖
|
|
|
|
|
+
|
|
|
|
|
+## Completion Status
|
|
|
|
|
+
|
|
|
|
|
+**Story ID:** 8.1
|
|
|
|
|
+**Story Key:** 8-1-region-page-object
|
|
|
|
|
+**Epic:** Epic 8 - 区域管理 E2E 测试 (Epic B)
|
|
|
|
|
+**Status:** ready-for-dev
|
|
|
|
|
+
|
|
|
|
|
+**交付物:**
|
|
|
|
|
+- [x] Story 文档创建完成
|
|
|
|
|
+- [ ] RegionManagementPage 类实现
|
|
|
|
|
+- [ ] TypeScript 类型定义
|
|
|
|
|
+- [ ] DOM 结构探索和验证
|
|
|
|
|
+- [ ] 代码审查和测试
|
|
|
|
|
+
|
|
|
|
|
+**下一步操作:**
|
|
|
|
|
+1. 运行 `/bmad:bmm:workflows:dev-story` 开始实现
|
|
|
|
|
+2. 探索区域管理页面的实际 DOM 结构
|
|
|
|
|
+3. 实现 RegionManagementPage 类
|
|
|
|
|
+4. 编写基础测试验证 Page Object 可用性
|
|
|
|
|
+
|
|
|
|
|
+**Ultimate context engine analysis completed - comprehensive developer guide created**
|
|
|
|
|
+
|