|
|
@@ -0,0 +1,270 @@
|
|
|
+# Story 11.1: Platform 管理 Page Object 开发
|
|
|
+
|
|
|
+Status: ready-for-dev
|
|
|
+
|
|
|
+<!-- Note: Validation is optional. Run validate-create-story for quality check before dev-story. -->
|
|
|
+
|
|
|
+## Story
|
|
|
+
|
|
|
+作为测试开发者,
|
|
|
+我想要创建 Platform(平台)管理的 Page Object,
|
|
|
+以便为 Platform 管理功能的 E2E 测试封装页面元素和操作方法。
|
|
|
+
|
|
|
+## Acceptance Criteria
|
|
|
+
|
|
|
+1. **AC1: 创建 PlatformPageObject 类,继承自 BasePageObject**
|
|
|
+ - 类文件路径: `web/tests/e2e/pages/admin/platform-management.page.ts`
|
|
|
+ - 使用 Playwright Page 对象作为构造参数
|
|
|
+ - 遵循项目现有 Page Object 设计模式
|
|
|
+
|
|
|
+2. **AC2: 实现列表页元素定位**
|
|
|
+ - 页面标题定位器
|
|
|
+ - 创建平台按钮
|
|
|
+ - 搜索输入框和搜索按钮
|
|
|
+ - 平台列表表格
|
|
|
+
|
|
|
+3. **AC3: 实现创建/编辑对话框元素定位**
|
|
|
+ - 对话框标题定位器(区分创建/编辑)
|
|
|
+ - 表单字段定位器:
|
|
|
+ - 平台名称(必填)
|
|
|
+ - 联系人
|
|
|
+ - 联系电话
|
|
|
+ - 联系邮箱
|
|
|
+ - 提交按钮(创建/更新)
|
|
|
+ - 取消按钮
|
|
|
+
|
|
|
+4. **AC4: 实现删除确认对话框元素定位**
|
|
|
+ - 确认删除对话框标题
|
|
|
+ - 确认删除按钮
|
|
|
+ - 取消删除按钮
|
|
|
+
|
|
|
+5. **AC5: 提供常用操作方法**
|
|
|
+ - `goto()`: 导航到平台管理页面
|
|
|
+ - `createPlatform()`: 创建平台(完整流程)
|
|
|
+ - `editPlatform()`: 编辑平台(完整流程)
|
|
|
+ - `deletePlatform()`: 删除平台(完整流程)
|
|
|
+ - `searchByName()`: 按平台名称搜索
|
|
|
+ - `platformExists()`: 验证平台是否存在
|
|
|
+
|
|
|
+6. **AC6: 代码质量标准**
|
|
|
+ - 通过 ESLint 检查,无警告和错误
|
|
|
+ - 通过 TypeScript 类型检查,无 `any` 类型
|
|
|
+ - 所有公共方法有完整的 JSDoc 注释
|
|
|
+
|
|
|
+## Tasks / Subtasks
|
|
|
+
|
|
|
+- [ ] 任务 1: 创建 PlatformPageObject 类基础结构 (AC: 1, 6)
|
|
|
+ - [ ] 创建文件 `web/tests/e2e/pages/admin/platform-management.page.ts`
|
|
|
+ - [ ] 定义 PlatformPageObject 类,接受 Page 参数
|
|
|
+ - [ ] 定义类型接口(PlatformData, FormSubmitResult 等)
|
|
|
+
|
|
|
+- [ ] 任务 2: 实现列表页选择器 (AC: 2)
|
|
|
+ - [ ] 定义页面标题选择器
|
|
|
+ - [ ] 定义创建平台按钮选择器
|
|
|
+ - [ ] 定义搜索输入框和按钮选择器
|
|
|
+ - [ ] 定义平台列表表格选择器
|
|
|
+
|
|
|
+- [ ] 任务 3: 实现对话框相关选择器和方法 (AC: 3, 4)
|
|
|
+ - [ ] 定义创建对话框标题选择器
|
|
|
+ - [ ] 定义编辑对话框标题选择器
|
|
|
+ - [ ] 定义表单字段选择器
|
|
|
+ - [ ] 定义提交/取消按钮选择器
|
|
|
+ - [ ] 定义删除确认对话框选择器
|
|
|
+
|
|
|
+- [ ] 任务 4: 实现基础导航和验证方法 (AC: 5, 6)
|
|
|
+ - [ ] 实现 `goto()` 方法
|
|
|
+ - [ ] 实现 `expectToBeVisible()` 方法
|
|
|
+ - [ ] 添加 JSDoc 注释
|
|
|
+
|
|
|
+- [ ] 任务 5: 实现 CRUD 操作方法 (AC: 5)
|
|
|
+ - [ ] 实现 `createPlatform(data)` 方法
|
|
|
+ - [ ] 实现 `editPlatform(platformName, data)` 方法
|
|
|
+ - [ ] 实现 `deletePlatform(platformName)` 方法
|
|
|
+ - [ ] 添加 JSDoc 注释
|
|
|
+
|
|
|
+- [ ] 任务 6: 实现搜索和验证方法 (AC: 5)
|
|
|
+ - [ ] 实现 `searchByName(name)` 方法
|
|
|
+ - [ ] 实现 `platformExists(platformName)` 方法
|
|
|
+ - [ ] 添加 JSDoc 注释
|
|
|
+
|
|
|
+- [ ] 任务 7: 代码质量验证 (AC: 6)
|
|
|
+ - [ ] 运行 ESLint 检查,修复所有问题
|
|
|
+ - [ ] 运行 TypeScript 类型检查,修复所有问题
|
|
|
+ - [ ] 确保 JSDoc 注释完整
|
|
|
+
|
|
|
+## Dev Notes
|
|
|
+
|
|
|
+### Epic 11 背景和目标
|
|
|
+
|
|
|
+**Epic 11: 基础配置管理测试 (Epic F)**
|
|
|
+
|
|
|
+为平台、公司、渠道配置管理编写 E2E 测试,为后续用户管理和跨端测试提供必要的测试数据。
|
|
|
+
|
|
|
+**实体关系链:**
|
|
|
+```
|
|
|
+Platform (平台)
|
|
|
+ ↓ 1:N
|
|
|
+Company (公司) - 必须 platformId
|
|
|
+ ↓ 1:N
|
|
|
+Order (订单) - 必须 companyId
|
|
|
+```
|
|
|
+
|
|
|
+**重要性说明:**
|
|
|
+- Platform 是订单创建的必要条件
|
|
|
+- Company 是订单和企业用户的必要条件(关联 Platform)
|
|
|
+- Story 11.1 是 Epic 11 的第一个 Story,为后续测试提供 Page Object 基础
|
|
|
+
|
|
|
+### 架构模式和约束
|
|
|
+
|
|
|
+**参考现有 Page Object 模式:**
|
|
|
+
|
|
|
+1. **order-management.page.ts** (`web/tests/e2e/pages/admin/order-management.page.ts`)
|
|
|
+ - 使用 Playwright Page 和 Locator 作为核心类型
|
|
|
+ - 定义常量(ORDER_STATUS, WORK_STATUS 等)
|
|
|
+ - 定义数据接口(OrderData, OrderPersonData 等)
|
|
|
+ - 定义网络响应接口(NetworkResponse)
|
|
|
+ - 定义表单提交结果接口(FormSubmitResult)
|
|
|
+ - 提供完整的 CRUD 操作方法
|
|
|
+ - 使用 `@d8d/e2e-test-utils` 工具函数(如 selectRadixOption)
|
|
|
+
|
|
|
+2. **region-management.page.ts** (`web/tests/e2e/pages/admin/region-management.page.ts`)
|
|
|
+ - 使用类似的结构和模式
|
|
|
+ - 定义区域层级常量和类型
|
|
|
+ - 提供树形结构相关方法(expandNode, collapseNode 等)
|
|
|
+ - 处理异步加载和懒加载场景
|
|
|
+
|
|
|
+**关键模式总结:**
|
|
|
+
|
|
|
+| 模式 | 描述 | 示例 |
|
|
|
+|------|------|------|
|
|
|
+| 类型定义 | 定义常量和接口 | ORDER_STATUS, OrderData |
|
|
|
+| 选择器定义 | 在构造函数中定义 Locator | this.pageTitle, this.addButton |
|
|
|
+| 导航方法 | goto() 和 expectToBeVisible() | async goto() |
|
|
|
+| CRUD 方法 | 提供完整流程方法 | async createOrder(data) |
|
|
|
+| 表单处理 | 填写表单 + 提交验证 | async fillOrderForm(), submitForm() |
|
|
|
+| 网络响应 | 监听 API 响应,返回结果 | responseHandler |
|
|
|
+| Toast 验证 | 检查 sonner toast 消息 | errorToast, successToast |
|
|
|
+
|
|
|
+### Platform 管理组件分析
|
|
|
+
|
|
|
+**组件路径:** `allin-packages/platform-management-ui/src/components/PlatformManagement.tsx`
|
|
|
+
|
|
|
+**关键字段:**
|
|
|
+| 字段 | 类型 | 必填 | data-testid |
|
|
|
+|------|------|------|-------------|
|
|
|
+| platformName | string | 是 | platform-name-input |
|
|
|
+| contactPerson | string | 否 | contact-person-input |
|
|
|
+| contactPhone | string | 否 | contact-phone-input |
|
|
|
+| contactEmail | string | 否 | contact-email-input |
|
|
|
+
|
|
|
+**关键 data-testid 属性:**
|
|
|
+- `create-platform-button`: 创建平台按钮
|
|
|
+- `search-input`: 搜索输入框
|
|
|
+- `search-button`: 搜索按钮
|
|
|
+- `edit-button-{id}`: 编辑按钮
|
|
|
+- `delete-button-{id}`: 删除按钮
|
|
|
+- `create-platform-dialog-title`: 创建对话框标题
|
|
|
+- `edit-platform-dialog-title`: 编辑对话框标题
|
|
|
+- `create-submit-button`: 创建提交按钮
|
|
|
+- `update-submit-button`: 更新提交按钮
|
|
|
+- `confirm-delete-button`: 确认删除按钮
|
|
|
+
|
|
|
+**页面路径:** `/admin/platforms`(待确认,可能需要通过实际访问验证)
|
|
|
+
|
|
|
+**API 端点:**
|
|
|
+- `GET /platforms`: 获取平台列表
|
|
|
+- `POST /platforms`: 创建平台
|
|
|
+- `POST /platforms/update`: 更新平台
|
|
|
+- `POST /platforms/delete`: 删除平台
|
|
|
+- `GET /platforms/search`: 搜索平台
|
|
|
+
|
|
|
+### 项目结构约束
|
|
|
+
|
|
|
+**Page Object 存放路径:**
|
|
|
+```
|
|
|
+web/tests/e2e/pages/admin/
|
|
|
+├── order-management.page.ts # 订单管理 Page Object (参考)
|
|
|
+├── region-management.page.ts # 区域管理 Page Object (参考)
|
|
|
+└── platform-management.page.ts # 平台管理 Page Object (本次创建)
|
|
|
+```
|
|
|
+
|
|
|
+**测试文件路径(后续 Story 创建):**
|
|
|
+```
|
|
|
+web/tests/e2e/specs/admin/
|
|
|
+└── platform-*.spec.ts
|
|
|
+```
|
|
|
+
|
|
|
+### TypeScript 严格模式要求
|
|
|
+
|
|
|
+根据 `project-context.md`:
|
|
|
+- 使用 TypeScript 严格模式,无 `any` 类型
|
|
|
+- 所有导出函数都有完整的参数类型和返回值类型
|
|
|
+- 类型定义支持 IDE 自动补全和类型检查
|
|
|
+- 函数命名:camelCase(如 `createPlatform`)
|
|
|
+
|
|
|
+### 测试标准和规范
|
|
|
+
|
|
|
+遵循项目测试标准:
|
|
|
+- `docs/standards/testing-standards.md`
|
|
|
+- `docs/standards/web-ui-testing-standards.md`
|
|
|
+
|
|
|
+**关键选择器策略:**
|
|
|
+1. 优先使用 `data-testid` 属性
|
|
|
+2. 其次使用 ARIA role + name 组合
|
|
|
+3. 谨慎使用文本选择器(避免重复或不稳定)
|
|
|
+
|
|
|
+**等待策略:**
|
|
|
+- 使用 Playwright 的 auto-waiting 机制
|
|
|
+- 关键元素使用 `waitFor({ state: 'visible' })`
|
|
|
+- 网络请求使用 `waitForLoadState('networkidle')` 或 `domcontentloaded`
|
|
|
+
|
|
|
+### 依赖关系
|
|
|
+
|
|
|
+**Epic 11 内部依赖:**
|
|
|
+- Story 11.1 (当前) → Story 11.2 → Story 11.3 → ...
|
|
|
+
|
|
|
+**外部依赖:**
|
|
|
+- Epic 1, 2: `@d8d/e2e-test-utils` 包(已存在,提供 selectRadixOption 等工具)
|
|
|
+
|
|
|
+### 已知问题和注意事项
|
|
|
+
|
|
|
+1. **页面路由待确认:**
|
|
|
+ - 平台管理页面的实际路由可能是 `/admin/platforms` 或其他
|
|
|
+ - 需要通过实际访问验证
|
|
|
+ - 可以参考其他管理页面的路由模式
|
|
|
+
|
|
|
+2. **对话框处理:**
|
|
|
+ - 创建和编辑使用同一个对话框组件,通过 `isCreateForm` 状态区分
|
|
|
+ - 需要分别处理两种模式的定位器和操作
|
|
|
+
|
|
|
+3. **表单验证:**
|
|
|
+ - 平台名称为必填字段
|
|
|
+ - 其他字段为可选字段
|
|
|
+ - 需要验证表单错误提示的显示
|
|
|
+
|
|
|
+### 开发顺序建议
|
|
|
+
|
|
|
+1. 首先定义常量和类型接口
|
|
|
+2. 然后实现构造函数和选择器定义
|
|
|
+3. 实现基础导航和验证方法
|
|
|
+4. 实现对话框操作方法
|
|
|
+5. 实现 CRUD 完整流程方法
|
|
|
+6. 最后实现搜索和辅助方法
|
|
|
+
|
|
|
+## Dev Agent Record
|
|
|
+
|
|
|
+### Agent Model Used
|
|
|
+
|
|
|
+Claude (d8d-model)
|
|
|
+
|
|
|
+### Debug Log References
|
|
|
+
|
|
|
+无(初始创建)
|
|
|
+
|
|
|
+### Completion Notes List
|
|
|
+
|
|
|
+待开发完成后填写
|
|
|
+
|
|
|
+### File List
|
|
|
+
|
|
|
+待开发完成后填写
|