- Rename directory keep-notes -> memento-note with all code references - Prisma: SQLite -> PostgreSQL (both app and MCP server schemas) - Sync MCP schema with main app (add missing fields, relations, indexes) - Delete 17 SQLite migrations (clean slate for PostgreSQL) - Remove SQLite dependencies (@libsql/client, better-sqlite3, etc.) - Fix MCP server: hardcoded Windows DB paths -> DATABASE_URL env var - Fix MCP server: .dockerignore excluded index-sse.js (SSE mode broken) - MCP Dockerfile: node:20 -> node:22 - Docker Compose: add postgres service, remove SQLite volume - Generate favicon.ico, icon-192.png, icon-512.png, apple-icon.png - Update layout.tsx icons and manifest.json for PNG icons - Update all .env files for PostgreSQL - Rewrite README.md with updated sections - Remove mcp-server/node_modules and prisma/client-generated from git tracking Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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()
|
|
})
|
|
})
|