# Story 13.6: 首页看板数据联动专项测试 Status: ready-for-dev ## 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 async expectToBeVisible(): Promise // 订单 CRUD async createOrder(data: OrderData): Promise async editOrder(orderId: string, data: OrderData): Promise async deleteOrder(orderId: string): Promise async activateOrder(orderName: string): Promise async closeOrder(orderName: string): Promise // 订单状态 async getOrderStatus(orderName: string): Promise ``` **订单状态流转:** ```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 async expectToBeVisible(): Promise // 登录方法 async login(phone: string, password: string): Promise async expectLoginSuccess(): Promise // Token 管理 async getToken(): Promise async clearAuth(): Promise ``` **企业小程序登录流程:** ```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({ 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 { // 实现逻辑 } /** * 获取订单数量统计徽章 */ async getOrderCountBadge(filter?: 'all' | 'inProgress' | 'completed'): Promise { // 实现逻辑 } /** * 刷新首页看板数据 */ async refreshDashboard(): Promise { // 实现下拉刷新 } /** * 获取首页看板统计数据 */ async getDashboardStatistics(): Promise { // 实现逻辑 } /** * 等待订单卡片出现在首页看板 */ async waitForOrderCard(orderName: string, timeout?: number): Promise { // 实现轮询等待 } ``` **类型定义:** ```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 { 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 { // 方案 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