All checks were successful
Build and Deploy Frontend Learner / Build Frontend Learner Docker Image (push) Successful in 48s
Build and Deploy Frontend Learner / Deploy E-learning Frontend Learner to Dev Server (push) Successful in 4s
Build and Deploy Frontend Learner / Notify Deployment Status (push) Successful in 1s
129 lines
4.2 KiB
TypeScript
129 lines
4.2 KiB
TypeScript
/**
|
|
* @file helpers.ts
|
|
* @description Shared E2E test helpers — ฟังก์ชันที่ใช้ร่วมกันในทุกไฟล์ test
|
|
* รวม: waitAppSettled, login helpers, common locators, constants
|
|
*/
|
|
import { type Page, type Locator, expect } from '@playwright/test';
|
|
|
|
// ==========================================
|
|
// Constants
|
|
// ==========================================
|
|
export const BASE_URL = process.env.E2E_BASE_URL ?? 'http://localhost:3000';
|
|
export const TEST_EMAIL = 'studentedtest@example.com';
|
|
export const TEST_PASSWORD = 'admin123';
|
|
|
|
/** Timeout configs — ปรับค่าได้ที่เดียว */
|
|
export const TIMEOUT: Record<string, number> = {
|
|
/** รอหน้าโหลด */
|
|
PAGE_LOAD: 15_000,
|
|
/** รอ login + redirect */
|
|
LOGIN: 25_000,
|
|
/** รอ element แสดงผล */
|
|
ELEMENT: 12_000,
|
|
/** รอ network settle */
|
|
SETTLE: 300,
|
|
};
|
|
|
|
// ==========================================
|
|
// Wait Helpers
|
|
// ==========================================
|
|
|
|
/**
|
|
* รอให้แอปโหลดเสร็จสมบูรณ์ (DOM + Network + hydration)
|
|
*/
|
|
export async function waitAppSettled(page: Page, ms = TIMEOUT.SETTLE) {
|
|
await page.waitForLoadState('domcontentloaded');
|
|
await page.waitForLoadState('networkidle').catch(() => {});
|
|
await page.waitForTimeout(ms);
|
|
}
|
|
|
|
/**
|
|
* รอจนกว่า locator ใดก็ได้ใน array จะ visible
|
|
* @throws เมื่อไม่มี locator ไหน visible ภายใน timeout
|
|
*/
|
|
export async function expectAnyVisible(
|
|
page: Page,
|
|
locators: Locator[],
|
|
timeout = TIMEOUT.PAGE_LOAD
|
|
) {
|
|
const start = Date.now();
|
|
while (Date.now() - start < timeout) {
|
|
for (const loc of locators) {
|
|
try {
|
|
if (await loc.isVisible()) return;
|
|
} catch { /* locator detached / stale — ลองใหม่ */ }
|
|
}
|
|
await page.waitForTimeout(200);
|
|
}
|
|
throw new Error(
|
|
`None of the expected locators became visible within ${timeout}ms`
|
|
);
|
|
}
|
|
|
|
// ==========================================
|
|
// Login Locators
|
|
// ==========================================
|
|
|
|
export function emailLocator(page: Page): Locator {
|
|
return page
|
|
.locator('input[type="email"]')
|
|
.or(page.getByRole('textbox', { name: /อีเมล|email/i }))
|
|
.first();
|
|
}
|
|
|
|
export function passwordLocator(page: Page): Locator {
|
|
return page
|
|
.locator('input[type="password"]')
|
|
.or(page.getByRole('textbox', { name: /รหัสผ่าน|password/i }))
|
|
.first();
|
|
}
|
|
|
|
export function loginButtonLocator(page: Page): Locator {
|
|
return page
|
|
.getByRole('button', { name: /เข้าสู่ระบบ|login/i })
|
|
.or(page.locator('button[type="submit"]'))
|
|
.first();
|
|
}
|
|
|
|
// ==========================================
|
|
// Login Flow
|
|
// ==========================================
|
|
|
|
/**
|
|
* ล็อกอินด้วย test account — ใช้ใน beforeEach ของ tests ที่ต้อง authenticate
|
|
*
|
|
* @param page — Playwright Page
|
|
* @param opts — ตัวเลือกเสริม
|
|
* @param opts.assertDashboard — (default: true) ถ้า true จะ assert ว่าเข้า dashboard สำเร็จ
|
|
*
|
|
* @throws หาก login ล้มเหลวหรือไม่ถึง dashboard
|
|
*/
|
|
export async function setupLogin(
|
|
page: Page,
|
|
opts: { assertDashboard?: boolean } = {}
|
|
) {
|
|
const { assertDashboard = true } = opts;
|
|
|
|
await page.goto(`${BASE_URL}/auth/login`, { waitUntil: 'domcontentloaded' });
|
|
await waitAppSettled(page);
|
|
|
|
// กรอกข้อมูล
|
|
await emailLocator(page).fill(TEST_EMAIL);
|
|
await passwordLocator(page).fill(TEST_PASSWORD);
|
|
await loginButtonLocator(page).click();
|
|
|
|
// รอ redirect ไป dashboard
|
|
await page.waitForURL('**/dashboard', { timeout: TIMEOUT.LOGIN });
|
|
await waitAppSettled(page);
|
|
|
|
if (assertDashboard) {
|
|
// ยืนยันว่าเข้า dashboard ได้จริง
|
|
const evidence = [
|
|
page.locator('.q-page-container').first(),
|
|
page.locator('.q-drawer').first(),
|
|
page.locator('img[src*="avataaars"]').first(),
|
|
page.locator('img[alt],[alt="User Avatar"]').first(),
|
|
];
|
|
await expectAnyVisible(page, evidence, TIMEOUT.PAGE_LOAD);
|
|
}
|
|
}
|