elearning/frontend_management/tests/instructor/courses-list.spec.ts
Missez 0205aab461
All checks were successful
Build and Deploy Frontend Management to Dev Server / Build Frontend Management Docker Image (push) Successful in 52s
Build and Deploy Frontend Management to Dev Server / Deploy E-learning Frontend Management to Dev Server (push) Successful in 4s
Build and Deploy Frontend Management to Dev Server / Notify Deployment Status (push) Successful in 1s
feat: Introduce core authentication service, several new admin management pages, and instructor feature tests.
2026-03-06 11:24:10 +07:00

114 lines
5.1 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 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();
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();
// 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.getByRole('listbox').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();
}
});
});