Status: in-progress
作为测试开发者, 我想要验证后台编辑订单后企业小程序的数据同步, 以便确保跨端数据更新的正确性和时效性。
Given 后台订单管理功能已完成(Epic 10) When 测试者在管理后台编辑已有订单 Then 测试应验证以下功能:
Given 管理后台已编辑订单 When 企业用户登录小程序 Then 测试应验证以下功能:
Given 订单支持多种字段编辑 When 执行编辑操作 Then 测试应验证以下场景:
Given 测试需要同时操作后台和小程序 When 执行跨端测试 Then 测试应满足以下要求:
Given 跨端测试涉及多个系统 When 执行测试 Then 测试应遵循以下策略:
Given 网络延迟和系统负载 When 编辑订单后查询小程序 Then 测试应验证以下场景:
Given 遵循项目测试规范 When 编写测试代码 Then 代码应符合以下标准:
order-edit-sync.spec.tspnpm typecheck 类型检查测试开发流程(增强的 TDD + 持续验证): 本 Story 采用 Playwright MCP 持续验证的测试开发流程。
核心原则:
- 即时验证: 在开发过程中立即使用 Playwright MCP 验证,不等到专门的 E2E Story
- 持续反馈: 每完成一个功能模块立即验证,快速发现问题
- 减少返工: 早期发现问题可以减少后期返工成本
Playwright MCP 使用时机:
- ✅ 任务 0: 探索页面结构、验证流程可行性
- ✅ 任务 1-4: 每写一个测试就用 MCP 验证选择器、页面结构
- ✅ 任务 5-6: 每实现一个功能就用 MCP 验证是否正常工作
- ✅ 任务 7: 重构后用 MCP 确保功能未破坏
任务 0 必须在任务 1-6 之前完成,它为后续任务提供验证过的选择器和基础模式。
[ ] 任务 1: 创建跨端测试文件和基础设施 (AC: #4, #7)
web/tests/e2e/specs/cross-platform/order-edit-sync.spec.ts[ ] 任务 2: 实现后台编辑订单测试 (AC: #1)
[ ] 任务 3: 实现企业小程序验证测试 (AC: #2)
[ ] 任务 4: 实现多字段编辑同步测试 (AC: #3)
[ ] 任务 5: 实现测试数据清理策略 (AC: #5)
[ ] 任务 6: 实现数据同步时效性验证 (AC: #6)
pnpm typecheck 验证类型检查核心理念: Playwright MCP 不应该只在任务0使用一次,而应该作为整个开发过程中的持续验证工具。
| 对比维度 | 传统流程(只在任务0用 MCP) | 持续验证流程(整个开发过程用 MCP) |
|---|---|---|
| 问题发现时机 | 运行完整测试套件时发现 | 几秒钟内立即发现 |
| 反馈速度 | 分钟级(重新编译+运行测试) | 秒级(直接在 MCP 中验证) |
| 调试效率 | 只看截图和日志 | 完整页面状态+交互式调试 |
| 认知负担 | 频繁在"写代码"和"跑测试"间切换 | 保持开发心流,即时验证 |
| 返工成本 | 高(写很多代码后才发现问题) | 低(每步验证后继续) |
┌─────────────────────────────────────────────────────────┐
│ 持续验证循环 │
├─────────────────────────────────────────────────────────┤
│ │
│ 编写/修改代码 │
│ ↓ │
│ 立即用 Playwright MCP 验证 │
│ ↓ │
│ 发现问题? │
│ ├── 是 → 修复代码 → 重新验证 │
│ └── 否 → 继续下一步 │
│ │
└─────────────────────────────────────────────────────────┘
阶段 1: EXPLORE(任务 0)
目标: 探索页面结构、验证流程可行性
操作: 完整走一遍测试流程,记录选择器
输出: 验证过的选择器、测试骨架
阶段 2: RED(任务 1-4 - 编写测试)
每写一个测试用例 → 用 MCP 验证选择器 → 发现选择器错误 → 修复测试
示例:
1. 编写测试: await page.click('[data-testid="edit-button"]');
2. MCP 验证: 发现选择器不存在
3. 修复测试: 改为正确的选择器
4. 重新验证: 确认可以点击
5. 继续编写下一步
阶段 3: GREEN(任务 5-6 - 实现代码)
每实现一个功能 → 用 MCP 验证功能 → 发现字段没同步 → 调整代码
示例:
1. 实现编辑功能: orderManagementPage.editOrder(...)
2. MCP 验证: 编辑后小程序数据没更新
3. 调查原因: 发现同步时间不够
4. 优化等待: 增加轮询等待时间
5. 重新验证: 确认数据同步成功
阶段 4: REFACTOR(任务 7 - 优化代码)
重构代码 → 用 MCP 确保功能未破坏 → 发现回归 → 回退或修复
示例:
1. 重构: 提取公共方法到基类
2. MCP 验证: 所有功能仍然正常
3. 完成: 提交重构代码
| 场景 | 使用 Playwright MCP | 运行自动化测试 |
|---|---|---|
| 编写新测试前 | ✅ 探索页面结构 | |
| 编写测试中 | ✅ 验证选择器、交互 | |
| 实现功能中 | ✅ 验证功能正确性 | |
| 修复 bug 时 | ✅ 验证修复效果 | |
| 代码重构后 | ✅ 快速验证 | |
| 提交前 | ✅ 完整测试套件 | |
| CI/CD | ✅ 完整测试套件 |
【任务 0】探索阶段
├─ MCP 验证完整流程 ✓
├─ 记录选择器 ✓
└─ 生成测试骨架 ✓
【任务 1】编写测试 - 测试 1
├─ 编写测试代码
├─ MCP 验证选择器 → 发现选择器错误
├─ 修复选择器
├─ MCP 重新验证 ✓
└─ 继续下一个测试
【任务 2】编写测试 - 测试 2
├─ 编写测试代码
├─ MCP 验证页面结构 → 发现字段名错误
├─ 修复字段名
├─ MCP 重新验证 ✓
└─ 继续下一个测试
【任务 5】实现功能
├─ 实现 Page Object 方法
├─ MCP 验证功能 → 发现数据没保存
├─ 调查原因: 缺少等待
├─ 添加等待逻辑
├─ MCP 重新验证 ✓
└─ 继续下一个功能
【任务 7】重构代码
├─ 提取公共方法
├─ MCP 验证所有功能 ✓
└─ 完成重构
【提交前】完整测试套件
└─ pnpm test:e2e:chromium ✓
Epic 13: 跨端数据同步测试 (Epic E)
Epic 13 Story 依赖关系:
Story 13.1: 后台创建订单 → 企业小程序验证 ✅ 已完成
Story 13.2: 后台编辑订单 → 企业小程序验证 ← 当前 Story
Story 13.3: 后台添加人员 → 人才小程序验证
Story 13.4: 后台更新状态 → 双小程序验证
Story 13.5: 跨端测试稳定性验证
Story 13.6: 首页看板数据联动专项测试
完成时间: 2026-01-14 探索方法: 使用 Playwright MCP 工具手动验证完整测试流程
测试目标: 验证后台编辑订单后,企业小程序能否正确显示更新后的订单信息
测试结果: ✅ 成功(有重要发现)
数据同步时效性:
后台选择器(已验证可用):
| 功能 | 选择器/方法 |
|------|-------------|
| 订单菜单触发器 | order-menu-trigger-{orderId} (例如: order-menu-trigger-721) |
| 编辑按钮 | edit-order-button-{orderId} (例如: edit-order-button-721) |
| 订单名称输入框 | getByRole('textbox', { name: '订单名称' }) |
| 预计开始日期 | getByRole('textbox', { name: '预计开始日期' }) |
| 平台选择器 | 与创建相同(待确认 data-testid) |
| 公司选择器 | 与创建相同(待确认 data-testid) |
| 订单状态选择器 | getByRole('combobox', { name: '订单状态' }) |
| 工作状态选择器 | getByRole('combobox', { name: '工作状态' }) |
| 更新按钮 | order-update-submit-button |
| 成功提示 | getByRole('listitem').filter({ hasText: '订单更新成功' }) |
小程序选择器(已验证可用):
| 功能 | 选择器/方法 |
|------|-------------|
| 手机号输入框 | mini-phone-input |
| 登录按钮 | mini-login-button |
| 订单列表项 | 通过文本内容定位订单名称 |
| 查看详情按钮 | getByText('查看详情') |
| 订单名称(详情页) | 通过文本内容验证 |
测试流程(已验证):
后台编辑流程:
/admin/orders)小程序验证流程:
13800001111 / password123)关键发现(2026-01-14 探索):
⚠️ 重要发现:小程序列表页缓存问题
数据同步验证策略:
公司关联确认(与 Story 13.1 一致):
13800001111 关联公司: "测试公司_1768346782396"编辑订单选择器模式:
order-menu-trigger-{orderId}edit-order-button-{orderId}order-update-submit-button待解决问题:
建议的 E2E 测试验证点:
从 Story 13.1(后台创建订单 → 企业小程序验证)中学习到的关键经验:
Playwright MCP 探索经验:
data-testid 选择器,避免文本选择器关键发现(Story 13.1 探索结果):
公司关联问题: 小程序用户关联的公司必须与后台选择的公司一致,否则小程序看不到订单
对话框检测: 使用 text=选择残疾人 检测对话框标题比 [role="dialog"] 更可靠
confirm-batch-button data-testid数据同步时间: 实际同步时间 < 1秒,远超 ≤ 10 秒的要求
测试代码模式(Story 13.1):
// 使用多 Page 对象管理
const orderManagementPage = new OrderManagementPage(adminPage);
const enterpriseMiniPage = new EnterpriseMiniPage(miniPage);
// 创建订单(编辑测试的前置条件)
const orderData = {
name: `跨端测试订单_${Date.now()}`,
expectedStartDate: '2026-01-15',
platformId: 1,
companyId: 1, // 必须与小程序用户关联的公司一致
};
const result = await orderManagementPage.createOrder(orderData);
已知问题(Story 13.1 剩余):
从已完成的 Epic 10 Story 10.5 中学习到的订单编辑模式:
OrderManagementPage 编辑方法:
// 编辑订单
async editOrder(orderName: string, data: OrderData): Promise<FormSubmitResult>
// 订单数据结构(编辑支持的字段)
interface OrderData {
name?: string; // 订单名称(可编辑)
expectedStartDate?: string; // 预计开始日期(可编辑)
platformId?: number; // 平台ID(可编辑)
companyId?: number; // 公司ID(可编辑)
channelId?: number; // 渠道ID(可编辑)
status?: string; // 订单状态(可编辑)
workStatus?: string; // 工作状态(可编辑)
}
订单编辑测试场景(Epic 10 Story 10.5):
编辑测试文件参考: web/tests/e2e/specs/admin/order-edit.spec.ts
从已完成的 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);
});
预期页面元素(基于 Story 13.1):
如页面未实现,需要添加 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-edit-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/admin/order-edit.spec.ts (Epic 10) - 编辑订单测试web/tests/e2e/specs/cross-platform/order-create-sync.spec.ts (Story 13.1) - 跨端测试模式优先级(遵循项目标准):
data-testid 属性(最高优先级)后台编辑表单选择器(参考 Epic 10):
edit-button-{orderId} 或列表项点击platform-selector-edit, company-selector-edit 等)order-edit-submit-button跨端测试数据类型:
interface CrossPlatformOrderEditData {
/** 后台订单 ID */
adminOrderId: string;
/** 编辑前订单名称 */
originalName: string;
/** 编辑后订单名称 */
editedName: string;
/** 编辑后的订单状态 */
status: string;
/** 编辑后的预计开始日期 */
expectedStartDate?: 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 文档:
13-1-order-create-sync.md - Story 13.1 完整文档(Playwright MCP 探索结果、测试模式)10-1-order-page-object.md (订单管理 Page Object)10-5-order-edit-tests.md (编辑订单测试)12-4-enterprise-mini-page-object.md (企业小程序 Page Object)12-5-enterprise-mini-login.md (企业小程序登录测试)Created by create-story workflow
Implementation phase - no debug yet
Story created - ready for development
新建文件:
_bmad-output/implementation-artifacts/13-2-order-edit-sync.md - 本 Story 文档待创建文件(开发阶段):
web/tests/e2e/specs/cross-platform/order-edit-sync.spec.ts - 跨端编辑同步测试