Status: in-progress
作为测试开发者, 我想要验证后台创建订单后企业小程序的数据同步, 以便确保跨端数据同步的正确性和时效性。
注意: 本 Story 不包含 WebSocket 通信验证,因为小程序和后端服务未采用 WebSocket。
Given 后台订单管理功能已完成(Epic 10) When 测试者在管理后台创建订单 Then 测试应验证以下功能:
Given 管理后台已创建订单 When 企业用户登录小程序 Then 测试应验证以下功能:
Given 测试需要同时操作后台和小程序 When 执行跨端测试 Then 测试应满足以下要求:
Given 跨端测试涉及多个系统 When 执行测试 Then 测试应遵循以下策略:
Given 网络延迟和系统负载 When 创建订单后查询小程序 Then 测试应验证以下场景:
Given 遵循项目测试规范 When 编写测试代码 Then 代码应符合以下标准:
order-create-sync.spec.tspnpm typecheck 类型检查测试开发流程(增强的 TDD): 本 Story 采用 Playwright MCP 优先的测试开发流程。任务 0 必须在任务 1-6 之前完成,它为后续任务提供验证过的选择器、交互模式和测试骨架。
注意: 已移除 WebSocket 相关任务(原任务 4),因为小程序和后端服务未采用 WebSocket。
[ ] 任务 1: 创建跨端测试文件和基础设施 (AC: #3, #6)
web/tests/e2e/specs/cross-platform/order-create-sync.spec.ts[ ] 任务 2: 实现后台创建订单测试 (AC: #1)
[ ] 任务 3: 实现企业小程序验证测试 (AC: #2)
[ ] 任务 4: 实现测试数据清理策略 (AC: #4)
[ ] 任务 5: 实现数据同步时效性验证 (AC: #5)
pnpm typecheck 验证类型检查代码审查来源: Story 13.6 的代码审查发现,这些问题在 DisabledPersonSelector 组件和测试代码中存在,需要在 Story 13.1 完成前修复。
TIMEOUTS 常量,消除魔术数字Epic 13: 跨端数据同步测试 (Epic E)
Epic 13 Story 依赖关系:
Story 13.1: 后台创建订单 → 企业小程序验证 ← 当前 Story
Story 13.2: 后台编辑订单 → 企业小程序验证
Story 13.3: 后台添加人员 → 人才小程序验证
Story 13.4: 后台更新状态 → 双小程序验证
Story 13.5: 跨端测试稳定性验证
测试目标: 验证后台创建订单后,企业小程序能否正确显示该订单
测试结果: ✅ 成功
数据同步时效性:
后台选择器(已验证可用):
| 功能 | data-testid |
|------|-------------|
| 创建订单按钮 | create-order-button |
| 平台选择器 | platform-selector-create |
| 公司选择器 | company-selector-create |
| 选择残疾人按钮 | select-persons-button |
| 残疾人复选框 | person-checkbox-{id} |
| 确认选择按钮 | confirm-batch-button |
| 创建提交按钮 | order-create-submit-button |
小程序选择器(已验证可用):
| 功能 | data-testid |
|------|-------------|
| 手机号输入框 | mini-phone-input |
| 登录按钮 | mini-login-button |
测试流程(已验证):
注意事项:
关键发现(2026-01-14 探索):
残疾人选择问题:
getByTestId('person-checkbox-1240') 可以选择残疾人(1240 是残疾人 ID)confirm-batch-button 确认公司关联问题:
测试状态持久化:
对话框检测:
text=选择残疾人 检测对话框标题比 [role="dialog"] 更可靠confirm-batch-button data-testid待解决问题:
从已完成的 Epic 10 中学习到的订单管理模式:
OrderManagementPage 可用方法:
// 页面导航
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 orderExists(orderName: string): Promise<boolean>
// 订单详情
async openDetailDialog(orderName: string): Promise<void>
async getOrderDetailInfo(): Promise<OrderData>
订单数据结构:
interface OrderData {
name: string; // 订单名称
expectedStartDate?: string; // 预计开始日期
platformId?: number; // 平台ID
companyId?: number; // 公司ID
channelId?: number; // 渠道ID
status?: string; // 订单状态
workStatus?: string; // 工作状态
}
订单创建模式:
const orderData = {
name: `跨端测试订单_${Date.now()}`,
expectedStartDate: '2026-01-15',
platformId: 1,
companyId: 1,
};
const result = await orderManagementPage.createOrder(orderData);
expect(result.success).toBe(true);
从已完成的 Epic 12 中学习到的小程序模式:
EnterpriseMiniPage 可用方法:
// 页面导航
async goto(): Promise<void>
async expectToBeVisible(): Promise<void>
// 登录方法
async login(phone: string, password: string): Promise<void>
// Token 管理
async getToken(): Promise<string | null>
async setToken(token: string): Promise<void>
async clearAuth(): Promise<void>
// 订单列表(待实现)
async getOrderList(): Promise<OrderData[]>
async waitForOrderToAppear(orderName: string, timeout?: number): Promise<boolean>
企业小程序登录流程:
await enterpriseMiniPage.goto();
await enterpriseMiniPage.login(
'13800138000', // 企业用户手机号
'password123'
);
await enterpriseMiniPage.expectLoginSuccess();
方案 1: 使用多个 Browser Context(推荐)
import { test as base } from '@playwright/test';
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();
},
orderManagementPage: async ({ adminPage }, use) => {
const page = new OrderManagementPage(adminPage);
await use(page);
},
enterpriseMiniPage: async ({ miniPage }, use) => {
const page = new EnterpriseMiniPage(miniPage);
await use(page);
},
});
方案 2: 使用单个 Browser Context,多个 Page(备选)
test('跨端数据同步测试', async ({ page }) => {
// 后台操作
const adminPage = page;
const orderManagementPage = new OrderManagementPage(adminPage);
// 小程序操作(使用新的 page)
const miniContext = await adminPage.context().browser()?.newContext();
const miniPage = await miniContext?.newPage();
const enterpriseMiniPage = new EnterpriseMiniPage(miniPage!);
// ...
});
轮询等待模式:
async waitForOrderToAppear(
orderName: string,
timeout: number = 10000
): Promise<boolean> {
const startTime = Date.now();
while (Date.now() - startTime < timeout) {
const orders = await this.getOrderList();
if (orders.some(o => o.name === orderName)) {
return true;
}
await this.page.waitForTimeout(500); // 每 500ms 检查一次
}
return false;
}
使用 Playwright 的等待机制:
await expect(async () => {
const orders = await enterpriseMiniPage.getOrderList();
expect(orders.some(o => o.name === orderName)).toBe(true);
}).toPass({
timeout: 10000,
intervals: [500, 1000], // 检查间隔
});
前置条件:
测试数据唯一性:
const timestamp = Date.now();
const orderData = {
name: `跨端同步测试_${timestamp}`,
expectedStartDate: '2026-01-15',
};
清理方法:
test.afterEach(async ({ orderManagementPage, orderName }) => {
// 在后台删除测试订单
await orderManagementPage.goto();
await orderManagementPage.deleteOrder(orderName);
});
验证清理成功:
test('清理后小程序不显示订单', async ({ enterpriseMiniPage, orderName }) => {
const orders = await enterpriseMiniPage.getOrderList();
expect(orders.some(o => o.name === orderName)).toBe(false);
});
预期页面元素:
如页面未实现,需要添加 data-testid:
private readonly selectors = {
orderList: '[data-testid="mini-order-list"]',
orderItem: '[data-testid="mini-order-item"]',
orderName: '[data-testid="mini-order-name"]',
orderStatus: '[data-testid="mini-order-status"]',
orderDate: '[data-testid="mini-order-date"]',
};
新建文件:
web/tests/e2e/specs/cross-platform/order-create-sync.spec.tsweb/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/admin/order-create.spec.ts (Epic 10)优先级(遵循项目标准):
data-testid 属性(最高优先级)需要在小程序页面添加 data-testid:
mini-order-list - 订单列表容器mini-order-item - 订单项(可动态生成)mini-order-name - 订单名称mini-order-status - 订单状态跨端测试数据类型:
interface CrossPlatformOrderData {
/** 后台订单 ID */
adminOrderId: string;
/** 订单名称 */
orderName: string;
/** 订单状态 */
status: string;
/** 创建时间 */
createdAt: string;
}
interface SyncVerificationResult {
/** 同步是否成功 */
synced: boolean;
/** 同步耗时(毫秒) */
syncTime: number;
/** 后台订单数据 */
adminOrder: OrderData;
/** 小程序订单数据 */
miniOrder?: OrderData;
}
使用 TIMEOUTS 常量:
import { TIMEOUTS } from '../../utils/timeouts';
// 数据同步等待时间
const SYNC_TIMEOUT = TIMEOUTS.networkIdle; // 10000ms
// 轮询检查间隔
const POLL_INTERVAL = 500;
跨端测试调试:
page.screenshot() 在关键步骤截图console.debug() 输出订单信息同步问题调试:
架构文档:
_bmad-output/planning-artifacts/epics.md#Epic 13_bmad-output/project-context.mddocs/standards/e2e-radix-testing.md相关 Story 文档:
10-1-order-page-object.md (订单管理 Page Object)10-4-order-create-tests.md (创建订单测试)12-4-enterprise-mini-page-object.md (企业小程序 Page Object)12-5-enterprise-mini-login.md (企业小程序登录测试)探索报告:
13-1-playwright-mcp-exploration.md - Playwright MCP 测试探索报告 (2026-01-14)Created by create-story workflow
Implementation phase - no debug yet
任务 0 完成记录 (2026-01-14):
测试文件状态:
web/tests/e2e/specs/cross-platform/order-create-sync.spec.ts修改的文件:
web/tests/e2e/specs/cross-platform/order-create-sync.spec.ts - 测试文件,已添加残疾人选择逻辑和公司选择修复Artifact file: /mnt/code/188-179-template-6/_bmad-output/implementation-artifacts/13-1-order-create-sync.md