|
|
@@ -0,0 +1,577 @@
|
|
|
+# Story 8.2: 编写区域列表查看测试
|
|
|
+
|
|
|
+Status: ready-for-dev
|
|
|
+
|
|
|
+<!-- Note: Validation is optional. Run validate-create-story for quality check before dev-story. -->
|
|
|
+
|
|
|
+## Story
|
|
|
+
|
|
|
+作为测试开发者,
|
|
|
+我想要编写区域列表查看的 E2E 测试,
|
|
|
+以便验证区域列表的基本功能和数据展示。
|
|
|
+
|
|
|
+## Acceptance Criteria
|
|
|
+
|
|
|
+**Given** 区域管理 Page Object 已创建
|
|
|
+**When** 编写区域列表查看测试用例
|
|
|
+**Then** 验证区域列表按预期加载
|
|
|
+**And** 验证区域数据的正确展示(名称、层级、状态等)
|
|
|
+**And** 验证分页功能(如适用)
|
|
|
+**And** 验证搜索功能(如适用)
|
|
|
+**And** 测试在真实浏览器中通过
|
|
|
+
|
|
|
+## Tasks / Subtasks
|
|
|
+
|
|
|
+- [ ] 创建测试文件基础结构 (AC: #)
|
|
|
+ - [ ] 创建 `web/tests/e2e/specs/admin/region-list.spec.ts`
|
|
|
+ - [ ] 配置 test fixtures(adminLoginPage, regionManagementPage)
|
|
|
+ - [ ] 设置测试组和 beforeEach/afterEach 钩子
|
|
|
+- [ ] 实现页面加载验证测试 (AC: #)
|
|
|
+ - [ ] 测试页面标题显示正确
|
|
|
+ - [ ] 测试新增按钮存在并可点击
|
|
|
+ - [ ] 测试区域树结构加载完成
|
|
|
+ - [ ] 测试默认区域数据展示
|
|
|
+- [ ] 实现区域数据展示验证测试 (AC: #)
|
|
|
+ - [ ] 测试区域名称正确显示
|
|
|
+ - [ ] 测试区域层级标识正确(省/市/区/街道)
|
|
|
+ - [ ] 测试区域状态正确显示(启用/禁用)
|
|
|
+ - [ ] 测试节点展开/收起功能
|
|
|
+- [ ] 实现搜索功能测试(如适用)(AC: #)
|
|
|
+ - [ ] 测试按区域名称搜索
|
|
|
+ - [ ] 测试搜索结果显示
|
|
|
+ - [ ] 测试搜索清空功能
|
|
|
+- [ ] 实现测试数据隔离 (AC: #)
|
|
|
+ - [ ] 每个测试使用独立的测试数据
|
|
|
+ - [ ] 测试后清理测试数据
|
|
|
+ - [ ] 确保测试顺序独立
|
|
|
+
|
|
|
+## Dev Notes
|
|
|
+
|
|
|
+### Epic 8 背景和上下文
|
|
|
+
|
|
|
+**Epic 8: 区域管理 E2E 测试 (Epic B - 业务测试 Epic)**
|
|
|
+
|
|
|
+这是 Epic B(区域管理业务测试)的第二个 Story。Story 8.1 已经创建了 RegionManagementPage Page Object,本 Story 将编写第一个实际测试用例 - 区域列表查看测试。
|
|
|
+
|
|
|
+**依赖:**
|
|
|
+- Epic 1: ✅ 已完成(Select 工具基础框架)
|
|
|
+- Epic 2: ✅ 已完成(Select 工具在真实 E2E 测试中验证)
|
|
|
+- Epic 3: ✅ 已完成(文件上传工具、级联选择工具)
|
|
|
+- Story 8.1: ✅ 已完成(RegionManagementPage Page Object)
|
|
|
+
|
|
|
+**业务分组:**
|
|
|
+- Epic A(残疾人管理)- 已完成基础工具验证
|
|
|
+- Epic B(区域管理)- 当前目标
|
|
|
+- Epic C(订单管理)- 待开发
|
|
|
+
|
|
|
+### 区域管理功能概述
|
|
|
+
|
|
|
+区域管理是一个树形结构管理页面,用于管理省/市/区/街道四级区域数据。根据 Story 8.1 的 DOM 结构分析:
|
|
|
+
|
|
|
+**页面组件分析:**
|
|
|
+- `AreaManagement.tsx` - 主页面组件,显示省市区树形管理
|
|
|
+- `AreaForm.tsx` - 表单组件,用于添加/编辑区域
|
|
|
+- `AreaTreeAsync.tsx` - 树形组件,显示区域层级结构
|
|
|
+
|
|
|
+**页面元素:**
|
|
|
+- 页面标题: "省市区树形管理"
|
|
|
+- 新增按钮: "新增省"
|
|
|
+- 树形容器: `.border.rounded-lg.bg-background`
|
|
|
+- 搜索功能: 需要验证是否存在
|
|
|
+
|
|
|
+**区域树节点结构:**
|
|
|
+- 每个节点显示:区域名称、状态徽章
|
|
|
+- 节点操作按钮:新增子区域、编辑、删除、状态切换
|
|
|
+- 展开/收起按钮:用于控制子节点显示
|
|
|
+
|
|
|
+### RegionManagementPage API 参考
|
|
|
+
|
|
|
+基于 Story 8.1 的实现,RegionManagementPage 提供以下关键方法:
|
|
|
+
|
|
|
+**导航方法:**
|
|
|
+```typescript
|
|
|
+// 导航到区域管理页面
|
|
|
+await regionManagementPage.goto();
|
|
|
+
|
|
|
+// 验证页面元素可见性
|
|
|
+await regionManagementPage.expectToBeVisible();
|
|
|
+
|
|
|
+// 等待树结构加载完成
|
|
|
+await regionManagementPage.waitForTreeLoaded();
|
|
|
+```
|
|
|
+
|
|
|
+**列表查询方法:**
|
|
|
+```typescript
|
|
|
+// 检查区域是否存在
|
|
|
+const exists = await regionManagementPage.regionExists('广东省');
|
|
|
+
|
|
|
+// 获取区域状态
|
|
|
+const status = await regionManagementPage.getRegionStatus('广东省'); // 'enabled' | 'disabled'
|
|
|
+
|
|
|
+// 展开节点
|
|
|
+await regionManagementPage.expandNode('广东省');
|
|
|
+
|
|
|
+// 收起节点
|
|
|
+await regionManagementPage.collapseNode('广东省');
|
|
|
+```
|
|
|
+
|
|
|
+**对话框操作方法:**
|
|
|
+```typescript
|
|
|
+// 打开新增省对话框
|
|
|
+await regionManagementPage.openCreateProvinceDialog();
|
|
|
+
|
|
|
+// 打开新增子区域对话框
|
|
|
+await regionManagementPage.openAddChildDialog('广东省');
|
|
|
+
|
|
|
+// 打开编辑对话框
|
|
|
+await regionManagementPage.openEditDialog('广东省');
|
|
|
+```
|
|
|
+
|
|
|
+### 测试文件结构模式
|
|
|
+
|
|
|
+参考 `web/tests/e2e/specs/admin/disability-person-complete.spec.ts` 的成功模式:
|
|
|
+
|
|
|
+```typescript
|
|
|
+import { test, expect } from '@playwright/test';
|
|
|
+import { AdminLoginPage } from '@/pages/admin/admin-login.page';
|
|
|
+import { RegionManagementPage } from '@/pages/admin/region-management.page';
|
|
|
+
|
|
|
+test.describe('区域列表查看测试', () => {
|
|
|
+ let adminLoginPage: AdminLoginPage;
|
|
|
+ let regionManagementPage: RegionManagementPage;
|
|
|
+
|
|
|
+ test.beforeEach(async ({ page }) => {
|
|
|
+ adminLoginPage = new AdminLoginPage(page);
|
|
|
+ regionManagementPage = new RegionManagementPage(page);
|
|
|
+
|
|
|
+ // 登录
|
|
|
+ await adminLoginPage.goto();
|
|
|
+ await adminLoginPage.login('admin', 'admin123');
|
|
|
+
|
|
|
+ // 导航到区域管理页面
|
|
|
+ await regionManagementPage.goto();
|
|
|
+ });
|
|
|
+
|
|
|
+ test.afterEach(async ({ page }) => {
|
|
|
+ // 清理测试数据
|
|
|
+ // TODO: 实现数据清理逻辑
|
|
|
+ });
|
|
|
+
|
|
|
+ test('应该显示区域列表页面标题', async ({ page }) => {
|
|
|
+ // 测试实现
|
|
|
+ });
|
|
|
+});
|
|
|
+```
|
|
|
+
|
|
|
+### 测试用例设计
|
|
|
+
|
|
|
+**1. 页面加载验证测试:**
|
|
|
+```typescript
|
|
|
+test('应该显示区域列表页面标题', async ({ page }) => {
|
|
|
+ await expect(regionManagementPage.pageTitle).toBeVisible();
|
|
|
+ await expect(regionManagementPage.pageTitle).toContainText('省市区树形管理');
|
|
|
+});
|
|
|
+
|
|
|
+test('应该显示新增省按钮', async ({ page }) => {
|
|
|
+ await expect(regionManagementPage.addProvinceButton).toBeVisible();
|
|
|
+ await expect(regionManagementPage.addProvinceButton).toContainText('新增省');
|
|
|
+});
|
|
|
+
|
|
|
+test('应该等待树结构加载完成', async ({ page }) => {
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
+ // 验证树形容器可见
|
|
|
+ await expect(regionManagementPage.treeContainer).toBeVisible();
|
|
|
+});
|
|
|
+```
|
|
|
+
|
|
|
+**2. 区域数据展示验证测试:**
|
|
|
+```typescript
|
|
|
+test('应该显示默认省份数据', async ({ page }) => {
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
+
|
|
|
+ // 验证默认省份存在(根据实际数据调整)
|
|
|
+ const exists = await regionManagementPage.regionExists('广东省');
|
|
|
+ expect(exists).toBe(true);
|
|
|
+});
|
|
|
+
|
|
|
+test('应该正确显示区域状态', async ({ page }) => {
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
+
|
|
|
+ // 获取区域状态
|
|
|
+ const status = await regionManagementPage.getRegionStatus('广东省');
|
|
|
+ expect(status).toBe('enabled'); // 或 'disabled'
|
|
|
+});
|
|
|
+
|
|
|
+test('应该能展开和收起区域节点', async ({ page }) => {
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
+
|
|
|
+ // 展开节点
|
|
|
+ await regionManagementPage.expandNode('广东省');
|
|
|
+
|
|
|
+ // 验证子节点可见(如广州市)
|
|
|
+ const childExists = await regionManagementPage.regionExists('广州市');
|
|
|
+ expect(childExists).toBe(true);
|
|
|
+
|
|
|
+ // 收起节点
|
|
|
+ await regionManagementPage.collapseNode('广东省');
|
|
|
+});
|
|
|
+```
|
|
|
+
|
|
|
+**3. 搜索功能测试(如适用):**
|
|
|
+```typescript
|
|
|
+test.describe('区域搜索功能', () => {
|
|
|
+ test('应该能按区域名称搜索', async ({ page }) => {
|
|
|
+ // 如果页面有搜索功能
|
|
|
+ // TODO: 实现
|
|
|
+ });
|
|
|
+
|
|
|
+ test('应该能清空搜索结果', async ({ page }) => {
|
|
|
+ // TODO: 实现
|
|
|
+ });
|
|
|
+});
|
|
|
+```
|
|
|
+
|
|
|
+### 测试数据管理策略
|
|
|
+
|
|
|
+**数据隔离原则:**
|
|
|
+- 每个测试应使用独立的测试数据
|
|
|
+- 避免测试之间的数据依赖
|
|
|
+- 测试后清理创建的测试数据
|
|
|
+
|
|
|
+**测试数据生成:**
|
|
|
+```typescript
|
|
|
+/**
|
|
|
+ * 生成唯一区域名称
|
|
|
+ */
|
|
|
+function generateUniqueRegionName(prefix: string = '测试区域'): string {
|
|
|
+ const timestamp = Date.now();
|
|
|
+ const random = Math.floor(Math.random() * 1000);
|
|
|
+ return `${prefix}_${timestamp}_${random}`;
|
|
|
+}
|
|
|
+
|
|
|
+// 使用示例
|
|
|
+const uniqueName = generateUniqueRegionName('测试省');
|
|
|
+```
|
|
|
+
|
|
|
+**数据清理策略:**
|
|
|
+- 选项 1: 使用 API 直接删除测试数据
|
|
|
+- 选项 2: 通过 UI 删除创建的测试数据
|
|
|
+- 选项 3: 使用事务回滚(如可能)
|
|
|
+
|
|
|
+```typescript
|
|
|
+test.afterEach(async ({ page }) => {
|
|
|
+ // 清理本测试创建的数据
|
|
|
+ if (createdRegionName) {
|
|
|
+ try {
|
|
|
+ await regionManagementPage.deleteRegion(createdRegionName);
|
|
|
+ } catch (error) {
|
|
|
+ console.debug('清理测试数据失败:', error);
|
|
|
+ }
|
|
|
+ }
|
|
|
+});
|
|
|
+```
|
|
|
+
|
|
|
+### 选择器策略验证
|
|
|
+
|
|
|
+基于 Story 8.1 的 DOM 结构探索:
|
|
|
+
|
|
|
+**页面选择器(已验证):**
|
|
|
+- 页面标题: `getByText('省市区树形管理')`
|
|
|
+- 新增按钮: `getByRole('button', { name: '新增省' })`
|
|
|
+- 树形容器: `.border.rounded-lg.bg-background`
|
|
|
+- Toast 消息: `[data-sonner-toast][data-type="success|error"]`
|
|
|
+
|
|
|
+**节点操作按钮(已验证):**
|
|
|
+- 展开/收起: 基于 SVG 图标定位
|
|
|
+- 编辑按钮: `xpath=.//ancestor::div[contains(@class, "group")]//button[.//svg[contains(@class, "pencil")]]`
|
|
|
+- 删除按钮: `xpath=.//ancestor::div[contains(@class, "group")]//button[.//svg[contains(@class, "trash")]]`
|
|
|
+- 状态切换: `xpath=.//ancestor::div[contains(@class, "group")]//button[.//svg[contains(@class, "power")]]`
|
|
|
+
|
|
|
+### 项目结构说明
|
|
|
+
|
|
|
+**目标文件位置:**
|
|
|
+```
|
|
|
+web/tests/e2e/specs/admin/region-list.spec.ts
|
|
|
+```
|
|
|
+
|
|
|
+**导入路径:**
|
|
|
+```typescript
|
|
|
+import { AdminLoginPage } from '@/pages/admin/admin-login.page';
|
|
|
+import { RegionManagementPage } from '@/pages/admin/region-management.page';
|
|
|
+```
|
|
|
+
|
|
|
+**测试命令:**
|
|
|
+```bash
|
|
|
+# 运行区域列表测试
|
|
|
+cd web
|
|
|
+pnpm test:e2e:chromium region-list
|
|
|
+
|
|
|
+# 快速失败模式(调试)
|
|
|
+timeout 60 pnpm test:e2e:chromium region-list
|
|
|
+```
|
|
|
+
|
|
|
+### TypeScript + Playwright 陷阱预防
|
|
|
+
|
|
|
+**基于 Architecture.md 的关键陷阱:**
|
|
|
+
|
|
|
+⚠️ **DOM 结构假设必须验证**
|
|
|
+- Story 8.1 已经验证了 DOM 结构
|
|
|
+- 使用已验证的选择器策略
|
|
|
+
|
|
|
+✅ **正确做法:**
|
|
|
+```typescript
|
|
|
+// 使用精确文本匹配
|
|
|
+page.getByText('省市区树形管理', { exact: true })
|
|
|
+
|
|
|
+// 使用已验证的选择器
|
|
|
+await regionManagementPage.waitForTreeLoaded();
|
|
|
+```
|
|
|
+
|
|
|
+❌ **避免:**
|
|
|
+```typescript
|
|
|
+// 避免部分文本匹配
|
|
|
+page.getByText('省市区') // 可能匹配多个元素
|
|
|
+
|
|
|
+// 避免使用 page.evaluate()
|
|
|
+const text = await page.evaluate(() => document.querySelector('...'));
|
|
|
+```
|
|
|
+
|
|
|
+### 与参考测试的对比
|
|
|
+
|
|
|
+**参考测试: disability-person-complete.spec.ts**
|
|
|
+
|
|
|
+| 方面 | 残疾人管理测试 | 区域列表测试 |
|
|
|
+|------|---------------|-------------|
|
|
|
+| 页面结构 | 表单 + 列表 | 树形结构 |
|
|
|
+| 数据展示 | 表格行 | 树节点 |
|
|
|
+| 导航方式 | 直接访问页面 | 直接访问页面 |
|
|
|
+| 测试隔离 | 使用唯一 ID | 使用唯一区域名 |
|
|
|
+| 数据清理 | API 或 UI | API 或 UI |
|
|
|
+
|
|
|
+**关键差异:**
|
|
|
+1. 区域管理使用树形结构而非表格
|
|
|
+2. 区域管理有展开/收起功能
|
|
|
+3. 区域管理的状态切换更复杂(有专门的对话框)
|
|
|
+
|
|
|
+### 测试调试技巧
|
|
|
+
|
|
|
+**1. 查看 DOM 结构:**
|
|
|
+```bash
|
|
|
+# 使用 Playwright Inspector
|
|
|
+cd web
|
|
|
+pnpm test:e2e:chromium region-list --debug
|
|
|
+```
|
|
|
+
|
|
|
+**2. 查看错误上下文:**
|
|
|
+```bash
|
|
|
+# 测试失败后查看
|
|
|
+cat test-results/*/error-context.md
|
|
|
+```
|
|
|
+
|
|
|
+**3. 添加调试输出:**
|
|
|
+```typescript
|
|
|
+test('调试测试', async ({ page }) => {
|
|
|
+ console.debug('当前 URL:', page.url());
|
|
|
+ const isVisible = await regionManagementPage.pageTitle.isVisible();
|
|
|
+ console.debug('标题可见性:', isVisible);
|
|
|
+});
|
|
|
+```
|
|
|
+
|
|
|
+### 可用的 e2e-test-utils 工具
|
|
|
+
|
|
|
+根据 `packages/e2e-test-utils/src/index.ts`:
|
|
|
+
|
|
|
+```typescript
|
|
|
+// 本测试主要使用 Page Object,直接工具较少
|
|
|
+// 可能需要的工具:
|
|
|
+
|
|
|
+import { selectRadixOption, selectRadixOptionAsync } from '@d8d/e2e-test-utils';
|
|
|
+import { selectCascade } from '@d8d/e2e-test-utils';
|
|
|
+import { uploadFileToField } from '@d8d/e2e-test-utils';
|
|
|
+```
|
|
|
+
|
|
|
+**注意:** 本测试主要验证列表查看功能,可能不需要直接使用工具函数。后续 Story(添加、编辑区域)会使用更多工具。
|
|
|
+
|
|
|
+### 常见问题排查
|
|
|
+
|
|
|
+**问题 1: 树结构加载超时**
|
|
|
+- 原因: 异步数据加载未完成
|
|
|
+- 解决: 使用 `waitForTreeLoaded()` 等待加载完成
|
|
|
+
|
|
|
+**问题 2: 节点展开后子节点不可见**
|
|
|
+- 原因: 展开动画未完成
|
|
|
+- 解决: 添加 `waitForTimeout(500)` 或使用 `waitForSelector()`
|
|
|
+
|
|
|
+**问题 3: 区域名称重复导致测试不稳定**
|
|
|
+- 原因: 多个测试使用相同名称
|
|
|
+- 解决: 使用 `generateUniqueRegionName()` 生成唯一名称
|
|
|
+
|
|
|
+### 测试覆盖率目标
|
|
|
+
|
|
|
+**本 Story 的测试覆盖率:**
|
|
|
+- 页面加载验证: 100%
|
|
|
+- 区域数据展示验证: 100%
|
|
|
+- 搜索功能(如存在): 100%
|
|
|
+- 节点展开/收起: 100%
|
|
|
+
|
|
|
+**测试通过率目标:** 连续运行 10 次,100% 通过
|
|
|
+
|
|
|
+### 后续 Story 依赖
|
|
|
+
|
|
|
+本测试是 Epic 8 的第一个实际测试,后续 Story 依赖:
|
|
|
+- Story 8.3: 添加区域测试 - 依赖列表查看
|
|
|
+- Story 8.4: 编辑区域测试 - 依赖列表查看
|
|
|
+- Story 8.5: 删除区域测试 - 依赖列表查看
|
|
|
+
|
|
|
+## Dev Agent Record
|
|
|
+
|
|
|
+### Agent Model Used
|
|
|
+
|
|
|
+<!-- 开发完成后填写 -->
|
|
|
+
|
|
|
+### 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
|
|
|
+# 运行区域列表测试
|
|
|
+cd web
|
|
|
+pnpm test:e2e:chromium region-list
|
|
|
+
|
|
|
+# 快速失败模式(调试)
|
|
|
+timeout 60 pnpm test:e2e:chromium region-list
|
|
|
+
|
|
|
+# 运行所有 E2E 测试
|
|
|
+pnpm test:e2e:chromium
|
|
|
+```
|
|
|
+
|
|
|
+**包管理:**
|
|
|
+- 使用 pnpm(版本 10.18.3)
|
|
|
+- 内部包使用 workspace 协议
|
|
|
+
|
|
|
+**命名约定:**
|
|
|
+- 测试文件名: kebab-case + `.spec.ts` 后缀
|
|
|
+- 测试组: 使用 `test.describe()` 分组
|
|
|
+- 测试名称: 中文描述,格式 "应该..."
|
|
|
+
|
|
|
+### 必须遵循的架构决策
|
|
|
+
|
|
|
+**来自 Architecture.md 的关键决策:**
|
|
|
+
|
|
|
+1. **选择器策略(混合策略优先级):**
|
|
|
+ - `data-testid` - 最高优先级
|
|
|
+ - `aria-label` + role - 无障碍标准
|
|
|
+ - Text content + role - 兜底方案
|
|
|
+
|
|
|
+2. **测试基础设施:**
|
|
|
+ - 测试文件位置: `web/tests/e2e/specs/admin/`
|
|
|
+ - Page Object 位置: `web/tests/e2e/pages/admin/`
|
|
|
+ - Fixtures 位置: `web/tests/e2e/fixtures/`
|
|
|
+
|
|
|
+3. **测试隔离:**
|
|
|
+ - 每个测试使用独立数据
|
|
|
+ - 测试后清理数据
|
|
|
+ - 支持并行执行
|
|
|
+
|
|
|
+### TypeScript + Playwright 陷阱预防
|
|
|
+
|
|
|
+⚠️ **DOM 结构假设必须验证**
|
|
|
+- Story 8.1 已验证 DOM 结构
|
|
|
+- 使用 RegionManagementPage 的封装方法
|
|
|
+
|
|
|
+✅ **正确做法:**
|
|
|
+```typescript
|
|
|
+// 使用 Page Object 封装的方法
|
|
|
+await regionManagementPage.waitForTreeLoaded();
|
|
|
+const exists = await regionManagementPage.regionExists('广东省');
|
|
|
+await regionManagementPage.expandNode('广东省');
|
|
|
+```
|
|
|
+
|
|
|
+❌ **避免:**
|
|
|
+```typescript
|
|
|
+// 避免直接操作 DOM
|
|
|
+await page.locator('.tree-node').click();
|
|
|
+```
|
|
|
+
|
|
|
+### 代码质量检查清单
|
|
|
+
|
|
|
+**代码质量:**
|
|
|
+- [ ] 测试用例有清晰的描述
|
|
|
+- [ ] 使用 `test.describe()` 组织相关测试
|
|
|
+- [ ] 每个测试独立运行,不依赖其他测试
|
|
|
+
|
|
|
+**测试数据:**
|
|
|
+- [ ] 使用唯一标识符避免数据冲突
|
|
|
+- [ ] 测试后清理测试数据
|
|
|
+- [ ] 使用 `beforeEach`/`afterEach` 钩子
|
|
|
+
|
|
|
+**错误处理:**
|
|
|
+- [ ] 失败时有清晰的错误消息
|
|
|
+- [ ] 使用 try-catch 处理清理操作
|
|
|
+
|
|
|
+### 参考文档位置
|
|
|
+
|
|
|
+| 文档 | 路径 |
|
|
|
+|------|------|
|
|
|
+| 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` |
|
|
|
+| Story 8.1 | `_bmad-output/implementation-artifacts/8-1-region-page-object.md` |
|
|
|
+| RegionManagementPage | `web/tests/e2e/pages/admin/region-management.page.ts` |
|
|
|
+| 参考测试 | `web/tests/e2e/specs/admin/disability-person-complete.spec.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.2
|
|
|
+**Story Key:** 8-2-region-list-test
|
|
|
+**Epic:** Epic 8 - 区域管理 E2E 测试 (Epic B)
|
|
|
+**Status:** ready-for-dev
|
|
|
+
|
|
|
+**交付物:**
|
|
|
+- [x] Story 文档创建完成
|
|
|
+- [ ] 区域列表查看测试实现
|
|
|
+- [ ] 测试在真实浏览器中通过
|
|
|
+- [ ] 测试连续运行 10 次验证
|
|
|
+
|
|
|
+**下一步操作:**
|
|
|
+1. 实现 `web/tests/e2e/specs/admin/region-list.spec.ts`
|
|
|
+2. 运行测试并验证通过
|
|
|
+3. 进入 Story 8.3(添加区域测试)
|