/** * ================================================================ * 场景:成长记录同步全流程 E2E 测试 * ================================================================ * 用户故事:作为家长,我希望记录孩子的成长轨迹, * 上传健康报告并与测评结果关联,获得全面的成长分析。 * * 流程步骤: * 1. 家长创建孩子的成长档案(基本信息、学校、年级等) * 2. 家长上传孩子的健康体检报告 * 3. 系统解析报告,提取身高、体重、视力等数据 * 4. 成长记录与认知测评结果关联 * 5. 系统更新孩子的五维能量数据 * * 关键里程碑: * - [Milestone-1] 成长档案创建成功 * - [Milestone-2] 健康报告上传并解析成功 * - [Milestone-3] 成长记录与测评报告关联 * - [Milestone-4] 五维能量数据更新 * ================================================================ * * 运行:npx playwright test tests/e2e/growth-record-sync.spec.js */ const { test, expect } = require('@playwright/test'); test.describe('【场景流程】成长记录同步全流程', () => { // ===== 场景1:创建成长档案 ===== /** * 场景:家长为孩子创建一个成长档案 * 角色:家长 * 触发条件:家长首次使用成长记录功能 */ test('[场景1] 创建孩子成长档案 - 期望档案创建成功', async ({ page }) => { // ========== Given:进入创建成长档案页面 ========== await page.goto('/#/pages/growth/create'); await page.waitForLoadState('networkidle'); // ========== Step 1:选择孩子 ========== const childPicker = page.locator('.child-picker, .select-child'); if (await childPicker.isVisible()) { await childPicker.click(); await page.waitForSelector('.child-option, .option-item', { timeout: 5000 }); await page.click('.child-option:first-child, .option-item:first-child'); } // ========== Step 2:填写基本信息 ========== // 输入学校名称 const schoolInput = page.locator('input[placeholder*="学校"], .school-input, input[name="school"]'); if (await schoolInput.isVisible()) { await schoolInput.fill('北京市第一小学'); } // 选择年级 const gradePicker = page.locator('.grade-picker, .select-grade'); if (await gradePicker.isVisible()) { await gradePicker.click(); await page.waitForSelector('.grade-option, .option-item', { timeout: 5000 }); await page.click('.grade-option:has-text("三年级"), .grade-option:nth-child(3)'); } // ========== When:提交创建 ========== await page.click('.submit-btn, .create-btn'); // ========== Then:Milestone-1 - 档案创建成功 ======== await page.waitForSelector('.success-tip, .created, .record-success', { timeout: 10000 }); const successTip = page.locator('.success-tip, .created, .record-success'); expect(await successTip.isVisible()).toBeTruthy(); }); /** * 场景:家长创建档案时未选择孩子 * 角色:家长 * 触发条件:表单中孩子ID为空 */ test('[场景1b] 创建档案时未选择孩子 - 期望返回错误', async ({ page }) => { // ========== Given:进入创建页面 ========== await page.goto('/#/pages/growth/create'); await page.waitForLoadState('networkidle'); // ========== Step 1:填写学校但选择孩子 ========== const schoolInput = page.locator('input[placeholder*="学校"], .school-input'); if (await schoolInput.isVisible()) { await schoolInput.fill('北京市第一小学'); } // ========== When:尝试提交 ========== await page.click('.submit-btn'); // ========== Then:返回错误提示 ======== await page.waitForSelector('.error-tip, .van-field__error, .form-error', { timeout: 5000 }); const errorTip = page.locator('.error-tip, .van-field__error'); expect(await errorTip.isVisible()).toBeTruthy(); expect(await errorTip.textContent()).toMatch(/孩子|选择/); }); // ===== 场景2:创建档案并购买测评 ===== /** * 场景:家长创建成长档案的同时购买认知测评服务 * 角色:家长 * 触发条件:勾选"同时购买测评"选项 */ test('[场景2] 创建档案并购买测评套餐 - 期望档案和订单同时创建', async ({ page }) => { // ========== Given:进入创建档案页面 ========== await page.goto('/#/pages/growth/create-with-order'); await page.waitForLoadState('networkidle'); // ========== Step 1:选择孩子 ========== const childPicker = page.locator('.child-picker'); if (await childPicker.isVisible()) { await childPicker.click(); await page.waitForSelector('.child-option', { timeout: 5000 }); await page.click('.child-option:first-child'); } // ========== Step 2:填写学校信息 ========== const schoolInput = page.locator('input[name="school"], .school-input'); if (await schoolInput.isVisible()) { await schoolInput.fill('北京市第二小学'); } // ========== Step 3:勾选同时购买测评 ========== const purchaseCheckbox = page.locator('.purchase-checkbox, .also-buy-assessment'); if (await purchaseCheckbox.isVisible()) { await purchaseCheckbox.click(); } // 选择套餐 const packageOption = page.locator('.package-option:first-child'); if (await packageOption.isVisible()) { await packageOption.click(); } // ========== When:提交 ========== await page.click('.submit-btn, .create-with-order-btn'); // ========== Then:档案和订单都创建成功 ======== await page.waitForSelector('.success-tip, .record-created', { timeout: 10000 }); // 验证跳转或显示订单信息 const orderInfo = page.locator('.order-info, .order-no'); // 可能跳转到了订单页面或留在创建页但显示了订单信息 expect(await page.locator('.success-tip, .record-created, .order-info').isVisible()).toBeTruthy(); }); // ===== 场景3:上传健康报告并解析 ===== /** * 场景:家长上传孩子的健康体检报告,系统自动解析 * 角色:家长 * 触发条件:上传体检报告文件 */ test('[场景3] 上传并解析健康报告 - 期望解析出健康数据', async ({ page }) => { // ========== Given:进入上传报告页面 ========== await page.goto('/#/pages/growth/upload-report'); await page.waitForLoadState('networkidle'); // ========== Step 1:选择孩子 ========== const childPicker = page.locator('.child-picker'); if (await childPicker.isVisible()) { await childPicker.click(); await page.waitForSelector('.child-option', { timeout: 5000 }); await page.click('.child-option:first-child'); } // ========== Step 2:上传报告文件 ========== // 点击上传按钮 const uploadBtn = page.locator('.upload-btn, .upload-report-btn'); if (await uploadBtn.isVisible()) { await uploadBtn.click(); } // 选择文件(模拟) const fileInput = page.locator('input[type="file"], .file-input'); if (await fileInput.isVisible()) { // 在实际测试中,这里会上传真实的PDF文件 // await fileInput.setInputFiles('/path/to/test-report.pdf'); } // ========== When:确认上传 ========== const confirmBtn = page.locator('.confirm-upload-btn, .submit-upload-btn'); if (await confirmBtn.isVisible()) { await confirmBtn.click(); } // ========== Then:Milestone-2 - 报告解析成功 ======== // 等待解析完成(可能需要几秒钟) await page.waitForSelector('.parsed-result, .report-data, .parse-success', { timeout: 30000 }); // 验证解析结果显示 const parsedData = page.locator('.parsed-result, .health-data'); expect(await parsedData.isVisible()).toBeTruthy(); // 验证关键数据提取 const heightData = page.locator('.height-value, .parsed-height'); const weightData = page.locator('.weight-value, .parsed-weight'); if (await heightData.isVisible()) { expect(await heightData.textContent()).toMatch(/\d+/); } }); // ===== 场景4:关联成长记录与测评结果 ===== /** * 场景:成长记录与认知测评结果进行关联 * 角色:系统(自动关联) * 触发条件:测评报告生成后 */ test('[场景4] 成长记录关联测评报告 - 期望关联成功', async ({ page }) => { // ========== Given:进入成长记录详情 ========== await page.goto('/#/pages/growth/record-detail/1'); await page.waitForLoadState('networkidle'); // ========== When:查看关联状态 ========== await page.waitForSelector('.record-detail, .growth-record', { timeout: 10000 }); // ========== Then:Milestone-3 - 关联成功 ======== // 查看是否有测评报告关联卡片 const assessmentCard = page.locator('.assessment-link, .related-assessment, .linked-report'); if (await assessmentCard.isVisible()) { // 验证关联的测评报告显示 expect(await assessmentCard.isVisible()).toBeTruthy(); } else { // 验证关联按钮存在,可以进行关联 const linkBtn = page.locator('.link-assessment-btn, .add-assessment-btn'); expect(await linkBtn.isVisible()).toBeTruthy(); } }); // ===== 场景5:查询孩子的成长记录列表 ===== /** * 场景:家长查看孩子的历史成长记录 * 角色:家长 * 触发条件:进入成长记录历史页面 */ test('[场景5] 查询成长记录历史 - 期望返回记录列表', async ({ page }) => { // ========== Given:进入成长记录列表 ========== await page.goto('/#/pages/growth/records'); await page.waitForLoadState('networkidle'); // ========== Step 1:选择孩子 ========== const childPicker = page.locator('.child-picker'); if (await childPicker.isVisible()) { await childPicker.click(); await page.waitForSelector('.child-option', { timeout: 5000 }); await page.click('.child-option:first-child'); } // ========== When:查询记录列表 ========== await page.waitForSelector('.record-item, .growth-item', { timeout: 10000 }); // ========== Then:返回历史记录列表 ======== const recordItems = page.locator('.record-item, .growth-item'); const count = await recordItems.count(); expect(count).toBeGreaterThan(0); // 验证记录包含日期 const firstRecord = recordItems.first(); const recordDate = firstRecord.locator('.record-date, .date-text'); expect(await recordDate.isVisible()).toBeTruthy(); }); // ===== 场景6:补充成长记录 ===== /** * 场景:家长为已有记录补充信息 * 角色:家长 * 触发条件:点击记录的"补充"按钮 */ test('[场景6] 补充成长记录 - 期望补充成功', async ({ page }) => { // ========== Given:进入记录详情 ========== await page.goto('/#/pages/growth/record-detail/1'); await page.waitForLoadState('networkidle'); // ========== When:点击补充按钮 ========== const supplementBtn = page.locator('.supplement-btn, .add-note-btn'); if (await supplementBtn.isVisible()) { await supplementBtn.click(); // 填写补充内容 const noteInput = page.locator('textarea[name="note"], .note-input'); if (await noteInput.isVisible()) { await noteInput.fill('本学期孩子在数学方面有明显进步,建议加强逻辑思维训练。'); } await page.click('.submit-supplement-btn'); // ========== Then:补充成功 ======== await page.waitForSelector('.success-tip, .supplement-success', { timeout: 10000 }); // 验证补充内容显示 const supplementList = page.locator('.supplement-list, .note-list'); expect(await supplementList.isVisible()).toBeTruthy(); } }); // ===== 场景7:完整成长记录流程(端到端)===== test('[场景7] 完整成长记录生命周期 - 期望全流程成功', async ({ page }) => { // ========== Step 1:创建成长档案 ========== await page.goto('/#/pages/growth/create'); await page.waitForLoadState('networkidle'); // 选择孩子 const childPicker = page.locator('.child-picker'); if (await childPicker.isVisible()) { await childPicker.click(); await page.waitForSelector('.child-option', { timeout: 5000 }); await page.click('.child-option:first-child'); } // 填写学校 const schoolInput = page.locator('input[name="school"], .school-input'); if (await schoolInput.isVisible()) { await schoolInput.fill('北京市第一小学'); } // 选择年级 const gradePicker = page.locator('.grade-picker'); if (await gradePicker.isVisible()) { await gradePicker.click(); await page.waitForSelector('.grade-option', { timeout: 5000 }); await page.click('.grade-option:nth-child(3)'); } await page.click('.submit-btn'); await page.waitForSelector('.success-tip, .record-success', { timeout: 10000 }); // ========== Step 2:查询记录列表 ========== await page.goto('/#/pages/growth/records'); await page.waitForLoadState('networkidle'); await page.waitForSelector('.record-item', { timeout: 10000 }); // 验证记录存在 const recordCount = await page.locator('.record-item').count(); expect(recordCount).toBeGreaterThan(0); // ========== Step 3:查看详情 ========== const firstRecord = page.locator('.record-item').first(); await firstRecord.click(); await page.waitForSelector('.record-detail, .growth-detail', { timeout: 10000 }); // 验证详情页面显示 expect(await page.locator('.record-detail, .growth-detail').isVisible()).toBeTruthy(); }); });