- Unified localStorage key to 'theme-preference' across all components
- Fixed header.tsx using wrong localStorage key ('theme' instead of 'theme-preference')
- Added localStorage hybrid persistence for instant theme changes
- Removed router.refresh() which was causing stale data revert
- Replaced Blue theme with Sepia
- Consolidated auth() calls to prevent race conditions
- Updated UserSettingsData types to include all themes
148 lines
5.5 KiB
TypeScript
148 lines
5.5 KiB
TypeScript
import { test, expect } from '@playwright/test'
|
|
|
|
test.describe('Admin Dashboard', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
// Navigate to admin dashboard
|
|
await page.goto('/admin')
|
|
})
|
|
|
|
test('should redirect to home if not authenticated', async ({ page, context }) => {
|
|
// Clear authentication
|
|
await context.clearCookies()
|
|
await page.goto('/admin')
|
|
await expect(page).toHaveURL('/')
|
|
})
|
|
|
|
test('should show sidebar navigation with all sections', async ({ page }) => {
|
|
// Check sidebar exists
|
|
const sidebar = page.locator('aside')
|
|
await expect(sidebar).toBeVisible()
|
|
|
|
// Check all navigation items exist
|
|
await expect(page.getByRole('link', { name: /dashboard/i })).toBeVisible()
|
|
await expect(page.getByRole('link', { name: /users/i })).toBeVisible()
|
|
await expect(page.getByRole('link', { name: /ai management/i })).toBeVisible()
|
|
await expect(page.getByRole('link', { name: /settings/i })).toBeVisible()
|
|
})
|
|
|
|
test('should show main content area with metrics', async ({ page }) => {
|
|
// Check main content area exists
|
|
const main = page.locator('main')
|
|
await expect(main).toBeVisible()
|
|
|
|
// Check metrics are displayed
|
|
await expect(page.getByText(/total users/i)).toBeVisible()
|
|
await expect(page.getByText(/active sessions/i)).toBeVisible()
|
|
await expect(page.getByText(/total notes/i)).toBeVisible()
|
|
await expect(page.getByText(/ai requests/i)).toBeVisible()
|
|
})
|
|
|
|
test('should highlight active section in sidebar', async ({ page }) => {
|
|
// Dashboard should be active on /admin
|
|
const dashboardLink = page.getByRole('link', { name: /dashboard/i })
|
|
await expect(dashboardLink).toHaveClass(/bg-gray-100|bg-zinc-800/)
|
|
})
|
|
|
|
test('should navigate between sections', async ({ page }) => {
|
|
// Navigate to Users
|
|
await page.click('a[href="/admin/users"]')
|
|
await expect(page).toHaveURL(/\/admin\/users/)
|
|
await expect(page.getByRole('heading', { name: /users/i })).toBeVisible()
|
|
|
|
// Navigate to AI Management
|
|
await page.click('a[href="/admin/ai"]')
|
|
await expect(page).toHaveURL(/\/admin\/ai/)
|
|
await expect(page.getByRole('heading', { name: /ai management/i })).toBeVisible()
|
|
|
|
// Navigate to Settings
|
|
await page.click('a[href="/admin/settings"]')
|
|
await expect(page).toHaveURL(/\/admin\/settings/)
|
|
await expect(page.getByRole('heading', { name: /settings/i }).first()).toBeVisible()
|
|
|
|
// Navigate back to Dashboard
|
|
await page.click('a[href="/admin"]')
|
|
await expect(page).toHaveURL(/\/admin\/?$/)
|
|
await expect(page.getByRole('heading', { name: /dashboard/i })).toBeVisible()
|
|
})
|
|
|
|
test('should be responsive on desktop (1024px+)', async ({ page }) => {
|
|
await page.setViewportSize({ width: 1024, height: 768 })
|
|
|
|
// Check sidebar is visible on desktop
|
|
const sidebar = page.locator('aside')
|
|
await expect(sidebar).toBeVisible()
|
|
await expect(sidebar).toHaveCSS('width', '256px')
|
|
|
|
// Check content area takes remaining space
|
|
const main = page.locator('main')
|
|
await expect(main).toBeVisible()
|
|
})
|
|
|
|
test('should be responsive on tablet (640px-1023px)', async ({ page }) => {
|
|
await page.setViewportSize({ width: 768, height: 1024 })
|
|
|
|
// Check layout still works on tablet
|
|
const sidebar = page.locator('aside')
|
|
await expect(sidebar).toBeVisible()
|
|
|
|
const main = page.locator('main')
|
|
await expect(main).toBeVisible()
|
|
})
|
|
|
|
test('should show metrics with trend indicators', async ({ page }) => {
|
|
// Check for trend indicators in metrics
|
|
const trends = page.locator('.text-green-600, .text-red-600, .dark\\:text-green-400, .dark\\:text-red-400')
|
|
await expect(trends).toHaveCount(3) // 3 metrics have trend indicators
|
|
})
|
|
|
|
test('should show users page correctly', async ({ page }) => {
|
|
await page.goto('/admin/users')
|
|
|
|
await expect(page.getByRole('heading', { name: /users/i })).toBeVisible()
|
|
await expect(page.getByText(/manage application users and permissions/i)).toBeVisible()
|
|
})
|
|
|
|
test('should show AI management page correctly', async ({ page }) => {
|
|
await page.goto('/admin/ai')
|
|
|
|
await expect(page.getByRole('heading', { name: /ai management/i })).toBeVisible()
|
|
await expect(page.getByText(/monitor and configure ai features/i)).toBeVisible()
|
|
await expect(page.getByText(/total requests/i)).toBeVisible()
|
|
await expect(page.getByText(/active ai features/i)).toBeVisible()
|
|
})
|
|
|
|
test('should show settings page correctly', async ({ page }) => {
|
|
await page.goto('/admin/settings')
|
|
|
|
await expect(page.getByRole('heading', { name: /settings/i }).first()).toBeVisible()
|
|
await expect(page.getByText(/configure application-wide settings/i)).toBeVisible()
|
|
})
|
|
})
|
|
|
|
test.describe('Admin Dashboard Accessibility', () => {
|
|
test('should be keyboard navigable', async ({ page }) => {
|
|
await page.goto('/admin')
|
|
|
|
// Check tab order
|
|
await page.keyboard.press('Tab')
|
|
await expect(page.getByRole('link', { name: /dashboard/i })).toBeFocused()
|
|
|
|
await page.keyboard.press('Tab')
|
|
await expect(page.getByRole('link', { name: /users/i })).toBeFocused()
|
|
|
|
await page.keyboard.press('Tab')
|
|
await expect(page.getByRole('link', { name: /ai management/i })).toBeFocused()
|
|
|
|
await page.keyboard.press('Tab')
|
|
await expect(page.getByRole('link', { name: /settings/i })).toBeFocused()
|
|
})
|
|
|
|
test('should have proper heading hierarchy', async ({ page }) => {
|
|
await page.goto('/admin')
|
|
|
|
// Check main heading is h1
|
|
const h1 = page.getByRole('heading', { level: 1, name: /dashboard/i })
|
|
await expect(h1).toBeVisible()
|
|
})
|
|
})
|