自動化學生購買與報名課程的完整流程,確保報名權限與點數扣除正確對齊。
此技能自動化學生在平台上的核心操作流程,特別是針對「點數不足時自動儲值並重新報名」的邏輯驗證。
auto-login 邏輯,使用指定測試帳號並繞過驗證碼完成登入。/pricing 進行儲值,點數足夠則直接跳至課程報名。
point-purchase-flow 技能,本技能專注於報名與扣點邏輯。/pricing/checkout 使用「模擬支付」完成自動儲值。point-purchase-flow 技能,本技能專注於整合報名邏輯。/api/orders 請求並驗證 paymentMethod 為 points 的準確性。pointCost 是否相符。/classroom。architecture_overview.md 所定義的標準核心操作流程執行驗證。app/courses/[id]/page.tsx (課程詳情入口)app/student_courses/page.tsx (學生課程清單頁)app/pricing/page.tsx & app/pricing/checkout/page.tsx (點數檢查與模擬支付)components/EnrollButton.tsx (報名按鈕核心組件,攔截扣點邏輯)components/EnrollmentManager.tsx (報名彈窗與狀態切換)components/OrdersManager.tsx (訂單清單顯示管理)app/api/orders/route.ts (報名訂單處理 API)app/api/points/route.ts (點數餘額同步 API)lib/pricingService.ts (點數扣除與折扣計算邏輯)lib/pointsStorage.ts (DynamoDB 點數存取底層邏輯)若報名或支付流程失敗,請執行以下檢查:
schema.graphql 變動或流程邏輯修改時,必須同步更新 architecture_overview.md。自動化測試腳本在執行過程中會動態生成暫時性課程,以下是相關規律:
test-course-${Date.now()} 或 AI 自動測試課程-${Date.now()}。/student_courses 頁面在讀取紀錄時會因失效而顯示 課程 ID(例如 test-course-1773471081484)作為標題回退顯示。e2e/student_enrollment_flow.spec.ts。用於驗證扣點與報名邏輯,不需真實信用卡。當被要求執行此流程或測試相關功能時,請:
執行 Playwright 測試:運行 e2e/student_enrollment_flow.spec.ts。
自動修正:
回報進度:回報最終成功狀態或無法自動修復的嚴重問題。
npx playwright test e2e/student_enrollment_flow.spec.ts
.env.local 必須包含 LOGIN_BYPASS_SECRET.env.local 必須包含 TEST_STUDENT_EMAIL / TEST_STUDENT_PASSWORDBASE_URL — 預設 http://localhost:3000,設為 https://www.jvtutorcorner.com 可切換正式環境e2e/student_enrollment_flow.spec.ts (模擬支付報名流程)npx playwright test e2e/student_enrollment_flow.spec.ts環境變數統一為 NEXT_PUBLIC_BASE_URL
原測試腳本 (E2E spec) 與 Playwright 配置對 BASE_URL 與 NEXT_PUBLIC_BASE_URL 的解析邏輯不一致。現已統一移除 BASE_URL 的依賴,所有測試流程(含 Playwright config)皆讀取 NEXT_PUBLIC_BASE_URL。
process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000'resetRes.ok 誤用屬性
與 courseRes.ok 相同問題,ok 必須呼叫為方法。
if (!resetRes.ok)if (!resetRes.ok())缺少點數扣除精準驗證
原測試硬編碼驗算 finalBalance !== 10,不適用不同方案或課程設定。
balanceBeforeEnroll - pointCost = finalBalance 的動態驗算。缺少「進入教室」步驟
原 E2E test 僅驗證到「報名成功」跳轉 /student_courses,沒有繼續進入教室的驗證。
/classroom。缺少 /api/orders 網路請求攔截
無法確認手動報名時 paymentMethod 是否正確設為 'points'。
page.waitForRequest 攔截 POST /api/orders,記錄並驗證 payload。courseRes.ok / cleanupRes.ok 誤用屬性
Playwright APIResponse.ok 是方法,非屬性,必須呼叫 ok()。
if (courseRes.ok) / if (cleanupRes.ok)if (courseRes.ok()) / if (cleanupRes.ok())pageText 可能為 null
page.locator('body').textContent() 回傳 Promise<string | null>,.catch(() => '') 只處理例外,不處理 null 回傳值。
const pageText = await page.locator('body').textContent().catch(() => '');const pageText = (await page.locator('body').textContent().catch(() => '')) ?? '';Playwright waitForNavigation 導致超時掛起
在 Next.js 此類 SPA(單頁應用程式)中,表單提交可能只觸發客戶端路由跳轉(Client-side routing),而不會觸發完整的網路導航。這會導致 page.waitForNavigation({ waitUntil: 'networkidle' }) 永遠等不到導航事件而觸發自動化腳本超時(例如 3 分鐘)。
await page.waitForNavigation({ waitUntil: 'networkidle' })await page.waitForURL(url => !url.href.includes('/login')) 或是等待特定的 DOM 元素。enrollmentType 為 points, plan, 與 both 且擁有大於 0 的 pointCost 的課程。若系統無可用課程,自動透過 API 以教師身份建立 points 課程測資。EnrollButton 只有當資料庫中的課程 enrollmentType === 'points' 時才允許送出 paymentMethod: 'points'。若設定為 plan 或 both 且環境尚未更新,會導致送出 paymentMethod: null,測試會報錯(點數未扣除)。https://www.jvtutorcorner.com 執行時,若遇到既有點數未扣除之問題,須確認 DynamoDB 內該課程的 enrollmentType 設定。points 課程),則採取 catch 策略忽略,避免強制 force 點擊而癱瘓測試。point-purchase-flow 技能管理。# 模擬支付完整測試
npx playwright test e2e/student_enrollment_flow.spec.ts