elearning/frontend_management/tests/instructor/courses-list.spec.ts
2026-03-06 15:47:43 +07:00

113 lines
5.2 KiB
TypeScript

import { test, expect } from '@playwright/test';
import { TEST_URLS } from '../fixtures/test-data';
/**
* Instructor Courses List Page Tests
* ใช้ cookies จาก instructor-setup project (ไม่ต้อง login ซ้ำ)
*/
test.describe('Instructor Courses List', () => {
test.beforeEach(async ({ page }) => {
await page.goto(TEST_URLS.instructorCourses);
await page.waitForLoadState('networkidle');
});
test('should display page header', async ({ page }) => {
await expect(page.getByText('หลักสูตรของฉัน')).toBeVisible();
await expect(page.getByText('จัดการหลักสูตรที่คุณสร้าง')).toBeVisible();
const createBtn = page.getByRole('button', { name: /สร้างหลักสูตรใหม่/ });
await expect(createBtn).toBeVisible();
});
test('should navigate to create course page', async ({ page }) => {
await page.getByRole('button', { name: /สร้างหลักสูตรใหม่/ }).click();
await page.waitForURL('**/instructor/courses/create**');
await expect(page).toHaveURL(/\/instructor\/courses\/create/);
});
test('should have search input', async ({ page }) => {
const searchInput = page.locator('input[placeholder*="ค้นหา"]');
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 toggle between card and table view', async ({ page }) => {
// Switch to table view
await page.locator('.q-btn-toggle button').last().click();
await page.waitForTimeout(300);
// Table should appear
await expect(page.locator('.q-table')).toBeVisible();
// 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();
await page.waitForTimeout(300);
});
test('should show course cards with status badges', async ({ page }) => {
// Wait for courses to load (either card or empty state)
const hasCards = await page.locator('.q-badge').first().isVisible().catch(() => false);
const isEmpty = await page.getByText('ยังไม่มีหลักสูตร').isVisible().catch(() => false);
// Either courses exist with badges or empty state shows
expect(hasCards || isEmpty).toBeTruthy();
});
test('should show course action menu', async ({ page }) => {
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) {
await moreBtn.click();
// 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').filter({ has: page.locator('.q-icon:has-text("more_vert")') }).first();
const hasCourses = await moreBtn.isVisible().catch(() => false);
if (hasCourses) {
await moreBtn.click();
await page.getByText('ทำสำเนา').click();
// Clone dialog should appear
await expect(page.getByText('ทำสำเนาหลักสูตร')).toBeVisible();
await expect(page.locator('.q-dialog input').first()).toBeVisible();
await page.waitForTimeout(1000);
}
});
test('should handle rejected course view details', async ({ page }) => {
// Filter by rejected status
await page.locator('.q-select').first().click();
await page.getByRole('listbox').getByText('ถูกปฏิเสธ').click();
await page.waitForLoadState('networkidle');
// If there are rejected courses, clicking view should show rejection dialog
const viewBtn = page.locator('button').filter({ has: page.locator('.q-icon:has-text("visibility")') }).first();
const hasRejected = await viewBtn.isVisible().catch(() => false);
if (hasRejected) {
await viewBtn.click();
// Rejection dialog should appear
await expect(page.getByText('หลักสูตรถูกปฏิเสธ')).toBeVisible();
await expect(page.getByText('เหตุผลการปฏิเสธ')).toBeVisible();
await expect(page.getByRole('button', { name: /คืนสถานะเป็นแบบร่าง/ })).toBeVisible();
await page.waitForTimeout(1000);
}
});
});