|
@@ -0,0 +1,282 @@
|
|
|
|
|
+# Story 11.6: 验证公司列表显示
|
|
|
|
|
+
|
|
|
|
|
+Status: ready-for-dev
|
|
|
|
|
+
|
|
|
|
|
+<!-- Note: Validation is optional. Run validate-create-story for quality check before dev-story. -->
|
|
|
|
|
+
|
|
|
|
|
+## Story
|
|
|
|
|
+
|
|
|
|
|
+作为测试开发者,
|
|
|
|
|
+我想要编写公司列表查看的 E2E 测试,
|
|
|
|
|
+以便验证公司列表的基本功能和数据展示。
|
|
|
|
|
+
|
|
|
|
|
+## Acceptance Criteria
|
|
|
|
|
+
|
|
|
|
|
+**Given** Epic 11.4 (Company 管理 Page Object) 已完成
|
|
|
|
|
+**When** 编写公司列表查看测试用例
|
|
|
|
|
+**Then** 验证以下场景:
|
|
|
|
|
+
|
|
|
|
|
+1. **公司列表按预期加载**
|
|
|
|
|
+ - 页面成功导航到 `/admin/companies`
|
|
|
|
|
+ - 页面标题"公司管理"显示正确
|
|
|
|
|
+ - 表格组件加载并可见
|
|
|
|
|
+ - 表格数据成功渲染
|
|
|
|
|
+
|
|
|
|
|
+2. **公司数据的正确展示**
|
|
|
|
|
+ - 公司名称显示正确(第0列)
|
|
|
|
|
+ - 关联平台显示正确(第1列)
|
|
|
|
|
+ - 联系人显示正确(第2列)
|
|
|
|
|
+ - 联系电话显示正确(第3列)
|
|
|
|
|
+ - 状态徽章显示正确(第4列:启用/禁用)
|
|
|
|
|
+ - 创建时间显示正确(第5列)
|
|
|
|
|
+ - 操作按钮显示正确(第6列:编辑、删除)
|
|
|
|
|
+
|
|
|
|
|
+3. **列表功能验证**
|
|
|
|
|
+ - 创建公司按钮存在且可点击
|
|
|
|
|
+ - 搜索输入框存在
|
|
|
|
|
+ - 搜索按钮存在
|
|
|
|
|
+ - 当无数据时显示正确提示
|
|
|
|
|
+ - 表格分页功能正常(如适用)
|
|
|
|
|
+
|
|
|
|
|
+4. **测试在真实浏览器中通过**
|
|
|
|
|
+ - 使用 Playwright Chromium 运行
|
|
|
|
|
+ - 所有断言通过
|
|
|
|
|
+ - 无超时失败
|
|
|
|
|
+
|
|
|
|
|
+## Tasks / Subtasks
|
|
|
|
|
+
|
|
|
|
|
+- [ ] Task 1: 创建测试文件基础结构 (AC: #1)
|
|
|
|
|
+ - [ ] Subtask 1.1: 创建 `web/tests/e2e/specs/admin/company-list.spec.ts`
|
|
|
|
|
+ - [ ] Subtask 1.2: 导入必要的依赖和 Page Object
|
|
|
|
|
+ - [ ] Subtask 1.3: 配置测试 fixture
|
|
|
|
|
+
|
|
|
|
|
+- [ ] Task 2: 实现页面加载和基础验证测试 (AC: #1)
|
|
|
|
|
+ - [ ] Subtask 2.1: 测试 - 应该成功导航到公司管理页面
|
|
|
|
|
+ - [ ] Subtask 2.2: 测试 - 应该显示正确的页面标题
|
|
|
|
|
+ - [ ] Subtask 2.3: 测试 - 应该加载公司列表表格
|
|
|
|
|
+
|
|
|
|
|
+- [ ] Task 3: 实现数据显示验证测试 (AC: #2)
|
|
|
|
|
+ - [ ] Subtask 3.1: 测试 - 应该正确显示公司名称
|
|
|
|
|
+ - [ ] Subtask 3.2: 测试 - 应该正确显示关联平台
|
|
|
|
|
+ - [ ] Subtask 3.3: 测试 - 应该正确显示联系人信息
|
|
|
|
|
+ - [ ] Subtask 3.4: 测试 - 应该正确显示状态徽章
|
|
|
|
|
+ - [ ] Subtask 3.5: 测试 - 应该正确显示创建时间
|
|
|
|
|
+
|
|
|
|
|
+- [ ] Task 4: 实现列表功能测试 (AC: #3, #4)
|
|
|
|
|
+ - [ ] Subtask 4.1: 测试 - 应该显示创建公司按钮
|
|
|
|
|
+ - [ ] Subtask 4.2: 测试 - 应该显示搜索输入框
|
|
|
|
|
+ - [ ] Subtask 4.3: 测试 - 无数据时显示正确提示
|
|
|
|
|
+ - [ ] Subtask 4.4: 运行所有测试并验证通过
|
|
|
|
|
+
|
|
|
|
|
+## Dev Notes
|
|
|
|
|
+
|
|
|
|
|
+### Epic 上下文
|
|
|
|
|
+
|
|
|
|
|
+**Epic 11: 基础配置管理测试 (Epic F)**
|
|
|
|
|
+
|
|
|
|
|
+**目标:** 为平台、公司、渠道配置管理编写 E2E 测试,为后续用户管理和跨端测试提供必要的测试数据。
|
|
|
|
|
+
|
|
|
|
|
+**实体关系链:**
|
|
|
|
|
+```
|
|
|
|
|
+Platform (平台)
|
|
|
|
|
+ ↓ 1:N
|
|
|
|
|
+Company (公司) - 必须 platformId
|
|
|
|
|
+ ↓ 1:N
|
|
|
|
|
+Order (订单) - 必须 companyId
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**当前进度:**
|
|
|
|
|
+- 11.1: Platform 管理 Page Object ✅ done
|
|
|
|
|
+- 11.2: 创建测试平台 ✅ done
|
|
|
|
|
+- 11.3: 验证平台列表显示 ✅ done
|
|
|
|
|
+- 11.4: Company 管理 Page Object ✅ done
|
|
|
|
|
+- 11.5: 创建测试公司 backlog
|
|
|
|
|
+- **11.6: 验证公司列表显示** ← 当前故事
|
|
|
|
|
+- 11.7-11.9: 后续故事
|
|
|
|
|
+
|
|
|
|
|
+### 前序故事学习 (Story 11.4)
|
|
|
|
|
+
|
|
|
|
|
+**Story 11.4 (Company Page Object) 已完成:**
|
|
|
|
|
+- Page Object 文件: `web/tests/e2e/pages/admin/company-management.page.ts`
|
|
|
|
|
+- 完整的选择器定义和 CRUD 方法
|
|
|
|
|
+- 使用 `@d8d/e2e-test-utils` 的 `selectRadixOptionAsync`
|
|
|
|
|
+- 支持创建、编辑、删除、搜索功能
|
|
|
|
|
+- 包含完整的 TypeScript 类型定义
|
|
|
|
|
+
|
|
|
|
|
+**关键 API:**
|
|
|
|
|
+```typescript
|
|
|
|
|
+// 导航到页面
|
|
|
|
|
+await companyPage.goto();
|
|
|
|
|
+
|
|
|
|
|
+// 验证页面可见
|
|
|
|
|
+await companyPage.expectToBeVisible();
|
|
|
|
|
+
|
|
|
|
|
+// 检查公司是否存在
|
|
|
|
|
+const exists = await companyPage.companyExists('公司名称');
|
|
|
|
|
+
|
|
|
|
|
+// 创建公司
|
|
|
|
|
+const result = await companyPage.createCompany({
|
|
|
|
|
+ companyName: '测试公司',
|
|
|
|
|
+ contactPerson: '张三',
|
|
|
|
|
+ contactPhone: '13800138000'
|
|
|
|
|
+}, '平台名称');
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**表格列顺序(重要):**
|
|
|
|
|
+- 第0列: 公司名称
|
|
|
|
|
+- 第1列: 平台
|
|
|
|
|
+- 第2列: 联系人
|
|
|
|
|
+- 第3列: 联系电话
|
|
|
|
|
+- 第4列: 状态(启用/禁用)
|
|
|
|
|
+- 第5列: 创建时间
|
|
|
|
|
+- 第6列: 操作(编辑、删除)
|
|
|
|
|
+
|
|
|
|
|
+### 参考测试模式 (Epic 8 区域管理)
|
|
|
|
|
+
|
|
|
|
|
+参考 `web/tests/e2e/specs/admin/region-list.spec.ts` 的测试模式:
|
|
|
|
|
+
|
|
|
|
|
+1. **测试文件结构:**
|
|
|
|
|
+```typescript
|
|
|
|
|
+import { test, expect } from '@playwright/test';
|
|
|
|
|
+import { CompanyManagementPage } from '@/pages/admin/company-management.page';
|
|
|
|
|
+
|
|
|
|
|
+test.describe('公司列表管理', () => {
|
|
|
|
|
+ let companyPage: CompanyManagementPage;
|
|
|
|
|
+
|
|
|
|
|
+ test.beforeEach(async ({ adminLoginPage, page }) => {
|
|
|
|
|
+ // 登录
|
|
|
|
|
+ await adminLoginPage.goto();
|
|
|
|
|
+ await adminLoginPage.login('admin', 'admin123');
|
|
|
|
|
+
|
|
|
|
|
+ companyPage = new CompanyManagementPage(page);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ test.afterEach(async ({ companyPage }) => {
|
|
|
|
|
+ // 清理测试数据
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ test('应该成功加载公司列表页面', async () => {
|
|
|
|
|
+ await companyPage.goto();
|
|
|
|
|
+ // 验证...
|
|
|
|
|
+ });
|
|
|
|
|
+});
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+2. **数据验证模式:**
|
|
|
|
|
+- 使用 `page.locator()` 定位表格元素
|
|
|
|
|
+- 使用 `filter({ hasText })` 精确匹配行
|
|
|
|
|
+- 使用 `nth(index)` 定位列
|
|
|
|
|
+- 使用 `expect().toBeVisible()` 验证可见性
|
|
|
|
|
+- 使用 `expect().toHaveText()` 验证文本内容
|
|
|
|
|
+
|
|
|
|
|
+3. **测试隔离:**
|
|
|
|
|
+- 每个测试使用唯一数据(时间戳)
|
|
|
|
|
+- 测试后清理数据
|
|
|
|
|
+- 避免测试间相互影响
|
|
|
|
|
+
|
|
|
|
|
+### 技术约束和最佳实践
|
|
|
|
|
+
|
|
|
|
|
+**选择器策略(来自 Architecture 文档):**
|
|
|
|
|
+1. 优先使用 `data-testid`
|
|
|
|
|
+2. 使用 `role` + `name` 组合
|
|
|
|
|
+3. 避免使用不稳定的 CSS 类
|
|
|
|
|
+4. 文本匹配使用 `:text-is()` 精确匹配
|
|
|
|
|
+
|
|
|
|
|
+**等待策略:**
|
|
|
|
|
+- 使用 Playwright 的 auto-waiting 机制
|
|
|
|
|
+- 不使用 `waitForTimeout`(除非必要)
|
|
|
|
|
+- 使用 `waitForLoadState('domcontentloaded')` 等待页面加载
|
|
|
|
|
+- 使用 `waitFor({ state: 'visible' })` 等待元素可见
|
|
|
|
|
+
|
|
|
|
|
+**错误处理:**
|
|
|
|
|
+- 捕获并记录有用的错误信息
|
|
|
|
|
+- 使用 `console.debug()` 调试(Vitest 支持)
|
|
|
|
|
+- 失败时自动截图(Playwright 默认)
|
|
|
|
|
+
|
|
|
|
|
+### 测试数据管理
|
|
|
|
|
+
|
|
|
|
|
+**测试平台创建(前置条件):**
|
|
|
|
|
+如果测试需要关联平台,需要先确保测试平台存在:
|
|
|
|
|
+- 可以通过 API 直接创建
|
|
|
|
|
+- 或使用 Story 11.2 创建的测试平台
|
|
|
|
|
+
|
|
|
|
|
+**测试数据清理:**
|
|
|
|
|
+```typescript
|
|
|
|
|
+test.afterEach(async ({ companyPage }) => {
|
|
|
|
|
+ // 清理测试创建的公司
|
|
|
|
|
+ const testCompanies = ['测试公司1', '测试公司2'];
|
|
|
|
|
+ for (const name of testCompanies) {
|
|
|
|
|
+ await companyPage.deleteCompany(name);
|
|
|
|
|
+ }
|
|
|
|
|
+});
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### Project Structure Notes
|
|
|
|
|
+
|
|
|
|
|
+**测试文件位置:**
|
|
|
|
|
+```
|
|
|
|
|
+web/tests/e2e/
|
|
|
|
|
+├── pages/admin/
|
|
|
|
|
+│ └── company-management.page.ts ← 已存在
|
|
|
|
|
+├── specs/admin/
|
|
|
|
|
+│ └── company-list.spec.ts ← 需要创建
|
|
|
|
|
+└── fixtures/
|
|
|
|
|
+ └── (测试数据文件)
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**导入路径:**
|
|
|
|
|
+```typescript
|
|
|
|
|
+// Page Object 导入
|
|
|
|
|
+import { CompanyManagementPage } from '@/pages/admin/company-management.page';
|
|
|
|
|
+
|
|
|
|
|
+// 测试工具导入
|
|
|
|
|
+import { selectRadixOptionAsync } from '@d8d/e2e-test-utils';
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### References
|
|
|
|
|
+
|
|
|
|
|
+**Epic 文档:**
|
|
|
|
|
+- [Source: _bmad-output/planning-artifacts/epics.md#Epic-11]
|
|
|
|
|
+
|
|
|
|
|
+**架构文档:**
|
|
|
|
|
+- [Source: _bmad-output/planning-artifacts/architecture.md] - TypeScript + Playwright 陷阱部分
|
|
|
|
|
+- [Source: docs/standards/e2e-radix-testing.md] - Radix UI E2E 测试标准
|
|
|
|
|
+
|
|
|
|
|
+**前序故事:**
|
|
|
|
|
+- [Source: _bmad-output/implementation-artifacts/11-4-company-page-object.md] - Company Page Object
|
|
|
|
|
+
|
|
|
|
|
+**参考测试实现:**
|
|
|
|
|
+- [Source: web/tests/e2e/specs/admin/region-list.spec.ts] - 区域列表测试参考
|
|
|
|
|
+
|
|
|
|
|
+**项目上下文:**
|
|
|
|
|
+- [Source: _bmad-output/project-context.md] - 技术栈和规则
|
|
|
|
|
+
|
|
|
|
|
+## Dev Agent Record
|
|
|
|
|
+
|
|
|
|
|
+### Agent Model Used
|
|
|
|
|
+
|
|
|
|
|
+Claude Opus 4.5 (claude-opus-4-5-20251101)
|
|
|
|
|
+
|
|
|
|
|
+### Debug Log References
|
|
|
|
|
+
|
|
|
|
|
+无
|
|
|
|
|
+
|
|
|
|
|
+### Completion Notes List
|
|
|
|
|
+
|
|
|
|
|
+1. 创建日期: 2026-01-12
|
|
|
|
|
+2. Epic 状态: in-progress
|
|
|
|
|
+3. 前置依赖: Story 11.4 (Company Page Object) 已完成
|
|
|
|
|
+4. 后续故事: Story 11.7 (Channel Page Object - 可选)
|
|
|
|
|
+
|
|
|
|
|
+### File List
|
|
|
|
|
+
|
|
|
|
|
+**计划创建/修改的文件:**
|
|
|
|
|
+- `web/tests/e2e/specs/admin/company-list.spec.ts` (新建)
|
|
|
|
|
+
|
|
|
|
|
+**依赖文件:**
|
|
|
|
|
+- `web/tests/e2e/pages/admin/company-management.page.ts`
|
|
|
|
|
+- `web/tests/e2e/fixtures/admin-login.fixture.ts`
|
|
|
|
|
+- `packages/e2e-test-utils/src/index.ts`
|
|
|
|
|
+
|
|
|
|
|
+**配置文件:**
|
|
|
|
|
+- `web/tests/e2e/playwright.config.ts`
|