| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366 |
- /**
- * ================================================================
- * 场景:测评订单全流程 E2E 测试
- * ================================================================
- * 用户故事:作为家长,我希望为孩子购买专业测评服务,
- * 以便了解孩子的认知发展状况并获得成长建议。
- *
- * 流程步骤:
- * 1. 家长选择规划师和测评套餐,进入测评申请页面
- * 2. 家长填写孩子信息,提交测评申请
- * 3. 家长完成支付,订单状态变更为"已支付"
- * 4. 系统自动确认预约,预约状态变更为"待测评"
- * 5. 规划师确认预约,查看孩子的基本信息(快照)
- * 6. 规划师完成测评,录入认知评估结果
- * 7. 家长/孩子查看测评报告
- *
- * 关键里程碑:
- * - [Milestone-1] 订单创建成功,获得订单号
- * - [Milestone-2] 支付成功,预约自动创建
- * - [Milestone-3] 规划师确认预约
- * - [Milestone-4] 测评结果录入完成
- * - [Milestone-5] 家长可查询到孩子的最新报告
- * ================================================================
- *
- * 运行:npx playwright test tests/e2e/assessment-order-flow.spec.js
- */
- const { test, expect } = require('@playwright/test');
- test.describe('【场景流程】测评订单全流程', () => {
- // ===== 场景1:家长选购测评套餐 =====
- /**
- * 场景:家长选择规划师并购买测评套餐
- * 角色:家长
- * 触发条件:家长选择了具体的规划师和测评套餐
- */
- test('[场景1] 家长购买测评套餐并完成支付 - 期望全流程成功', async ({ page }) => {
- // ========== Given:家长进入测评申请页面 ==========
- await page.goto('/#/pages/assessment/apply');
- await page.waitForLoadState('networkidle');
- // 验证页面加载成功
- await expect(page.locator('.assessment-apply-page')).toBeVisible({ timeout: 10000 });
- // ========== Step 1:选择孩子 ==========
- const childSelector = page.locator('.child-picker');
- if (await childSelector.isVisible()) {
- await childSelector.click();
- await page.waitForSelector('.child-option', { timeout: 5000 });
- await page.click('.child-option:first-child');
- }
- // ========== Step 2:选择规划师(可选)==========
- const guideSelector = page.locator('.guide-picker');
- if (await guideSelector.isVisible()) {
- await guideSelector.click();
- await page.waitForSelector('.guide-option', { timeout: 5000 });
- await page.click('.guide-option:first-child');
- }
- // ========== Step 3:选择测评套餐 ==========
- await page.click('.package-option:first-child');
- // ========== When:提交申请 ==========
- await page.click('.submit-btn');
- // ========== Then:Milestone-1 - 订单创建成功 ========
- // 等待订单确认弹窗或跳转
- await page.waitForSelector('.order-confirm-modal, .order-success-tip', { timeout: 10000 });
- // 验证订单号生成(订单号应该在页面某处显示)
- const orderSuccessTip = page.locator('.order-success-tip, .order-no');
- if (await orderSuccessTip.isVisible()) {
- const orderText = await orderSuccessTip.textContent();
- expect(orderText).toMatch(/订单|ASR|成功/);
- }
- // ========== Step 4:点击去支付 ==========
- await page.click('.go-pay-btn');
- // ========== Then:Milestone-2 - 支付成功 ========
- // 选择支付方式
- const wechatPayOption = page.locator('.pay-method:has-text("微信支付")');
- if (await wechatPayOption.isVisible()) {
- await wechatPayOption.click();
- }
- // 确认支付
- await page.click('.confirm-pay-btn');
- // 等待支付成功提示
- await page.waitForSelector('.pay-success-tip, .payment-success', { timeout: 15000 });
- // 验证支付状态
- const successTip = page.locator('.pay-success-tip, .payment-success');
- expect(await successTip.isVisible()).toBeTruthy();
- });
- // ===== 场景2:自动分配规划师流程 =====
- /**
- * 场景:家长未指定规划师,系统自动分配家庭绑定的规划师
- * 角色:家长
- * 触发条件:家长未指定 guideId,但家庭已绑定规划师
- */
- test('[场景2] 未指定规划师时系统自动分配 - 期望使用家庭绑定的规划师', async ({ page }) => {
- // ========== Given:家庭已绑定规划师 ==========
- await page.goto('/#/pages/assessment/apply');
- await page.waitForLoadState('networkidle');
- // ========== Step 1:选择孩子 ==========
- const childSelector = page.locator('.child-picker');
- if (await childSelector.isVisible()) {
- await childSelector.click();
- await page.waitForSelector('.child-option', { timeout: 5000 });
- await page.click('.child-option:first-child');
- }
- // ========== Step 2:直接选择套餐(不选规划师)==========
- await page.click('.package-option:first-child');
- // ========== When:提交申请 ==========
- await page.click('.submit-btn');
- // ========== Then:系统自动使用家庭绑定的规划师 ========
- // 应该显示自动分配提示或规划师名称
- await page.waitForSelector('.auto-assign-tip, .guide-name', { timeout: 10000 });
- const guideName = page.locator('.guide-name, .guide-info');
- if (await guideName.isVisible()) {
- const nameText = await guideName.textContent();
- expect(nameText.length).toBeGreaterThan(0);
- }
- });
- // ===== 场景3:规划师录入测评结果 =====
- /**
- * 场景:规划师完成测评后,录入孩子的认知评估结果
- * 角色:成长规划师
- * 触发条件:预约已完成,规划师完成了一对一测评
- */
- test('[场景3] 规划师录入测评结果 - 期望结果保存并可查询', async ({ page }) => {
- // ========== Given:规划师进入测评结果录入页面 ==========
- await page.goto('/#/pages/guide/assessment/record');
- await page.waitForLoadState('networkidle');
- // ========== Step 1:选择要录入的预约 ==========
- await page.waitForSelector('.appointment-item', { timeout: 10000 });
- await page.click('.appointment-item:first-child');
- // ========== Step 2:填写测评结果 ==========
- // 输入各项分数
- const scoreInputs = page.locator('.score-input');
- const scoreCount = await scoreInputs.count();
- for (let i = 0; i < scoreCount; i++) {
- await scoreInputs.nth(i).fill(String(Math.floor(Math.random() * 20) + 80));
- }
- // 输入综合评语
- const reportTextarea = page.locator('.analysis-report textarea, .report-textarea');
- if (await reportTextarea.isVisible()) {
- await reportTextarea.fill('孩子整体认知发展良好,在注意力和逻辑思维方面表现突出...');
- }
- // ========== When:提交测评结果 ==========
- await page.click('.submit-result-btn');
- // ========== Then:Milestone-4 - 测评结果保存成功 ========
- await page.waitForSelector('.submit-success-tip, .result-saved', { timeout: 10000 });
- const successTip = page.locator('.submit-success-tip, .result-saved');
- expect(await successTip.isVisible()).toBeTruthy();
- });
- // ===== 场景4:家长查询孩子测评报告 =====
- /**
- * 场景:家长为孩子购买测评后,查看孩子的最新认知评估报告
- * 角色:家长
- * 触发条件:规划师已完成测评并录入结果
- */
- test('[场景4] 家长查询孩子最新报告 - 期望返回完整报告内容', async ({ page }) => {
- // ========== Given:进入测评报告页面 ==========
- await page.goto('/#/pages/assessment/results');
- await page.waitForLoadState('networkidle');
- // ========== Step 1:选择孩子 ==========
- const childSelector = page.locator('.child-picker');
- if (await childSelector.isVisible()) {
- await childSelector.click();
- await page.waitForSelector('.child-option', { timeout: 5000 });
- await page.click('.child-option:first-child');
- }
- // ========== When:查看报告 ==========
- await page.click('.view-report-btn');
- // ========== Then:Milestone-5 - 返回完整报告内容 ========
- await page.waitForSelector('.report-detail, .result-card', { timeout: 10000 });
- // 验证报告包含必要内容
- const reportDetail = page.locator('.report-detail, .result-content');
- expect(await reportDetail.isVisible()).toBeTruthy();
- // 验证分数显示
- const scoreDisplay = page.locator('.overall-score, .score-value');
- if (await scoreDisplay.isVisible()) {
- const scoreText = await scoreDisplay.textContent();
- expect(scoreText).toMatch(/\d+/);
- }
- });
- // ===== 场景5:取消未支付订单 =====
- /**
- * 场景:家长创建订单后决定取消,选择关闭交易
- * 角色:家长
- * 触发条件:订单状态为"待支付"
- */
- test('[场景5] 家长取消未支付订单 - 期望订单关闭成功', async ({ page }) => {
- // ========== Given:进入我的订单页面 ==========
- await page.goto('/#/pages/assessment/orders');
- await page.waitForLoadState('networkidle');
- // ========== Step 1:找到待支付订单 ==========
- await page.waitForSelector('.order-item', { timeout: 10000 });
- const pendingOrder = page.locator('.order-item:has-text("待支付"), .order-item:has-text("待付款")').first();
- await pendingOrder.click();
- // ========== When:点击取消订单 ==========
- await page.click('.cancel-order-btn');
- // 确认取消
- const confirmBtn = page.locator('.confirm-cancel-btn, .van-dialog__confirm');
- if (await confirmBtn.isVisible()) {
- await confirmBtn.click();
- }
- // ========== Then:订单成功取消 ========
- await page.waitForSelector('.cancel-success-tip, .order-closed', { timeout: 10000 });
- // 订单状态应变为"已取消"
- const orderStatus = page.locator('.order-status');
- if (await orderStatus.isVisible()) {
- const statusText = await orderStatus.textContent();
- expect(statusText).toMatch(/已取消|已关闭/);
- }
- });
- // ===== 场景6:已支付订单退款 =====
- /**
- * 场景:家长支付后因故需要退款
- * 角色:家长(发起退款)→ 系统处理
- * 触发条件:订单状态为"已支付"
- */
- test('[场景6] 已支付订单申请退款 - 期望退款成功', async ({ page }) => {
- // ========== Given:进入订单详情 ==========
- await page.goto('/#/pages/assessment/order-detail?orderNo=ASR20260628001');
- await page.waitForLoadState('networkidle');
- // ========== When:申请退款 ==========
- await page.click('.apply-refund-btn');
- // 填写退款原因
- const reasonInput = page.locator('.refund-reason textarea, .reason-input');
- if (await reasonInput.isVisible()) {
- await reasonInput.fill('因计划变更,需要退款');
- }
- // 确认提交
- await page.click('.submit-refund-btn');
- // ========== Then:退款申请提交成功 ========
- await page.waitForSelector('.refund-submitted, .refund-success', { timeout: 10000 });
- const refundTip = page.locator('.refund-submitted, .refund-success');
- expect(await refundTip.isVisible()).toBeTruthy();
- });
- // ===== 场景7:完整测评流程(端到端)=====
- test('[场景7] 完整测评生命周期 - 期望全流程成功', async ({ page }) => {
- // ========== Step 1:申请测评 ==========
- await page.goto('/#/pages/assessment/apply');
- await page.waitForLoadState('networkidle');
- // 选择孩子
- const childSelector = page.locator('.child-picker');
- if (await childSelector.isVisible()) {
- await childSelector.click();
- await page.waitForSelector('.child-option', { timeout: 5000 });
- await page.click('.child-option:first-child');
- }
- // 选择套餐并提交
- await page.click('.package-option:first-child');
- await page.click('.submit-btn');
- // 等待订单创建
- await page.waitForSelector('.order-no, .go-pay-btn', { timeout: 10000 });
- // ========== Step 2:支付订单 ==========
- const goPayBtn = page.locator('.go-pay-btn');
- if (await goPayBtn.isVisible()) {
- await goPayBtn.click();
- // 选择微信支付并确认
- const wechatPay = page.locator('.pay-method:has-text("微信")');
- if (await wechatPay.isVisible()) {
- await wechatPay.click();
- }
- await page.click('.confirm-pay-btn');
- await page.waitForSelector('.pay-success-tip', { timeout: 15000 });
- }
- // ========== Step 3:规划师确认预约 ==========
- await page.goto('/#/pages/guide/assessment/list');
- await page.waitForLoadState('networkidle');
- const appointmentItem = page.locator('.appointment-item').first();
- if (await appointmentItem.isVisible()) {
- await appointmentItem.click();
- await page.click('.confirm-appointment-btn');
- }
- // ========== Step 4:规划师录入结果 ==========
- await page.goto('/#/pages/guide/assessment/record');
- await page.waitForLoadState('networkidle');
- const pendingRecord = page.locator('.pending-record-item').first();
- if (await pendingRecord.isVisible()) {
- await pendingRecord.click();
- // 填写分数
- const scoreInputs = page.locator('.score-input');
- for (let i = 0; i < await scoreInputs.count(); i++) {
- await scoreInputs.nth(i).fill('85');
- }
- await page.click('.submit-result-btn');
- await page.waitForSelector('.result-saved', { timeout: 10000 });
- }
- // ========== Step 5:家长查看报告 ==========
- await page.goto('/#/pages/assessment/results');
- 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');
- }
- // 验证报告存在
- await page.waitForSelector('.report-card, .result-item', { timeout: 10000 });
- });
- });
|