elearning/frontend_management/tests/instructor/courses-list.spec.ts
Missez 9bc24fbe8a
All checks were successful
Build and Deploy Frontend Management to Dev Server / Build Frontend Management Docker Image (push) Successful in 1m17s
Build and Deploy Frontend Management to Dev Server / Deploy E-learning Frontend Management to Dev Server (push) Successful in 8s
Build and Deploy Frontend Management to Dev Server / Notify Deployment Status (push) Successful in 2s
feat: Establish Playwright testing infrastructure with initial tests for authentication, admin, and instructor modules, and fix instructor video and quiz lesson management pages.
2026-03-02 15:48:47 +07:00

133 lines
5.9 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();
});
test('should have create course button', async ({ page }) => {
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 display stats cards', async ({ page }) => {
await expect(page.getByText('หลักสูตรทั้งหมด')).toBeVisible();
await expect(page.getByText('เผยแพร่แล้ว')).toBeVisible();
await expect(page.getByText('รอตรวจสอบ')).toBeVisible();
await expect(page.getByText('แบบร่าง')).toBeVisible();
await expect(page.getByText('ถูกปฏิเสธ')).toBeVisible();
});
test('should have search input', async ({ page }) => {
const searchInput = page.locator('input[placeholder*="ค้นหา"]');
await expect(searchInput).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 filter by status', async ({ page }) => {
// Open status dropdown
await page.locator('.q-select').first().click();
// Select "เผยแพร่แล้ว" (APPROVED)
await page.getByText('เผยแพร่แล้ว').click();
// Wait for API re-fetch
await page.waitForLoadState('networkidle');
});
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.getByText('หลักสูตร')).toBeVisible();
await expect(page.getByText('สถานะ')).toBeVisible();
await expect(page.getByText('ราคา')).toBeVisible();
// 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:has(.q-icon[class*="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();
}
});
test('should open clone dialog from menu', async ({ page }) => {
const moreBtn = page.locator('button:has(.q-icon[class*="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();
}
});
test('should handle rejected course view details', async ({ page }) => {
// Filter by rejected status
await page.locator('.q-select').first().click();
await page.getByText('ถูกปฏิเสธ').click();
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 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();
}
});
});