Ver código fonte

feat(story-13.6): 添加首页看板数据联动专项测试

- 在 Epic 13 中新增 Story 13.6
- 验证后台操作后企业小程序首页看板的数据同步
- 区别于 Story 13.1:13.1 验证订单列表,13.6 验证首页看板
- 包含 7 个验收标准:订单卡片、数量统计、状态徽章等

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
yourname 3 dias atrás
pai
commit
281dc04d39

+ 625 - 0
_bmad-output/implementation-artifacts/13-6-dashboard-sync.md

@@ -0,0 +1,625 @@
+# Story 13.6: 首页看板数据联动专项测试
+
+Status: ready-for-dev
+
+<!-- Note: Validation is optional. Run validate-create-story for quality check before dev-story. -->
+
+## Story
+
+作为测试开发者,
+我想要验证后台操作后企业小程序首页看板的数据同步,
+以便确保用户在小程序首页能看到最新的业务数据统计和订单卡片。
+
+## Acceptance Criteria
+
+### AC1: 后台创建订单 → 首页看板订单卡片同步
+**Given** 后台订单管理功能已完成(Epic 10)
+**When** 测试者在管理后台创建新订单
+**Then** 测试应验证以下功能:
+- 使用 OrderManagementPage 创建测试订单
+- 刷新企业小程序首页看板
+- 验证新订单的卡片显示在首页
+- 验证卡片信息完整(订单名称、状态、日期等)
+
+### AC2: 首页看板订单数量统计同步
+**Given** 后台已创建多个订单
+**When** 刷新企业小程序首页看板
+**Then** 测试应验证以下功能:
+- 验证订单总数统计正确
+- 验证各状态订单数量统计正确(进行中、已完成等)
+- 验证数量徽章显示正确
+
+### AC3: 首页看板状态徽章同步
+**Given** 后台订单状态发生变化
+**When** 订单状态被更新(如激活订单、关闭订单)
+**Then** 测试应验证以下功能:
+- 小程序首页订单卡片的状态徽章更新正确
+- 状态颜色区分正确(进行中、已完成、草稿等)
+
+### AC4: 首页看板卡片信息完整性验证
+**Given** 首页看板显示订单卡片
+**When** 查看订单卡片信息
+**Then** 测试应验证以下功能:
+- 卡片显示订单名称
+- 卡片显示订单状态
+- 卡片显示预计开始日期或创建日期
+- 卡片显示关联人数(如有)
+- 卡片信息与后台订单详情一致
+
+### AC5: 数据刷新时效性验证
+**Given** 后台操作已完成
+**When** 刷新小程序首页看板
+**Then** 测试应验证以下场景:
+- 在正常情况下,数据应在 3 秒内同步
+- 支持轮询等待机制(最多等待 10 秒)
+- 验证下拉刷新功能触发数据更新
+
+### AC6: 与订单列表页的区别验证
+**Given** 本 Story 与 Story 13.1 测试范围不同
+**When** 执行本 Story 测试
+**Then** 测试范围应明确区分:
+- Story 13.1: 验证后台创建订单 → 订单**列表**页显示
+- Story 13.6: 验证后台创建订单 → 首页**看板**卡片显示
+- 两个 Story 测试不同的页面元素和功能
+
+### AC7: 代码质量标准
+**Given** 遵循项目测试规范
+**When** 编写测试代码
+**Then** 代码应符合以下标准:
+- 使用 TIMEOUTS 常量定义超时
+- 使用 data-testid 选择器(优先级高于文本选择器)
+- 测试文件命名:`dashboard-sync.spec.ts`
+- 完整的测试描述和注释
+- TypeScript 类型安全
+- 通过 `pnpm typecheck` 类型检查
+
+## Tasks / Subtasks
+
+- [ ] 任务 1: 扩展 EnterpriseMiniPage 支持首页看板 (AC: #1, #2, #3, #4)
+  - [ ] 1.1 添加首页看板选择器(订单卡片容器、统计徽章等)
+  - [ ] 1.2 实现 getDashboardOrderCards() 方法
+  - [ ] 1.3 实现 getOrderCountBadge() 方法
+  - [ ] 1.4 实现下拉刷新方法 refreshDashboard()
+  - [ ] 1.5 实现 getDashboardStatistics() 方法
+
+- [ ] 任务 2: 创建跨端首页看板同步测试文件 (AC: #1, #6, #7)
+  - [ ] 2.1 创建 `web/tests/e2e/specs/cross-platform/dashboard-sync.spec.ts`
+  - [ ] 2.2 配置测试 fixtures(adminLoginPage, orderManagementPage, enterpriseMiniPage)
+  - [ ] 2.3 添加测试前置条件(需要测试平台、公司、企业用户数据)
+
+- [ ] 任务 3: 实现订单卡片同步验证测试 (AC: #1, #4)
+  - [ ] 3.1 编写"后台创建订单 → 首页看板显示卡片"测试
+  - [ ] 3.2 验证卡片信息完整性(名称、状态、日期、人数)
+  - [ ] 3.3 验证卡片信息与后台订单详情一致
+
+- [ ] 任务 4: 实现订单数量统计同步测试 (AC: #2)
+  - [ ] 4.1 编写"订单总数统计正确"测试
+  - [ ] 4.2 编写"各状态订单数量统计正确"测试
+  - [ ] 4.3 验证数量徽章显示
+
+- [ ] 任务 5: 实现状态徽章同步测试 (AC: #3)
+  - [ ] 5.1 编写"激活订单 → 状态徽章更新"测试
+  - [ ] 5.2 编写"关闭订单 → 状态徽章更新"测试
+  - [ ] 5.3 验证状态颜色区分正确
+
+- [ ] 任务 6: 实现数据刷新时效性测试 (AC: #5)
+  - [ ] 6.1 实现轮询等待机制
+  - [ ] 6.2 验证正常同步时间(≤ 3 秒)
+  - [ ] 6.3 验证下拉刷新功能
+
+- [ ] 任务 7: 实现测试数据清理策略 (AC: #4)
+  - [ ] 7.1 添加 afterEach 钩子清理订单数据
+  - [ ] 7.2 验证清理后首页看板不再显示该订单
+
+- [ ] 任务 8: 验证代码质量 (AC: #7)
+  - [ ] 8.1 运行 `pnpm typecheck` 验证类型检查
+  - [ ] 8.2 运行测试确保所有测试通过
+  - [ ] 8.3 验证选择器使用 data-testid
+
+## Dev Notes
+
+### Epic 13 背景和依赖
+
+**Epic 13: 跨端数据同步测试 (Epic E)**
+
+- **目标**: 验证后台操作后小程序端的数据同步,覆盖完整的业务流程
+- **业务分组**: Epic E(跨端数据同步测试)
+- **背景**: 真实用户旅程跨越管理后台和小程序,需要验证数据同步的正确性和时效性
+- **依赖**:
+  - Epic 10: ✅ 已完成(订单管理 E2E 测试)
+  - Epic 12: 🔄 进行中(小程序登录测试)
+
+**Epic 13 Story 依赖关系:**
+```
+Story 13.1: 后台创建订单 → 企业小程序**订单列表**验证 ✅
+Story 13.2: 后台编辑订单 → 企业小程序验证
+Story 13.3: 后台添加人员 → 人才小程序验证
+Story 13.4: 后台更新状态 → 双小程序验证
+Story 13.5: 跨端测试稳定性验证
+Story 13.6: 首页看板数据联动专项测试 ← 当前 Story
+```
+
+### 与 Story 13.1 的区别
+
+| 维度 | Story 13.1 | Story 13.6 |
+|------|-----------|-----------|
+| **验证目标** | 订单**列表**页 | 首页**看板** |
+| **验证内容** | 订单列表项显示、订单详情完整性 | 订单卡片、统计数量、状态徽章 |
+| **测试场景** | 创建订单 → 点击订单列表 → 验证详情 | 创建订单 → 查看首页 → 验证卡片和统计 |
+| **测试方法** | getOrderList(), openDetailDialog() | getDashboardOrderCards(), getOrderCountBadge() |
+| **数据时效** | 订单列表数据 | 首页看板统计、下拉刷新 |
+
+### 企业小程序首页看板结构(预期)
+
+基于小程序常见模式,首页看板预期包含以下元素:
+
+**订单卡片区域:**
+```
+┌─────────────────────────────┐
+│  首页看板                    │
+├─────────────────────────────┤
+│  统计卡片:                  │
+│  ┌─────────┬─────────┐      │
+│  │ 全部订单 │ 进行中  │      │
+│  │   12    │   5     │      │
+│  └─────────┴─────────┘      │
+├─────────────────────────────┤
+│  订单卡片列表:              │
+│  ┌─────────────────────┐    │
+│  │ 订单名称:测试订单    │    │
+│  │ 状态:进行中         │    │
+│  │ 日期:2026-01-15     │    │
+│  │ 人数:10 人          │    │
+│  └─────────────────────┘    │
+│  ┌─────────────────────┐    │
+│  │ 订单名称:测试订单2   │    │
+│  │ 状态:已完成         │    │
+│  └─────────────────────┘    │
+└─────────────────────────────┘
+```
+
+**预期 data-testid:**
+```typescript
+const DASHBOARD_SELECTORS = {
+  dashboard: 'mini-dashboard',
+  orderCard: 'mini-order-card',
+  orderName: 'mini-order-card-name',
+  orderStatus: 'mini-order-card-status',
+  orderDate: 'mini-order-card-date',
+  orderPersonCount: 'mini-order-card-person-count',
+  orderCountBadge: 'mini-order-count-badge',
+  orderStatusBadge: 'mini-order-status-badge',
+  refreshButton: 'mini-dashboard-refresh',
+};
+```
+
+### Epic 10 关键经验(订单管理)
+
+从已完成的 Epic 10 中学习到的订单管理模式:
+
+**OrderManagementPage 可用方法:**
+```typescript
+// 页面导航
+async goto(): Promise<void>
+async expectToBeVisible(): Promise<void>
+
+// 订单 CRUD
+async createOrder(data: OrderData): Promise<FormSubmitResult>
+async editOrder(orderId: string, data: OrderData): Promise<FormSubmitResult>
+async deleteOrder(orderId: string): Promise<FormSubmitResult>
+async activateOrder(orderName: string): Promise<FormSubmitResult>
+async closeOrder(orderName: string): Promise<FormSubmitResult>
+
+// 订单状态
+async getOrderStatus(orderName: string): Promise<string>
+```
+
+**订单状态流转:**
+```typescript
+// 订单状态
+enum OrderStatus {
+  DRAFT = '草稿',
+  CONFIRMED = '已确认',
+  IN_PROGRESS = '进行中',
+  COMPLETED = '已完成',
+  CANCELLED = '已取消',
+}
+
+// 激活订单(草稿 → 进行中)
+await orderManagementPage.activateOrder(orderName);
+
+// 关闭订单(进行中 → 已完成)
+await orderManagementPage.closeOrder(orderName);
+```
+
+### Epic 12 关键经验(小程序登录)
+
+从已完成的 Epic 12 中学习到的小程序模式:
+
+**EnterpriseMiniPage 已有方法:**
+```typescript
+// 页面导航
+async goto(): Promise<void>
+async expectToBeVisible(): Promise<void>
+
+// 登录方法
+async login(phone: string, password: string): Promise<void>
+async expectLoginSuccess(): Promise<void>
+
+// Token 管理
+async getToken(): Promise<string | null>
+async clearAuth(): Promise<void>
+```
+
+**企业小程序登录流程:**
+```typescript
+await enterpriseMiniPage.goto();
+await enterpriseMiniPage.login(
+  '13800138000',  // 企业用户手机号
+  'password123'
+);
+await enterpriseMiniPage.expectLoginSuccess();
+```
+
+### 多 Page 对象管理策略
+
+使用与 Story 13.1 相同的多 Context 策略:
+
+```typescript
+type CrossPlatformFixtures = {
+  adminPage: Page;
+  miniPage: Page;
+  orderManagementPage: OrderManagementPage;
+  enterpriseMiniPage: EnterpriseMiniPage;
+};
+
+export const test = base.extend<CrossPlatformFixtures>({
+  adminPage: async ({ browser }, use) => {
+    const context = await browser.newContext();
+    const page = await context.newPage();
+    await use(page);
+    await context.close();
+  },
+  miniPage: async ({ browser }, use) => {
+    const context = await browser.newContext();
+    const page = await context.newPage();
+    await use(page);
+    await context.close();
+  },
+  // ...
+});
+```
+
+### EnterpriseMiniPage 扩展方法
+
+需要添加以下方法到 `enterprise-mini.page.ts`:
+
+```typescript
+/**
+ * 获取首页看板的订单卡片列表
+ */
+async getDashboardOrderCards(): Promise<DashboardOrderCard[]> {
+  // 实现逻辑
+}
+
+/**
+ * 获取订单数量统计徽章
+ */
+async getOrderCountBadge(filter?: 'all' | 'inProgress' | 'completed'): Promise<number> {
+  // 实现逻辑
+}
+
+/**
+ * 刷新首页看板数据
+ */
+async refreshDashboard(): Promise<void> {
+  // 实现下拉刷新
+}
+
+/**
+ * 获取首页看板统计数据
+ */
+async getDashboardStatistics(): Promise<DashboardStatistics> {
+  // 实现逻辑
+}
+
+/**
+ * 等待订单卡片出现在首页看板
+ */
+async waitForOrderCard(orderName: string, timeout?: number): Promise<boolean> {
+  // 实现轮询等待
+}
+```
+
+**类型定义:**
+```typescript
+interface DashboardOrderCard {
+  name: string;
+  status: string;
+  date: string;
+  personCount?: number;
+  orderId: string;
+}
+
+interface DashboardStatistics {
+  totalCount: number;
+  inProgressCount: number;
+  completedCount: number;
+  draftCount: number;
+}
+```
+
+### 数据同步等待策略
+
+与 Story 13.1 类似的轮询等待模式:
+
+```typescript
+async waitForOrderCard(
+  orderName: string,
+  timeout: number = 10000
+): Promise<boolean> {
+  const startTime = Date.now();
+  while (Date.now() - startTime < timeout) {
+    const cards = await this.getDashboardOrderCards();
+    if (cards.some(c => c.name === orderName)) {
+      return true;
+    }
+    await this.page.waitForTimeout(500);
+  }
+  return false;
+}
+```
+
+### 测试数据准备策略
+
+**前置条件:**
+1. 需要测试平台数据(使用 Story 11.2 创建的平台)
+2. 需要测试公司数据(使用 Story 11.5 创建的公司)
+3. 需要企业用户数据(使用 Story 12.2 创建的企业用户)
+
+**测试数据唯一性:**
+```typescript
+const timestamp = Date.now();
+const orderData = {
+  name: `首页看板测试_${timestamp}`,
+  expectedStartDate: '2026-01-15',
+  platformId: 1,
+  companyId: 1,
+};
+```
+
+### 测试数据清理策略
+
+```typescript
+test.afterEach(async ({ orderManagementPage, orderName }) => {
+  // 在后台删除测试订单
+  await orderManagementPage.goto();
+  await orderManagementPage.deleteOrder(orderName);
+});
+```
+
+### 项目结构
+
+**新建文件:**
+- `web/tests/e2e/specs/cross-platform/dashboard-sync.spec.ts`
+- 扩展 `web/tests/e2e/pages/mini/enterprise-mini.page.ts`(添加首页看板方法)
+
+**相关参考文件:**
+- `web/tests/e2e/pages/admin/order-management.page.ts` (Epic 10)
+- `web/tests/e2e/pages/mini/enterprise-mini.page.ts` (Epic 12)
+- `web/tests/e2e/specs/cross-platform/order-create-sync.spec.ts` (Story 13.1)
+- `web/tests/e2e/specs/admin/dashboard.spec.ts` (管理后台 dashboard 测试)
+
+### 选择器策略
+
+**优先级(遵循项目标准):**
+1. `data-testid` 属性(最高优先级)
+2. ARIA 属性 + role
+3. 文本内容(最低优先级,避免使用)
+
+**需要在小程序首页看板页面添加 data-testid:**
+- `mini-dashboard` - 首页看板容器
+- `mini-order-card` - 订单卡片
+- `mini-order-card-name` - 订单名称
+- `mini-order-card-status` - 订单状态
+- `mini-order-card-date` - 订单日期
+- `mini-order-card-person-count` - 订单人数
+- `mini-order-count-badge` - 订单数量徽章
+- `mini-order-status-badge` - 状态徽章
+- `mini-dashboard-refresh` - 刷新按钮
+
+### TypeScript 类型定义
+
+**首页看板数据类型:**
+```typescript
+interface DashboardOrderCard {
+  /** 订单 ID */
+  orderId: string;
+  /** 订单名称 */
+  name: string;
+  /** 订单状态 */
+  status: OrderStatus;
+  /** 预计开始日期 */
+  expectedStartDate?: string;
+  /** 关联人数 */
+  personCount?: number;
+}
+
+interface DashboardStatistics {
+  /** 全部订单数 */
+  totalCount: number;
+  /** 进行中订单数 */
+  inProgressCount: number;
+  /** 已完成订单数 */
+  completedCount: number;
+  /** 草稿订单数 */
+  draftCount: number;
+}
+
+interface DashboardSyncVerificationResult {
+  /** 同步是否成功 */
+  synced: boolean;
+  /** 同步耗时(毫秒) */
+  syncTime: number;
+  /** 后台订单数据 */
+  adminOrder: OrderData;
+  /** 首页看板订单卡片 */
+  dashboardCard?: DashboardOrderCard;
+  /** 统计数据 */
+  statistics?: DashboardStatistics;
+}
+```
+
+### 测试超时配置
+
+**使用 TIMEOUTS 常量:**
+```typescript
+import { TIMEOUTS } from '../../utils/timeouts';
+
+// 首页看板数据同步等待时间
+const SYNC_TIMEOUT = TIMEOUTS.networkIdle; // 10000ms
+
+// 首页数据刷新等待时间
+const REFRESH_TIMEOUT = TIMEOUTS.PAGE_LOAD; // 30000ms
+
+// 轮询检查间隔
+const POLL_INTERVAL = 500;
+```
+
+### 下拉刷新实现
+
+小程序通常支持下拉刷新功能:
+
+```typescript
+/**
+ * 下拉刷新首页看板数据
+ */
+async refreshDashboard(): Promise<void> {
+  // 方案 1: 使用 Playwright 模拟下拉手势
+  await this.page.touchstart(0, 0);
+  await this.page.touchmove(0, 200);
+  await this.page.touchend();
+
+  // 等待刷新完成
+  await this.page.waitForTimeout(2000);
+
+  // 方案 2: 如果有刷新按钮,点击刷新按钮
+  // await this.refreshButton.click();
+}
+```
+
+### 调试技巧
+
+**首页看板调试:**
+1. 使用 `page.screenshot()` 在关键步骤截图
+2. 使用 `console.debug()` 输出订单卡片和统计信息
+3. 分别记录后台操作和小程序刷新的时间
+
+**同步问题调试:**
+- 检查网络请求(使用 Playwright 的 network 监听)
+- 检查首页看板 API 响应
+- 验证下拉刷新触发的请求
+
+### 参考文档
+
+**架构文档:**
+- `_bmad-output/planning-artifacts/epics.md#Epic 13`
+- `_bmad-output/project-context.md`
+- `docs/standards/e2e-radix-testing.md`
+
+**相关 Story 文档:**
+- `10-1-order-page-object.md` (订单管理 Page Object)
+- `10-7-order-status-tests.md` (订单状态测试)
+- `12-4-enterprise-mini-page-object.md` (企业小程序 Page Object)
+- `12-5-enterprise-mini-login.md` (企业小程序登录测试)
+- `13-1-order-create-sync.md` (订单列表同步测试)
+
+### 测试场景示例
+
+**场景 1: 创建订单 → 首页看板显示卡片**
+```typescript
+test('后台创建订单后首页看板显示订单卡片', async ({
+  adminPage, miniPage, orderManagementPage, enterpriseMiniPage
+}) => {
+  // 1. 后台创建订单
+  const orderName = `看板测试_${Date.now()}`;
+  await orderManagementPage.goto();
+  await orderManagementPage.createOrder({
+    name: orderName,
+    expectedStartDate: '2026-01-15',
+  });
+
+  // 2. 小程序登录并刷新首页
+  await enterpriseMiniPage.goto();
+  await enterpriseMiniPage.login('13800138000', 'password123');
+  await enterpriseMiniPage.expectLoginSuccess();
+  await enterpriseMiniPage.refreshDashboard();
+
+  // 3. 验证首页看板显示订单卡片
+  const cards = await enterpriseMiniPage.getDashboardOrderCards();
+  expect(cards.some(c => c.name === orderName)).toBe(true);
+
+  // 4. 验证卡片信息完整性
+  const card = cards.find(c => c.name === orderName);
+  expect(card?.status).toBeTruthy();
+  expect(card?.expectedStartDate).toBe('2026-01-15');
+});
+```
+
+**场景 2: 订单状态变化 → 首页看板状态徽章更新**
+```typescript
+test('激活订单后首页看板状态徽章更新', async ({
+  adminPage, miniPage, orderManagementPage, enterpriseMiniPage
+}) => {
+  // 1. 创建草稿订单
+  const orderName = `状态测试_${Date.now()}`;
+  await orderManagementPage.goto();
+  await orderManagementPage.createOrder({
+    name: orderName,
+    expectedStartDate: '2026-01-15',
+  });
+
+  // 2. 验证首页看板显示草稿状态
+  await enterpriseMiniPage.goto();
+  await enterpriseMiniPage.refreshDashboard();
+  let cards = await enterpriseMiniPage.getDashboardOrderCards();
+  let card = cards.find(c => c.name === orderName);
+  expect(card?.status).toBe('草稿');
+
+  // 3. 激活订单
+  await orderManagementPage.goto();
+  await orderManagementPage.activateOrder(orderName);
+
+  // 4. 验证首页看板状态更新
+  await enterpriseMiniPage.refreshDashboard();
+  cards = await enterpriseMiniPage.getDashboardOrderCards();
+  card = cards.find(c => c.name === orderName);
+  expect(card?.status).toBe('进行中');
+});
+```
+
+## Dev Agent Record
+
+### Agent Model Used
+
+_Created by create-story workflow_
+
+### Debug Log References
+
+_Implementation phase - no debug yet_
+
+### Completion Notes List
+
+_Ready for development - Status: ready-for-dev_
+
+### File List
+
+_Artifact file: `/mnt/code/188-179-template-6/_bmad-output/implementation-artifacts/13-6-dashboard-sync.md`_
+
+## Change Log
+
+- 2026-01-14: Story 13.6 创建完成
+  - 首页看板数据联动专项测试需求
+  - 与 Story 13.1 的区别说明
+  - EnterpriseMiniPage 扩展方法定义
+  - 状态:ready-for-dev

+ 2 - 1
_bmad-output/implementation-artifacts/sprint-status.yaml

@@ -209,11 +209,12 @@ development_status:
   # 依赖: Epic 10(订单管理)和 Epic 12(小程序登录)完成
   # 技术要点: 多 Page 对象管理、WebSocket 通信验证
   epic-13: in-progress
-  13-1-order-create-sync: ready-for-dev   # 后台创建订单 → 企业小程序验证
+  13-1-order-create-sync: in-progress   # 后台创建订单 → 企业小程序验证
   13-2-order-edit-sync: backlog            # 后台编辑订单 → 企业小程序验证
   13-3-person-add-sync: backlog            # 后台添加人员 → 人才小程序验证
   13-4-work-status-sync: backlog           # 后台更新状态 → 双小程序验证
   13-5-cross-platform-stability: backlog   # 跨端测试稳定性验证
+  13-6-dashboard-sync: ready-for-dev       # 首页看板数据联动专项测试
   epic-13-retrospective: optional
 
 # Epic 组织架构 (2026-01-13):

+ 1 - 0
_bmad-output/planning-artifacts/epics.md

@@ -2451,6 +2451,7 @@ Order (订单) - 必须 companyId
 - Story 13.3: 后台添加人员 → 人才小程序验证
 - Story 13.4: 后台更新状态 → 双小程序验证
 - Story 13.5: 跨端测试稳定性验证
+- Story 13.6: 首页看板数据联动专项测试
 
 **技术要点:**
 - 多 Page 对象管理(后台 + 小程序)