dan-assessment-vendor-flow.spec.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  1. /**
  2. * ================================================================
  3. * 场景:DAN 测评服务商体系全流程 E2E 测试
  4. * ================================================================
  5. * 用户故事:
  6. * - 管理员:创建和管理服务商(测评/解读/规划)
  7. * - 家长:购买测评服务、查看 AI 解读、获取规划方案
  8. * - 测评服务商:提供测评服务、录入结果
  9. * - 解读服务商:AI 解读 + 人工解读报告
  10. * - 规划服务商:基于测评结果制定成长规划
  11. *
  12. * 流程步骤:
  13. * 1. 管理员创建三类服务商并审核
  14. * 2. 家长选择服务商并购买测评套餐
  15. * 3. 测评服务商完成测评并录入结果
  16. * 4. AI 自动生成解读报告
  17. * 5. 解读服务商进行人工解读补充
  18. * 6. 规划服务商制定成长规划方案
  19. * 7. 家长查看完整报告和规划
  20. *
  21. * 关键里程碑:
  22. * - [Milestone-1] 服务商创建并审核通过
  23. * - [Milestone-2] 测评订单支付成功
  24. * - [Milestone-3] 测评结果录入完成
  25. * - [Milestone-4] AI 解读报告生成
  26. * - [Milestone-5] 人工解读补充完成
  27. * - [Milestone-6] 成长规划方案生成
  28. * - [Milestone-7] 家长查看完整报告
  29. * ================================================================
  30. *
  31. * 运行:npx playwright test tests/e2e/dan-assessment-vendor-flow.spec.js
  32. */
  33. const { test, expect } = require('@playwright/test');
  34. test.describe('【场景流程】DAN 测评服务商体系全流程', () => {
  35. // ===== 场景 1:管理员创建测评服务商 =====
  36. test('[场景 1] 管理员创建测评服务商 - 期望创建并审核通过', async ({ page }) => {
  37. // ========== Given:管理员进入服务商管理页 ==========
  38. await page.goto('/#/pages/admin/vendor-review');
  39. await page.waitForLoadState('networkidle');
  40. // ========== When:创建测评服务商 ==========
  41. // 方式 1:审核入驻申请
  42. const pendingVendor = page.locator('.vendor-item:has-text("assessment_provider"), .vendor-item:has-text("测评服务")').first();
  43. if (await pendingVendor.isVisible()) {
  44. // 已有待审核的测评服务商
  45. const approveBtn = pendingVendor.locator('.approve-btn, .pass-btn');
  46. if (await approveBtn.isVisible()) {
  47. await approveBtn.click();
  48. }
  49. } else {
  50. // 方式 2:直接创建服务商用户
  51. await page.goto('/#/pages/admin/user-create');
  52. await page.waitForLoadState('networkidle');
  53. const phoneInput = page.locator('input[name="phone"], .phone-input');
  54. if (await phoneInput.isVisible()) {
  55. await phoneInput.fill('139' + String(Date.now()).slice(-8));
  56. }
  57. const nameInput = page.locator('input[name="nickname"], .name-input');
  58. if (await nameInput.isVisible()) {
  59. await nameInput.fill('测评服务商_' + Date.now());
  60. }
  61. // 选择服务商类型
  62. const vendorTypeSelect = page.locator('select[name="vendorType"], .vendor-type-picker');
  63. if (await vendorTypeSelect.isVisible()) {
  64. await vendorTypeSelect.selectOption('assessment_provider');
  65. }
  66. await page.click('.submit-btn, .save-btn');
  67. }
  68. // ========== Then:Milestone-1 - 服务商创建成功 ========
  69. await page.waitForSelector('.success-tip, .create-success, .vendor-approved', { timeout: 10000 });
  70. expect(await page.locator('.success-tip, .create-success').isVisible()).toBeTruthy();
  71. });
  72. // ===== 场景 2:管理员创建解读服务商 =====
  73. test('[场景 2] 管理员创建解读服务商 - 期望创建并审核通过', async ({ page }) => {
  74. // ========== Given:管理员进入服务商管理页 ==========
  75. await page.goto('/#/pages/admin/vendor-review');
  76. await page.waitForLoadState('networkidle');
  77. // ========== When:创建解读服务商 ==========
  78. await page.goto('/#/pages/admin/user-create');
  79. await page.waitForLoadState('networkidle');
  80. const phoneInput = page.locator('input[name="phone"], .phone-input');
  81. if (await phoneInput.isVisible()) {
  82. await phoneInput.fill('139' + String(Date.now()).slice(-8));
  83. }
  84. const nameInput = page.locator('input[name="nickname"], .name-input');
  85. if (await nameInput.isVisible()) {
  86. await nameInput.fill('解读服务商_' + Date.now());
  87. }
  88. // 选择解读服务商类型
  89. const vendorTypeSelect = page.locator('select[name="vendorType"], .vendor-type-picker');
  90. if (await vendorTypeSelect.isVisible()) {
  91. await vendorTypeSelect.selectOption('interpretation_provider');
  92. }
  93. await page.click('.submit-btn, .save-btn');
  94. // ========== Then:Milestone-1 - 服务商创建成功 ========
  95. await page.waitForSelector('.success-tip, .create-success', { timeout: 10000 });
  96. expect(await page.locator('.success-tip, .create-success').isVisible()).toBeTruthy();
  97. });
  98. // ===== 场景 3:管理员创建规划服务商 =====
  99. test('[场景 3] 管理员创建规划服务商 - 期望创建并审核通过', async ({ page }) => {
  100. // ========== Given:管理员进入服务商管理页 ==========
  101. await page.goto('/#/pages/admin/vendor-review');
  102. await page.waitForLoadState('networkidle');
  103. // ========== When:创建规划服务商 ==========
  104. await page.goto('/#/pages/admin/user-create');
  105. await page.waitForLoadState('networkidle');
  106. const phoneInput = page.locator('input[name="phone"], .phone-input');
  107. if (await phoneInput.isVisible()) {
  108. await phoneInput.fill('139' + String(Date.now()).slice(-8));
  109. }
  110. const nameInput = page.locator('input[name="nickname"], .name-input');
  111. if (await nameInput.isVisible()) {
  112. await nameInput.fill('规划服务商_' + Date.now());
  113. }
  114. // 选择规划服务商类型(使用现有的 planner)
  115. const vendorTypeSelect = page.locator('select[name="vendorType"], .vendor-type-picker');
  116. if (await vendorTypeSelect.isVisible()) {
  117. await vendorTypeSelect.selectOption('planner');
  118. }
  119. await page.click('.submit-btn, .save-btn');
  120. // ========== Then:Milestone-1 - 服务商创建成功 ========
  121. await page.waitForSelector('.success-tip, .create-success', { timeout: 10000 });
  122. expect(await page.locator('.success-tip, .create-success').isVisible()).toBeTruthy();
  123. });
  124. // ===== 场景 4:家长购买测评服务 =====
  125. test('[场景 4] 家长购买测评服务 - 期望订单支付成功', async ({ page }) => {
  126. // ========== Given:家长进入测评套餐页 ==========
  127. await page.goto('/#/pages/assessment/apply');
  128. await page.waitForLoadState('networkidle');
  129. // 验证页面加载
  130. await expect(page.locator('.assessment-apply-page, .package-list')).toBeVisible({ timeout: 10000 });
  131. // ========== Step 1:选择测评套餐 ==========
  132. const packageOption = page.locator('.package-option, .package-card').first();
  133. if (await packageOption.isVisible()) {
  134. await packageOption.click();
  135. }
  136. // ========== Step 2:选择测评服务商 ==========
  137. const providerSelect = page.locator('.provider-picker, .assessment-provider-select');
  138. if (await providerSelect.isVisible()) {
  139. await providerSelect.click();
  140. await page.waitForSelector('.provider-option', { timeout: 3000 });
  141. await page.locator('.provider-option:has-text("测评服务")').first().click();
  142. }
  143. // ========== Step 3:选择孩子 ==========
  144. const childPicker = page.locator('.child-picker');
  145. if (await childPicker.isVisible()) {
  146. await childPicker.click();
  147. await page.waitForSelector('.child-option', { timeout: 3000 });
  148. await page.locator('.child-option').first().click();
  149. }
  150. // ========== Step 4:选择解读服务商(可选)==========
  151. const interpretationSelect = page.locator('.interpretation-provider-select');
  152. if (await interpretationSelect.isVisible()) {
  153. await interpretationSelect.click();
  154. await page.waitForSelector('.provider-option', { timeout: 3000 });
  155. await page.locator('.provider-option:has-text("解读服务")').first().click();
  156. }
  157. // ========== When:提交订单 ==========
  158. await page.click('.submit-btn, .create-order-btn');
  159. // 等待订单创建
  160. await page.waitForSelector('.order-confirm-modal, .order-success-tip', { timeout: 10000 });
  161. // ========== Then:Milestone-2 - 订单创建成功 ========
  162. const orderNoElement = page.locator('.order-no, .order-number');
  163. let orderNo = '';
  164. if (await orderNoElement.isVisible()) {
  165. orderNo = await orderNoElement.textContent();
  166. expect(orderNo).toBeTruthy();
  167. }
  168. // ========== Step 5:支付订单 ==========
  169. const payBtn = page.locator('.pay-btn, .go-pay-btn');
  170. if (await payBtn.isVisible()) {
  171. await payBtn.click();
  172. }
  173. // 选择支付方式
  174. const wechatPay = page.locator('.pay-method:has-text("微信")');
  175. if (await wechatPay.isVisible()) {
  176. await wechatPay.click();
  177. }
  178. // 确认支付
  179. await page.click('.confirm-pay-btn');
  180. // 等待支付成功
  181. await page.waitForSelector('.pay-success-tip, .payment-success', { timeout: 15000 });
  182. // ========== Then:支付成功 ========
  183. const paySuccessTip = page.locator('.pay-success-tip, .payment-success');
  184. expect(await paySuccessTip.isVisible()).toBeTruthy();
  185. });
  186. // ===== 场景 5:测评服务商录入测评结果 =====
  187. test('[场景 5] 测评服务商录入测评结果 - 期望结果保存成功', async ({ page }) => {
  188. // ========== Given:测评服务商进入测评结果录入页 ==========
  189. await page.goto('/#/pages/guide/assessment/record');
  190. await page.waitForLoadState('networkidle');
  191. // 验证页面加载
  192. await expect(page.locator('.assessment-record-page, .pending-records')).toBeVisible({ timeout: 10000 });
  193. // ========== Step 1:选择待录入的预约 ==========
  194. const pendingRecord = page.locator('.pending-record-item, .appointment-item').first();
  195. if (await pendingRecord.isVisible()) {
  196. await pendingRecord.click();
  197. }
  198. // 等待录入表单加载
  199. await page.waitForSelector('.record-form, .result-input-form', { timeout: 5000 });
  200. // ========== Step 2:填写测评维度分数 ==========
  201. // 注意力分数
  202. const attentionInput = page.locator('input[name="attentionScore"], .attention-input');
  203. if (await attentionInput.isVisible()) {
  204. await attentionInput.fill('85');
  205. }
  206. // 专注力分数
  207. const focusInput = page.locator('input[name="focusScore"], .focus-input');
  208. if (await focusInput.isVisible()) {
  209. await focusInput.fill('88');
  210. }
  211. // 记忆力分数
  212. const memoryInput = page.locator('input[name="memoryScore"], .memory-input');
  213. if (await memoryInput.isVisible()) {
  214. await memoryInput.fill('82');
  215. }
  216. // 逻辑思维分数
  217. const logicInput = page.locator('input[name="logicScore"], .logic-input');
  218. if (await logicInput.isVisible()) {
  219. await logicInput.fill('90');
  220. }
  221. // 知觉分数
  222. const perceptionInput = page.locator('input[name="perceptionScore"], .perception-input');
  223. if (await perceptionInput.isVisible()) {
  224. await perceptionInput.fill('87');
  225. }
  226. // 空间分数
  227. const spatialInput = page.locator('input[name="spatialScore"], .spatial-input');
  228. if (await spatialInput.isVisible()) {
  229. await spatialInput.fill('84');
  230. }
  231. // 处理速度分数
  232. const speedInput = page.locator('input[name="processingSpeedScore"], .speed-input');
  233. if (await speedInput.isVisible()) {
  234. await speedInput.fill('86');
  235. }
  236. // ========== Step 3:填写分析评语 ==========
  237. const analysisTextarea = page.locator('textarea[name="analysisReport"], .analysis-textarea');
  238. if (await analysisTextarea.isVisible()) {
  239. await analysisTextarea.fill('孩子在注意力和逻辑思维方面表现优秀,专注力良好。建议加强记忆力训练,提升空间感知能力。');
  240. }
  241. // ========== Step 4:填写成长建议 ==========
  242. const suggestionsTextarea = page.locator('textarea[name="growthSuggestions"], .suggestions-textarea');
  243. if (await suggestionsTextarea.isVisible()) {
  244. await suggestionsTextarea.fill('1. 每日专注力训练 15 分钟\n2. 记忆力游戏(如卡片配对)\n3. 空间拼图练习\n4. 逻辑思维题目训练');
  245. }
  246. // ========== When:提交测评结果 ==========
  247. await page.click('.submit-btn, .submit-result-btn');
  248. // ========== Then:Milestone-3 - 测评结果录入成功 ========
  249. await page.waitForSelector('.success-tip, .result-saved, .submit-success', { timeout: 10000 });
  250. expect(await page.locator('.success-tip, .result-saved').isVisible()).toBeTruthy();
  251. });
  252. // ===== 场景 6:AI 自动生成解读报告 =====
  253. test('[场景 6] AI 自动生成解读报告 - 期望报告生成成功', async ({ page }) => {
  254. // ========== Given:等待 AI 解读报告生成 ==========
  255. // AI 解读通常是自动触发的,在测评结果提交后系统自动生成
  256. // 这里我们验证 AI 解读报告是否已生成
  257. await page.goto('/#/pages/assessment/results');
  258. await page.waitForLoadState('networkidle');
  259. // ========== When:查看 AI 解读报告 ==========
  260. await page.waitForSelector('.ai-report-card, .ai-interpretation, .auto-report', { timeout: 15000 });
  261. // ========== Then:Milestone-4 - AI 解读报告生成 ========
  262. const aiReportCard = page.locator('.ai-report-card, .ai-interpretation');
  263. expect(await aiReportCard.isVisible()).toBeTruthy();
  264. // 验证报告包含关键内容
  265. const reportContent = page.locator('.report-content, .interpretation-text');
  266. if (await reportContent.isVisible()) {
  267. const contentText = await reportContent.textContent();
  268. expect(contentText.length).toBeGreaterThan(0);
  269. }
  270. // 验证包含维度分析
  271. const dimensionAnalysis = page.locator('.dimension-analysis, .score-analysis');
  272. if (await dimensionAnalysis.isVisible()) {
  273. const analysisText = await dimensionAnalysis.textContent();
  274. expect(analysisText).toContain('注意力') || expect(analysisText).toContain('专注力');
  275. }
  276. });
  277. // ===== 场景 7:解读服务商进行人工解读补充 =====
  278. test('[场景 7] 解读服务商人工解读补充 - 期望补充完成', async ({ page }) => {
  279. // ========== Given:解读服务商进入人工解读页 ==========
  280. await page.goto('/#/pages/interpretation/manual-review');
  281. await page.waitForLoadState('networkidle');
  282. // 验证页面加载
  283. await expect(page.locator('.manual-review-page, .pending-interpretations')).toBeVisible({ timeout: 10000 });
  284. // ========== Step 1:选择待解读的报告 ==========
  285. const pendingReport = page.locator('.pending-report-item, .interpretation-item').first();
  286. if (await pendingReport.isVisible()) {
  287. await pendingReport.click();
  288. }
  289. // 等待解读表单加载
  290. await page.waitForSelector('.interpretation-form, .manual-review-form', { timeout: 5000 });
  291. // ========== Step 2:查看 AI 解读报告 ==========
  292. const aiReportSection = page.locator('.ai-report-section, .ai-interpretation-preview');
  293. if (await aiReportSection.isVisible()) {
  294. // AI 报告已加载
  295. expect(await aiReportSection.isVisible()).toBeTruthy();
  296. }
  297. // ========== Step 3:补充人工解读 ==========
  298. const manualAnalysisTextarea = page.locator('textarea[name="manualAnalysis"], .manual-analysis-textarea');
  299. if (await manualAnalysisTextarea.isVisible()) {
  300. await manualAnalysisTextarea.fill('补充解读:孩子在认知发展方面整体表现良好,特别是在逻辑思维方面有明显优势。建议家长关注孩子的注意力训练,可以通过游戏化方式提升专注力持续时间。');
  301. }
  302. // ========== Step 4:补充个性化建议 ==========
  303. const personalizedSuggestions = page.locator('textarea[name="personalizedSuggestions"], .suggestions-textarea');
  304. if (await personalizedSuggestions.isVisible()) {
  305. await personalizedSuggestionsSuggestions.fill('1. 建议每周进行 3 次专注力训练\n2. 推荐参加逻辑思维兴趣班\n3. 家长陪伴阅读提升理解能力\n4. 定期复查跟踪发展状况');
  306. }
  307. // ========== When:提交人工解读 ==========
  308. await page.click('.submit-btn, .submit-interpretation-btn');
  309. // ========== Then:Milestone-5 - 人工解读补充完成 ========
  310. await page.waitForSelector('.success-tip, .interpretation-submitted, .submit-success', { timeout: 10000 });
  311. expect(await page.locator('.success-tip, .interpretation-submitted').isVisible()).toBeTruthy();
  312. });
  313. // ===== 场景 8:规划服务商制定成长规划方案 =====
  314. test('[场景 8] 规划服务商制定成长规划 - 期望规划方案生成', async ({ page }) => {
  315. // ========== Given:规划服务商进入规划制定页 ==========
  316. await page.goto('/#/pages/planner/growth-plan/create');
  317. await page.waitForLoadState('networkidle');
  318. // 验证页面加载
  319. await expect(page.locator('.growth-plan-page, .plan-form')).toBeVisible({ timeout: 10000 });
  320. // ========== Step 1:选择孩子 ==========
  321. const childPicker = page.locator('.child-picker');
  322. if (await childPicker.isVisible()) {
  323. await childPicker.click();
  324. await page.waitForSelector('.child-option', { timeout: 3000 });
  325. await page.locator('.child-option').first().click();
  326. }
  327. // ========== Step 2:查看测评结果 ==========
  328. const assessmentResultSection = page.locator('.assessment-result-section, .result-preview');
  329. if (await assessmentResultSection.isVisible()) {
  330. // 测评结果已加载
  331. expect(await assessmentResultSection.isVisible()).toBeTruthy();
  332. }
  333. // ========== Step 3:制定短期目标(1-3 个月)==========
  334. const shortTermGoalInput = page.locator('textarea[name="shortTermGoal"], .short-term-input');
  335. if (await shortTermGoalInput.isVisible()) {
  336. await shortTermGoalInput.fill('提升专注力持续时间至 20 分钟,增强记忆力训练效果');
  337. }
  338. // ========== Step 4:制定中期目标(3-6 个月)==========
  339. const midTermGoalInput = page.locator('textarea[name="midTermGoal"], .mid-term-input');
  340. if (await midTermGoalInput.isVisible()) {
  341. await midTermGoalInput.fill('全面提升五维能力,特别是逻辑思维和空间感知能力');
  342. }
  343. // ========== Step 5:制定长期目标(6-12 个月)==========
  344. const longTermGoalInput = page.locator('textarea[name="longTermGoal"], .long-term-input');
  345. if (await longTermGoalInput.isVisible()) {
  346. await longTermGoalInput.fill('建立完整的学习能力体系,为幼小衔接做好准备');
  347. }
  348. // ========== Step 6:制定训练计划 ==========
  349. const trainingPlanTextarea = page.locator('textarea[name="trainingPlan"], .training-plan-textarea');
  350. if (await trainingPlanTextarea.isVisible()) {
  351. await trainingPlanTextarea.fill(`
  352. 【每日训练】
  353. - 专注力训练:舒尔特方格 10 分钟
  354. - 记忆力训练:卡片配对游戏 15 分钟
  355. 【每周训练】
  356. - 逻辑思维:数学思维题 3 次/周
  357. - 空间感知:拼图游戏 2 次/周
  358. 【每月评估】
  359. - 月度能力测评
  360. - 训练效果跟踪
  361. - 方案调整优化
  362. `);
  363. }
  364. // ========== Step 7:推荐配套服务 ==========
  365. const serviceRecommendation = page.locator('.service-recommendation, .service-checkbox');
  366. if (await serviceRecommendation.isVisible()) {
  367. // 选择推荐的服务
  368. await page.locator('.service-checkbox:has-text("专注力训练")').first().click();
  369. }
  370. // ========== When:提交成长规划方案 ==========
  371. await page.click('.submit-btn, .create-plan-btn');
  372. // ========== Then:Milestone-6 - 成长规划方案生成 ========
  373. await page.waitForSelector('.success-tip, .plan-created, .submit-success', { timeout: 10000 });
  374. expect(await page.locator('.success-tip, .plan-created').isVisible()).toBeTruthy();
  375. });
  376. // ===== 场景 9:家长查看完整报告和规划 =====
  377. test('[场景 9] 家长查看完整报告和规划 - 期望查看成功', async ({ page }) => {
  378. // ========== Given:家长进入报告查看页 ==========
  379. await page.goto('/#/pages/assessment/results');
  380. await page.waitForLoadState('networkidle');
  381. // ========== When:查看完整报告 ==========
  382. // 验证测评结果
  383. await page.waitForSelector('.assessment-result-card, .result-summary', { timeout: 10000 });
  384. const resultCard = page.locator('.assessment-result-card, .result-summary');
  385. expect(await resultCard.isVisible()).toBeTruthy();
  386. // 验证 AI 解读报告
  387. const aiReportSection = page.locator('.ai-report-section, .ai-interpretation');
  388. expect(await aiReportSection.isVisible()).toBeTruthy();
  389. // 验证人工解读报告
  390. const manualReportSection = page.locator('.manual-interpretation-section, .manual-interpretation');
  391. if (await manualReportSection.isVisible()) {
  392. expect(await manualReportSection.isVisible()).toBeTruthy();
  393. }
  394. // 验证成长规划方案
  395. const growthPlanSection = page.locator('.growth-plan-section, .growth-plan');
  396. if (await growthPlanSection.isVisible()) {
  397. expect(await growthPlanSection.isVisible()).toBeTruthy();
  398. }
  399. // ========== Then:Milestone-7 - 完整报告查看成功 ========
  400. // 验证报告包含完整内容
  401. const fullReportContent = page.locator('.full-report, .complete-report');
  402. if (await fullReportContent.isVisible()) {
  403. const contentText = await fullReportContent.textContent();
  404. expect(contentText.length).toBeGreaterThan(100);
  405. }
  406. // 验证包含所有关键部分
  407. const sections = page.locator('.report-section, .report-part');
  408. const sectionCount = await sections.count();
  409. expect(sectionCount).toBeGreaterThanOrEqual(3); // 至少包含:测评结果、AI 解读、规划方案
  410. });
  411. // ===== 场景 10:完整流程端到端测试 =====
  412. test('[场景 10] DAN 测评服务商完整流程 - 期望全流程成功', async ({ page }) => {
  413. // ========== Step 1:管理员创建服务商 ==========
  414. await page.goto('/#/pages/admin/vendor-review');
  415. await page.waitForLoadState('networkidle');
  416. // 验证服务商管理页面加载
  417. expect(await page.locator('.vendor-review-page').isVisible()).toBeTruthy();
  418. // ========== Step 2:家长购买测评 ==========
  419. await page.goto('/#/pages/assessment/apply');
  420. await page.waitForLoadState('networkidle');
  421. // 选择套餐并提交
  422. const packageOption = page.locator('.package-option').first();
  423. if (await packageOption.isVisible()) {
  424. await packageOption.click();
  425. await page.click('.submit-btn');
  426. await page.waitForSelector('.order-confirm-modal', { timeout: 10000 });
  427. }
  428. // ========== Step 3:测评服务商录入结果 ==========
  429. await page.goto('/#/pages/guide/assessment/record');
  430. await page.waitForLoadState('networkidle');
  431. const pendingRecord = page.locator('.pending-record-item').first();
  432. if (await pendingRecord.isVisible()) {
  433. await pendingRecord.click();
  434. await page.waitForSelector('.record-form', { timeout: 5000 });
  435. // 填写分数
  436. const scoreInputs = page.locator('.score-input');
  437. const count = await scoreInputs.count();
  438. for (let i = 0; i < count; i++) {
  439. await scoreInputs.nth(i).fill('85');
  440. }
  441. await page.click('.submit-result-btn');
  442. await page.waitForSelector('.result-saved', { timeout: 10000 });
  443. }
  444. // ========== Step 4:查看完整报告 ==========
  445. await page.goto('/#/pages/assessment/results');
  446. await page.waitForLoadState('networkidle');
  447. // 验证报告存在
  448. await page.waitForSelector('.result-card, .report-summary', { timeout: 10000 });
  449. const resultCard = page.locator('.result-card, .report-summary');
  450. expect(await resultCard.isVisible()).toBeTruthy();
  451. // ========== Then:全流程成功 ========
  452. // 验证所有里程碑都已达成
  453. const milestones = [
  454. page.locator('.assessment-result-card'),
  455. page.locator('.ai-interpretation'),
  456. page.locator('.growth-plan')
  457. ];
  458. for (const milestone of milestones) {
  459. if (await milestone.isVisible()) {
  460. expect(await milestone.isVisible()).toBeTruthy();
  461. }
  462. }
  463. });
  464. });