Add tests result

This commit is contained in:
Missez 2026-03-06 15:47:37 +07:00
parent 853c141910
commit 9e4fcbf04e
111 changed files with 1078 additions and 77 deletions

View file

@ -100,7 +100,7 @@ test.describe('Admin Categories', () => {
await deleteBtn.click();
await page.waitForTimeout(500);
await page.getByRole('button', { name: 'OK' }).click();
await page.getByRole('button', { name: 'ลบหมวดหมู่' }).click();
await page.waitForTimeout(500);
await expect(page.locator('.q-notification').filter({ hasText: 'deleted' })).toBeVisible({ timeout: 10_000 });
});

View file

@ -57,11 +57,7 @@ test.describe('Admin Recommended Courses', () => {
await expect(page.getByText('รายละเอียด (Description)')).toBeVisible();
await expect(page.getByText('หมวดหมู่ (Category):')).toBeVisible();
await expect(page.getByText('ผู้สอน (Instructors)')).toBeVisible();
// Close dialog via close button in q-bar
await page.locator('.q-bar .q-btn').filter({ has: page.locator('[class*="q-icon"]') }).click();
await page.waitForTimeout(300);
await expect(page.getByText('รายละเอียดคอร์ส (Course Details)')).not.toBeVisible();
await page.waitForTimeout(1000);
}
});
});

View file

