feat: Establish Playwright testing infrastructure with initial tests for authentication, admin, and instructor modules, and fix instructor video and quiz lesson management pages.
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
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
This commit is contained in:
parent
734d922393
commit
9bc24fbe8a
18 changed files with 1344 additions and 7 deletions
213
frontend_management/tests/admin/users.spec.ts
Normal file
213
frontend_management/tests/admin/users.spec.ts
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
import { test, expect } from '@playwright/test';
|
||||
import { TEST_URLS } from '../fixtures/test-data';
|
||||
|
||||
/**
|
||||
* Admin Users Page Tests
|
||||
* ใช้ cookies จาก admin-setup project (ไม่ต้อง login ซ้ำ)
|
||||
*/
|
||||
test.describe('Admin Users', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto(TEST_URLS.adminUsers);
|
||||
await page.waitForLoadState('networkidle');
|
||||
});
|
||||
|
||||
test('check display page', async ({ page }) => {
|
||||
// Header
|
||||
await expect(page.getByText('จัดการผู้ใช้งาน')).toBeVisible();
|
||||
|
||||
// Search input
|
||||
await expect(page.locator('input[placeholder*="ค้นหาชื่อ"]')).toBeVisible();
|
||||
|
||||
// Stats cards
|
||||
await expect(page.getByText('ผู้ใช้ทั้งหมด')).toBeVisible();
|
||||
await expect(page.getByText('Admin', { exact: true })).toBeVisible();
|
||||
await expect(page.getByText('Instructor', { exact: true })).toBeVisible();
|
||||
await expect(page.getByText('Student', { exact: true })).toBeVisible();
|
||||
|
||||
// Table
|
||||
await expect(page.locator('.q-table')).toBeVisible();
|
||||
});
|
||||
|
||||
test('should filter users by search', async ({ page }) => {
|
||||
const searchInput = page.locator('input[placeholder*="ค้นหาชื่อ"]');
|
||||
await searchInput.fill('admin');
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// Table should still be visible with filtered results
|
||||
await expect(page.locator('.q-table')).toBeVisible();
|
||||
});
|
||||
|
||||
test('should filter users by role', async ({ page }) => {
|
||||
// ใช้ outlined q-select (ตัว filter role ไม่ใช่ pagination)
|
||||
const roleSelect = page.locator('.q-select.q-field--outlined');
|
||||
await roleSelect.click();
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
// Select Instructor
|
||||
await page.locator('.q-item__label').filter({ hasText: 'Instructor' }).click();
|
||||
await page.waitForTimeout(500);
|
||||
// Table should show filtered results
|
||||
await expect(page.locator('.q-table')).toBeVisible();
|
||||
|
||||
await roleSelect.click();
|
||||
await page.waitForTimeout(300);
|
||||
// Select Student
|
||||
await page.locator('.q-item__label').filter({ hasText: 'Student' }).click();
|
||||
await page.waitForTimeout(500);
|
||||
// Table should show filtered results
|
||||
await expect(page.locator('.q-table')).toBeVisible();
|
||||
|
||||
await roleSelect.click();
|
||||
await page.waitForTimeout(300);
|
||||
// Select Admin
|
||||
await page.locator('.q-item__label').filter({ hasText: 'Admin' }).click();
|
||||
await page.waitForTimeout(500);
|
||||
// Table should show filtered results
|
||||
await expect(page.locator('.q-table')).toBeVisible();
|
||||
|
||||
// กลับไปเลือก "บทบาททั้งหมด"
|
||||
await roleSelect.click();
|
||||
await page.waitForTimeout(300);
|
||||
await page.locator('.q-item__label').filter({ hasText: 'บทบาททั้งหมด' }).click();
|
||||
await page.waitForTimeout(500);
|
||||
});
|
||||
|
||||
test('should open action menu', async ({ page }) => {
|
||||
// Click more_vert button on first row
|
||||
const actionBtn = page.locator('.q-table .q-btn').filter({ has: page.locator('.q-icon') }).first();
|
||||
const hasData = await actionBtn.isVisible().catch(() => false);
|
||||
|
||||
if (hasData) {
|
||||
await actionBtn.click();
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
// Menu should show options
|
||||
await expect(page.getByText('ดู', { exact: true })).toBeVisible();
|
||||
await expect(page.getByText('แก้ Role', { exact: true })).toBeVisible();
|
||||
await expect(page.getByText('ลบ', { exact: true })).toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
test('should open view user dialog', async ({ page }) => {
|
||||
const actionBtn = page.locator('.q-table .q-btn').filter({ has: page.locator('.q-icon') }).first();
|
||||
const hasData = await actionBtn.isVisible().catch(() => false);
|
||||
|
||||
if (hasData) {
|
||||
await actionBtn.click();
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
// Click "ดู" option
|
||||
await page.getByText('ดู', { exact: true }).click();
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
// Dialog should show user details
|
||||
await expect(page.getByText('รายละเอียดผู้ใช้')).toBeVisible();
|
||||
|
||||
// Close button
|
||||
await page.getByRole('button', { name: 'ปิด' }).click();
|
||||
await expect(page.locator('.q-dialog')).not.toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
test('open change role dialog', async ({ page }) => {
|
||||
const actionBtn = page.locator('.q-table .q-btn').filter({ has: page.locator('.q-icon') }).first();
|
||||
const hasData = await actionBtn.isVisible().catch(() => false);
|
||||
|
||||
// Table should still be visible with filtered results
|
||||
await expect(page.locator('.q-table')).toBeVisible();
|
||||
if (hasData) {
|
||||
await actionBtn.click();
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
// Click "แก้ Role"
|
||||
await page.getByText('แก้ Role').click();
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
// Change role dialog should appear
|
||||
await expect(page.getByText('เปลี่ยน Role')).toBeVisible();
|
||||
|
||||
// Cancel the dialog
|
||||
await page.getByRole('button', { name: 'Cancel' }).click();
|
||||
await page.waitForTimeout(300);
|
||||
}
|
||||
});
|
||||
|
||||
test('change role ', async ({ page }) => {
|
||||
const actionBtn = page.locator('.q-table .q-btn').filter({ has: page.locator('.q-icon') }).first();
|
||||
const hasData = await actionBtn.isVisible().catch(() => false);
|
||||
const searchInput = page.locator('input[placeholder*="ค้นหาชื่อ"]');
|
||||
await searchInput.fill('lertp');
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// Table should still be visible with filtered results
|
||||
await expect(page.locator('.q-table')).toBeVisible();
|
||||
if (hasData) {
|
||||
// Click "แก้ Role Student"
|
||||
await actionBtn.click();
|
||||
await page.waitForTimeout(300);
|
||||
await page.getByText('แก้ Role').click();
|
||||
await page.waitForTimeout(300);
|
||||
// Change role dialog should appear
|
||||
await expect(page.getByText('เปลี่ยน Role')).toBeVisible();
|
||||
// select role Student
|
||||
await page.waitForTimeout(300);
|
||||
await page.locator('.q-dialog .q-radio__label').filter({ hasText: 'Student' }).click();
|
||||
await page.waitForTimeout(500);
|
||||
// save
|
||||
await page.getByRole('button', { name: 'OK' }).click();
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
// Click "แก้ Role Admin"
|
||||
await actionBtn.click();
|
||||
await page.waitForTimeout(300);
|
||||
await page.getByText('แก้ Role').click();
|
||||
await page.waitForTimeout(300);
|
||||
// Change role dialog should appear
|
||||
await expect(page.getByText('เปลี่ยน Role')).toBeVisible();
|
||||
// select role Admin
|
||||
await page.waitForTimeout(300);
|
||||
await page.locator('.q-dialog .q-radio__label').filter({ hasText: 'Admin' }).click();
|
||||
await page.waitForTimeout(500);
|
||||
// save
|
||||
await page.getByRole('button', { name: 'OK' }).click();
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
||||
// Click "แก้ Role Instructor"
|
||||
await actionBtn.click();
|
||||
await page.waitForTimeout(300);
|
||||
await page.getByText('แก้ Role').click();
|
||||
await page.waitForTimeout(300);
|
||||
// Change role dialog should appear
|
||||
await expect(page.getByText('เปลี่ยน Role')).toBeVisible();
|
||||
// select role Instructor
|
||||
await page.waitForTimeout(300);
|
||||
await page.locator('.q-dialog .q-radio__label').filter({ hasText: 'Instructor' }).click();
|
||||
await page.waitForTimeout(500);
|
||||
// save
|
||||
await page.getByRole('button', { name: 'OK' }).click();
|
||||
await page.waitForTimeout(300);
|
||||
}
|
||||
});
|
||||
|
||||
// test('should open delete confirmation dialog', async ({ page }) => {
|
||||
// const actionBtn = page.locator('.q-table .q-btn').filter({ has: page.locator('.q-icon') }).first();
|
||||
// const hasData = await actionBtn.isVisible().catch(() => false);
|
||||
|
||||
// if (hasData) {
|
||||
// await actionBtn.click();
|
||||
// await page.waitForTimeout(300);
|
||||
|
||||
// // Click "ลบ"
|
||||
// await page.getByText('ลบ').click();
|
||||
// await page.waitForTimeout(300);
|
||||
|
||||
// // Delete confirmation dialog
|
||||
// await expect(page.getByText('ยืนยันการลบ')).toBeVisible();
|
||||
|
||||
// // Cancel the dialog
|
||||
// await page.getByRole('button', { name: 'Cancel' }).click();
|
||||
// await page.waitForTimeout(300);
|
||||
// }
|
||||
// });
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue