import { test, expect } from '@playwright/test'; import { WebsiteRouteManager } from '../../shared/website/WebsiteRouteManager'; import { WebsiteAuthManager } from '../../shared/website/WebsiteAuthManager'; import { ConsoleErrorCapture } from '../../shared/website/ConsoleErrorCapture'; const API_BASE_URL = process.env.API_URL || 'http://localhost:3101'; test.describe('Website Pages - TypeORM Integration', () => { let routeManager: WebsiteRouteManager; test.beforeEach(() => { routeManager = new WebsiteRouteManager(); }); test('verify Docker and TypeORM are running', async ({ page }) => { const response = await page.goto(`${API_BASE_URL}/health`); expect(response?.ok()).toBe(true); const healthData = await response?.json().catch(() => null); expect(healthData).toBeTruthy(); expect(healthData.database).toBe('connected'); }); test('all routes from RouteConfig are discoverable', async () => { expect(() => routeManager.getWebsiteRouteInventory()).not.toThrow(); }); test('public routes are accessible without authentication', async ({ page }) => { const routes = routeManager.getWebsiteRouteInventory(); const publicRoutes = routes.filter(r => r.access === 'public').slice(0, 5); for (const route of publicRoutes) { const path = routeManager.resolvePathTemplate(route.pathTemplate, route.params); const response = await page.goto(`${API_BASE_URL}${path}`); expect(response?.ok() || response?.status() === 404).toBeTruthy(); } }); test('protected routes redirect unauthenticated users to login', async ({ page }) => { const routes = routeManager.getWebsiteRouteInventory(); const protectedRoutes = routes.filter(r => r.access !== 'public').slice(0, 3); for (const route of protectedRoutes) { const path = routeManager.resolvePathTemplate(route.pathTemplate, route.params); await page.goto(`${API_BASE_URL}${path}`); const currentUrl = new URL(page.url()); expect(currentUrl.pathname).toBe('/auth/login'); expect(currentUrl.searchParams.get('returnTo')).toBe(path); } }); test('admin routes require admin role', async ({ page, browser }) => { const routes = routeManager.getWebsiteRouteInventory(); const adminRoutes = routes.filter(r => r.access === 'admin').slice(0, 2); for (const route of adminRoutes) { const path = routeManager.resolvePathTemplate(route.pathTemplate, route.params); // Regular auth user should be blocked await WebsiteAuthManager.createAuthContext(browser, 'auth'); await page.goto(`${API_BASE_URL}${path}`); expect(page.url().includes('login')).toBeTruthy(); // Admin user should have access await WebsiteAuthManager.createAuthContext(browser, 'admin'); await page.goto(`${API_BASE_URL}${path}`); expect(page.url().includes(path)).toBeTruthy(); } }); test('sponsor routes require sponsor role', async ({ page, browser }) => { const routes = routeManager.getWebsiteRouteInventory(); const sponsorRoutes = routes.filter(r => r.access === 'sponsor').slice(0, 2); for (const route of sponsorRoutes) { const path = routeManager.resolvePathTemplate(route.pathTemplate, route.params); // Regular auth user should be blocked await WebsiteAuthManager.createAuthContext(browser, 'auth'); await page.goto(`${API_BASE_URL}${path}`); expect(page.url().includes('login')).toBeTruthy(); // Sponsor user should have access await WebsiteAuthManager.createAuthContext(browser, 'sponsor'); await page.goto(`${API_BASE_URL}${path}`); expect(page.url().includes(path)).toBeTruthy(); } }); test('auth routes redirect authenticated users away', async ({ page, browser }) => { const routes = routeManager.getWebsiteRouteInventory(); const authRoutes = routes.filter(r => r.access === 'auth').slice(0, 2); for (const route of authRoutes) { const path = routeManager.resolvePathTemplate(route.pathTemplate, route.params); await WebsiteAuthManager.createAuthContext(browser, 'auth'); await page.goto(`${API_BASE_URL}${path}`); // Should redirect to dashboard or stay on the page const currentUrl = page.url(); expect(currentUrl.includes('dashboard') || currentUrl.includes(path)).toBeTruthy(); } }); test('parameterized routes handle edge cases', async ({ page }) => { const edgeCases = routeManager.getParamEdgeCases(); for (const route of edgeCases) { const path = routeManager.resolvePathTemplate(route.pathTemplate, route.params); const response = await page.goto(`${API_BASE_URL}${path}`); if (route.allowNotFound) { expect(response?.status() === 404 || response?.status() === 500).toBeTruthy(); } } }); test('no console or page errors on critical routes', async ({ page }) => { const faultRoutes = routeManager.getFaultInjectionRoutes(); for (const route of faultRoutes) { const capture = new ConsoleErrorCapture(page); const path = routeManager.resolvePathTemplate(route.pathTemplate, route.params); await page.goto(`${API_BASE_URL}${path}`); await page.waitForTimeout(500); const errors = capture.getErrors(); expect(errors.length).toBe(0); } }); test('TypeORM session persistence across routes', async ({ page }) => { const routes = routeManager.getWebsiteRouteInventory(); const testRoutes = routes.filter(r => r.access === 'public').slice(0, 5); for (const route of testRoutes) { const path = routeManager.resolvePathTemplate(route.pathTemplate, route.params); const response = await page.goto(`${API_BASE_URL}${path}`); expect(response?.ok() || response?.status() === 404).toBeTruthy(); } }); test('auth drift scenarios', async ({ page }) => { const driftRoutes = routeManager.getAuthDriftRoutes(); for (const route of driftRoutes) { const path = routeManager.resolvePathTemplate(route.pathTemplate, route.params); // Try accessing protected route without auth await page.goto(`${API_BASE_URL}${path}`); const currentUrl = page.url(); expect(currentUrl.includes('login') || currentUrl.includes('auth')).toBeTruthy(); } }); test('handles invalid routes gracefully', async ({ page }) => { const invalidRoutes = [ '/invalid-route', '/leagues/invalid-id', '/drivers/invalid-id', ]; for (const route of invalidRoutes) { const response = await page.goto(`${API_BASE_URL}${route}`); const status = response?.status(); const url = page.url(); expect([200, 404].includes(status ?? 0) || url.includes('/auth/login')).toBe(true); } }); });