@ -24,6 +24,7 @@ test.describe('Login Page', () => {
test('should show validation errors for empty fields', async ({ page }) => {
// Click submit without filling fields
await page.locator('button[type="submit"]').click();
await page.waitForTimeout(1000);
// Expect validation messages in Thai
await expect(page.getByText('กรุณากรอกอีเมล')).toBeVisible();
@ -31,8 +32,11 @@ test.describe('Login Page', () => {
test('should show validation errors for empty fields password', async ({ page }) => {
// Click submit without filling fields
await page.waitForTimeout(1000);
await page.locator('input[type="email"]').fill('test@email.com');
await page.waitForTimeout(1000);
await page.locator('button[type="submit"]').click();
await page.waitForTimeout(1000);
// Expect validation messages in Thai
await expect(page.getByText('กรุณากรอกรหัสผ่าน')).toBeVisible();
@ -76,11 +80,13 @@ test.describe('Login Page', () => {
});
test('should login as instructor and redirect to /instructor', async ({ page }) => {
await page.waitForTimeout(1000);
await page.locator('input[type="email"]').fill(TEST_INSTRUCTOR.email);
await page.waitForTimeout(1000);
await page.locator('input[type="password"]').fill(TEST_INSTRUCTOR.password);
await page.waitForTimeout(1000);
await page.locator('button[type="submit"]').click();
await page.waitForTimeout(1000);
// Should redirect to instructor dashboard
await page.waitForURL('**/instructor**', { timeout: 15_000 });
@ -88,7 +94,9 @@ test.describe('Login Page', () => {
});
test('should open forgot password modal', async ({ page }) => {
await page.waitForTimeout(1000);
await page.getByText('ลืมรหัสผ่าน?').click();
await page.waitForTimeout(1000);
// Modal should be visible
await expect(page.getByText('ลืมรหัสผ่าน').nth(1)).toBeVisible();

View file

@ -53,15 +53,16 @@ test.describe.serial('Course Detail Tabs', () => {
await expect(structureTab).toBeVisible();
// ตรวจสอบว่ามี chapters หรือ empty state
const hasChapters = await page.locator('.font-semibold').getByText(/^Chapter/).first().isVisible().catch(() => false);
await expect(page.getByText('โครงสร้างบทเรียน')).toBeVisible();
const hasEmptyState = await page.getByText('ยังไม่มีบทเรียน').isVisible().catch(() => false);
const hasChapters = !hasEmptyState && (await page.locator('.q-list.border-t').first().isVisible().catch(() => false));
expect(hasChapters || hasEmptyState).toBeTruthy();
// ถ้ามี chapters → กดเข้าดู lesson แรก
if (hasChapters) {
// หา lesson แรกใน structure tab แล้วกด
const firstLesson = page.locator('.q-item').filter({ hasText: /^Lesson/ }).first();
const firstLesson = page.locator('.q-item').filter({ hasText: /Lesson \d/ }).first();
await expect(firstLesson).toBeVisible();
await firstLesson.click();
@ -154,10 +155,6 @@ test.describe.serial('Course Detail Tabs', () => {
// ตรวจสอบว่ามีผลลัพธ์ (dropdown options) หรือ "ไม่พบผู้ใช้"
const hasResults = await page.locator('.q-menu .q-item').first().isVisible().catch(() => false);
expect(hasResults).toBeTruthy();
// ปิด dialog
await dialog.getByRole('button', { name: 'ยกเลิก' }).click();
await expect(dialog).toBeHidden({ timeout: 3_000 });
}
});
@ -251,7 +248,6 @@ test.describe.serial('Course Detail Tabs', () => {
await expect(dialog.getByText('สร้างประกาศใหม่')).toBeVisible();
// กรอกหัวข้อ (ภาษาไทย)
await dialog.locator('input').filter({ has: page.locator('[aria-label="หัวข้อ (ภาษาไทย) *"]') }).first().click();
await dialog.getByLabel('หัวข้อ (ภาษาไทย) *').fill(announcementTitle);
// กรอกหัวข้อ (English)

View file

@ -30,15 +30,10 @@ test.describe('Instructor Courses List', () => {
await expect(searchInput).toBeVisible();
await searchInput.fill('JavaScript');
await page.waitForLoadState('networkidle');
await page.waitForTimeout(1000);
await expect(page.getByText('พื้นฐาน JavaScript', { exact: true })).toBeVisible();
});
test('should have status filter dropdown', async ({ page }) => {
// Click the status select to open dropdown
const statusSelect = page.locator('.q-select').first();
await expect(statusSelect).toBeVisible();
});
test('should toggle between card and table view', async ({ page }) => {
// Switch to table view
await page.locator('.q-btn-toggle button').last().click();
@ -50,6 +45,7 @@ test.describe('Instructor Courses List', () => {
// Table should have expected columns
await expect(page.locator('thead').getByText('สถานะ')).toBeVisible();
await expect(page.locator('thead').getByText('ราคา')).toBeVisible();
await page.waitForTimeout(1000);
// Switch back to card view
await page.locator('.q-btn-toggle button').first().click();
@ -66,7 +62,7 @@ test.describe('Instructor Courses List', () => {
});
test('should show course action menu', async ({ page }) => {
const moreBtn = page.locator('button:has(.q-icon[class*="more_vert"])').first();
const moreBtn = page.locator('button').filter({ has: page.locator('.q-icon:has-text("more_vert")') }).first();
const hasCourses = await moreBtn.isVisible().catch(() => false);
if (hasCourses) {
@ -75,11 +71,12 @@ test.describe('Instructor Courses List', () => {
// Menu should show duplicate and delete options
await expect(page.getByText('ทำสำเนา')).toBeVisible();
await expect(page.getByText('ลบ')).toBeVisible();
await page.waitForTimeout(1000);
}
});
test('should open clone dialog from menu', async ({ page }) => {
const moreBtn = page.locator('button:has(.q-icon[class*="more_vert"])').first();
const moreBtn = page.locator('button').filter({ has: page.locator('.q-icon:has-text("more_vert")') }).first();
const hasCourses = await moreBtn.isVisible().catch(() => false);
if (hasCourses) {
@ -89,6 +86,7 @@ test.describe('Instructor Courses List', () => {
// Clone dialog should appear
await expect(page.getByText('ทำสำเนาหลักสูตร')).toBeVisible();
await expect(page.locator('.q-dialog input').first()).toBeVisible();
await page.waitForTimeout(1000);
}
});
@ -99,7 +97,7 @@ test.describe('Instructor Courses List', () => {
await page.waitForLoadState('networkidle');
// If there are rejected courses, clicking view should show rejection dialog
const viewBtn = page.locator('button:has(.q-icon[class*="visibility"])').first();
const viewBtn = page.locator('button').filter({ has: page.locator('.q-icon:has-text("visibility")') }).first();
const hasRejected = await viewBtn.isVisible().catch(() => false);
if (hasRejected) {
@ -109,6 +107,7 @@ test.describe('Instructor Courses List', () => {
await expect(page.getByText('หลักสูตรถูกปฏิเสธ')).toBeVisible();
await expect(page.getByText('เหตุผลการปฏิเสธ')).toBeVisible();
await expect(page.getByRole('button', { name: /คืนสถานะเป็นแบบร่าง/ })).toBeVisible();
await page.waitForTimeout(1000);
}
});
});