| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353 |
- /**
- * ================================================================
- * 场景:成长记录同步全流程 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();
- });
- });
|