import { test, expect, type Page, type Locator } from '@playwright/test'; const BASE_URL = process.env.E2E_BASE_URL ?? 'http://localhost:3000'; // ใช้ account ตามที่คุณให้มา const EMAIL = 'studentedtest@example.com'; const PASSWORD = 'admin123'; async function waitAppSettled(page: Page) { await page.waitForLoadState('domcontentloaded'); await page.waitForLoadState('networkidle').catch(() => {}); await page.waitForTimeout(200); } function emailLocator(page: Page): Locator { return page .locator('input[type="email"]') .or(page.getByRole('textbox', { name: /อีเมล|email/i })) .first(); } function passwordLocator(page: Page): Locator { return page .locator('input[type="password"]') .or(page.getByRole('textbox', { name: /รหัสผ่าน|password/i })) .first(); } function loginButtonLocator(page: Page): Locator { return page .getByRole('button', { name: /เข้าสู่ระบบ|login/i }) .or(page.locator('button[type="submit"]')) .first(); } async function expectAnyVisible(page: Page, locators: Locator[], timeout = 20_000) { const start = Date.now(); while (Date.now() - start < timeout) { for (const loc of locators) { try { if (await loc.isVisible()) return; } catch {} } await page.waitForTimeout(200); } throw new Error('None of the expected dashboard locators became visible.'); } test.describe('Login -> Dashboard', () => { test('Success Login แล้วเข้า /dashboard ได้', async ({ page }) => { await page.goto(`${BASE_URL}/auth/login`, { waitUntil: 'domcontentloaded' }); await waitAppSettled(page); await emailLocator(page).fill(EMAIL); await passwordLocator(page).fill(PASSWORD); await loginButtonLocator(page).click(); await page.waitForURL('**/dashboard', { timeout: 25_000 }); await waitAppSettled(page); // ✅ ใช้ Locator ที่พบเจอแน่นอนใน Layout/Page โดยไม่ยึดติดกับภาษาปัจจุบัน (I18n) const dashboardEvidence = [ // มองหา Layout container ฝั่ง Dashboard page.locator('.q-page-container').first(), page.locator('.q-drawer').first(), // มองหารูปโปรไฟล์ (UserAvatar) page.locator('img[src*="avataaars"]').first(), page.locator('img[alt],[alt="User Avatar"]').first() ]; await expectAnyVisible(page, dashboardEvidence, 20_000); await page.screenshot({ path: 'tests/e2e/screenshots/login-to-dashboard.png', fullPage: true }); }); test('Invalid Email - Thai characters (พิมพ์ภาษาไทย)', async ({ page }) => { await page.goto(`${BASE_URL}/auth/login`, { waitUntil: 'domcontentloaded' }); await waitAppSettled(page); await emailLocator(page).fill('ทดสอบภาษาไทย'); await passwordLocator(page).fill(PASSWORD); const errorHint = page.getByText('ห้ามใส่ภาษาไทย'); await expect(errorHint.first()).toBeVisible({ timeout: 12_000 }); await page.screenshot({ path: 'tests/e2e/screenshots/login-thai-email.png', fullPage: true }); }); test('Invalid Email Format (อีเมลผิดรูปแบบ)', async ({ page }) => { await page.goto(`${BASE_URL}/auth/login`, { waitUntil: 'domcontentloaded' }); await waitAppSettled(page); // *สำคัญ*: HTML5 จะดักจับ invalid-email-format ตั้งแต่กด Submit (native validation) // ทำให้ Vue Form ไม่เริ่มทำงาน // ดังนั้นเพื่อให้ทดสอบเจอ Error จาก useFormValidation จริงๆ เราใช้ 'test@domain' // ซึ่ง HTML5 ปล่อยผ่าน แต่ /regex/ ของระบบตรวจเจอว่าไม่มี .com await emailLocator(page).fill('test@domain'); await passwordLocator(page).fill(PASSWORD); await loginButtonLocator(page).click(); await waitAppSettled(page); const errorHint = page.getByText('กรุณากรอกอีเมลให้ถูกต้อง (you@example.com)'); await expect(errorHint.first()).toBeVisible({ timeout: 12_000 }); await page.screenshot({ path: 'tests/e2e/screenshots/login-invalid-email.png', fullPage: true }); }); test('Wrong Password (รหัสผ่านผิด หรืออีเมลไม่ถูกต้องในระบบ)', async ({ page }) => { await page.goto(`${BASE_URL}/auth/login`, { waitUntil: 'domcontentloaded' }); await waitAppSettled(page); await emailLocator(page).fill(EMAIL); await passwordLocator(page).fill('wrong-password-123'); await loginButtonLocator(page).click(); await waitAppSettled(page); const errorHint = page.getByText('กรุณาเช็ค Email หรือ รหัสผ่านใหม่อีกครั้ง'); await expect(errorHint.first()).toBeVisible({ timeout: 12_000 }); await page.screenshot({ path: 'tests/e2e/screenshots/login-wrong-password.png', fullPage: true }); }); });