diff --git a/src/__tests__/e2e/admin-features.test.ts b/src/__tests__/e2e/admin-features.test.ts new file mode 100644 index 0000000..af229d6 --- /dev/null +++ b/src/__tests__/e2e/admin-features.test.ts @@ -0,0 +1,98 @@ +/** + * Admin Features Test: Match and Player Deletion + * + * This test suite specifically tests the new admin features: + * - Match deletion from admin panel + * - Player deletion from admin panel + * + * @chromium-admin - Tests that require admin authentication + */ + +import { test, expect } from '@playwright/test' +import { prisma } from '@/lib/prisma' + +test.describe('Admin Features: Match and Player Management @chromium-admin', () => { + test.describe('Match Management', () => { + test('should access matches admin page', async ({ page }) => { + await page.goto('/admin/matches') + + // Verify page loads + await expect(page.locator('text=Match Management')).toBeVisible() + }) + + test('should show delete buttons for matches', async ({ page }) => { + await page.goto('/admin/matches') + + // Verify delete buttons exist in the table + const deleteButtons = page.locator('button:has-text("Delete")') + const count = await deleteButtons.count() + // Table might be empty, but the column should exist + await expect(page.locator('text=Actions')).toBeVisible() + }) + + test('should have proper match data structure', async ({ page }) => { + await page.goto('/admin/matches') + + // Verify table headers (using more specific selectors) + await expect(page.locator('th:has-text("Date")')).toBeVisible() + await expect(page.locator('th:has-text("Tournament")')).toBeVisible() + await expect(page.locator('th:has-text("Team 1")')).toBeVisible() + await expect(page.locator('th:has-text("Score")').first()).toBeVisible() + await expect(page.locator('th:has-text("Team 2")')).toBeVisible() + }) + }) + + test.describe('Player Management', () => { + test('should access players admin page', async ({ page }) => { + await page.goto('/admin/players') + + // Verify page loads + await expect(page.locator('text=Player Management')).toBeVisible() + }) + + test('should show edit and delete buttons for players', async ({ page }) => { + await page.goto('/admin/players') + + // Verify action buttons exist + await expect(page.locator('text=Actions')).toBeVisible() + }) + + test('should have proper player data structure', async ({ page }) => { + await page.goto('/admin/players') + + // Verify table headers + await expect(page.locator('text=Player Name')).toBeVisible() + await expect(page.locator('text=Current Elo')).toBeVisible() + await expect(page.locator('text=Games')).toBeVisible() + await expect(page.locator('text=Record')).toBeVisible() + await expect(page.locator('text=Win Rate')).toBeVisible() + }) + }) + + test.describe('API Endpoints', () => { + test('should have matches API endpoint', async ({ page }) => { + // Try to access the matches API + const response = await page.request.get('/api/matches') + expect(response.ok()).toBeTruthy() + }) + + test('should have players admin API endpoint', async ({ page }) => { + // Try to access the players API + const response = await page.request.get('/api/players') + expect(response.ok()).toBeTruthy() + }) + }) + + test.describe('Navigation Updates', () => { + test('should show admin links when authenticated', async ({ page }) => { + // Go to admin page (already authenticated via chromium-admin project) + await page.goto('/admin') + + // Verify admin links ARE visible (using exact text matching) + await expect(page.locator('a:has-text("Admin")').first()).toBeVisible() + await expect(page.locator('a:has-text("Matches")').first()).toBeVisible() + await expect(page.locator('a:has-text("Players")').first()).toBeVisible() + await expect(page.locator('a:has-text("Users")').first()).toBeVisible() + }) + }) +}) diff --git a/src/__tests__/e2e/smoke-test.test.ts b/src/__tests__/e2e/smoke-test.test.ts new file mode 100644 index 0000000..d8717c7 --- /dev/null +++ b/src/__tests__/e2e/smoke-test.test.ts @@ -0,0 +1,130 @@ +/** + * Smoke Test: EuchreCamp Application + * + * This test suite provides comprehensive acceptance/regression testing + * for the core functionality of the EuchreCamp application. + */ + +import { test, expect } from '@playwright/test' + +test.describe('Smoke Test: EuchreCamp Application', () => { + test.describe('Admin Panel Navigation', () => { + test('should navigate to admin dashboard', async ({ page }) => { + await page.goto('/admin') + // Admin dashboard should be visible + await expect(page.locator('text=Admin')).toBeVisible() + }) + + test('should navigate to matches admin page', async ({ page }) => { + await page.goto('/admin/matches') + await expect(page.locator('text=Match Management')).toBeVisible() + }) + + test('should navigate to players admin page', async ({ page }) => { + await page.goto('/admin/players') + await expect(page.locator('text=Player Management')).toBeVisible() + }) + + test('should navigate to users admin page', async ({ page }) => { + await page.goto('/admin/users') + await expect(page.locator('text=User Management')).toBeVisible() + }) + }) + + test.describe('Match Management', () => { + test('should display matches page', async ({ page }) => { + await page.goto('/admin/matches') + // Verify page header is visible + await expect(page.locator('text=Match Management')).toBeVisible() + + // Page should load successfully - verify either table or empty state is present + const hasTable = await page.locator('table').count().then(c => c > 0) + const hasEmptyState = await page.locator('text=/no matches|No matches/').count().then(c => c > 0) + + // At least one should be present + expect(hasTable || hasEmptyState).toBeTruthy() + }) + + test('should have delete button for matches when matches exist', async ({ page }) => { + await page.goto('/admin/matches') + // Check if delete buttons exist in the table + const deleteButtons = page.locator('button:has-text("Delete")') + const count = await deleteButtons.count() + // Table might be empty, but if there are matches, delete buttons should exist + if (count > 0) { + await expect(page.locator('text=Actions')).toBeVisible() + } + }) + }) + + test.describe('Player Management', () => { + test('should display players table', async ({ page }) => { + await page.goto('/admin/players') + await expect(page.locator('table')).toBeVisible() + await expect(page.locator('text=Player Name')).toBeVisible() + await expect(page.locator('text=Current Elo')).toBeVisible() + await expect(page.locator('text=Actions')).toBeVisible() + }) + + test('should have edit and delete buttons for players', async ({ page }) => { + await page.goto('/admin/players') + // At minimum, verify the Actions column exists + await expect(page.locator('text=Actions')).toBeVisible() + }) + + test('should allow editing player name', async ({ page }) => { + await page.goto('/admin/players') + // Click edit on first player + const editButton = page.locator('button:has-text("Edit")').first() + if (await editButton.isVisible()) { + await editButton.click() + + // Verify edit modal appears + await expect(page.locator('text=Edit Player Name')).toBeVisible() + + // Close modal + await page.click('text=Cancel') + await expect(page.locator('text=Edit Player Name')).not.toBeVisible() + } + }) + }) + + test.describe('User Management', () => { + test('should display users page', async ({ page }) => { + await page.goto('/admin/users') + // Page should load with either a table or "no users" message + const hasTable = await page.locator('table').isVisible().catch(() => false) + const hasNoUsers = await page.locator('text=No users found').isVisible().catch(() => false) + + // At least one of these should be true + expect(hasTable || hasNoUsers).toBeTruthy() + + // Verify page header is visible + await expect(page.locator('text=User Management')).toBeVisible() + }) + + test('should have create user link', async ({ page }) => { + await page.goto('/admin/users') + // Check for the main create user link (with green button styling) + const createLink = page.locator('a.bg-green-600:has-text("Create User")') + await expect(createLink).toBeVisible() + }) + }) + + test.describe('Public Pages', () => { + test('should display rankings page', async ({ page }) => { + await page.goto('/rankings') + // Rankings page should be accessible even when authenticated + // Just verify the page loads without error + await expect(page.locator('body')).toBeVisible() + }) + + test('should display player profile page', async ({ page }) => { + // Navigate to a player profile (using player ID 1 which should exist) + await page.goto('/players/1/profile') + // Profile page should be accessible even when authenticated + // Just verify the page loads without error + await expect(page.locator('body')).toBeVisible() + }) + }) +})