import { test, expect } from '@playwright/test'; test.describe('Authentication Flow', () => { let consoleMessages: string[] = []; let consoleErrors: string[] = []; let failedRequests: string[] = []; test.beforeEach(async ({ page }) => { test.setTimeout(120000); // Capture all console messages page.on('console', msg => { const text = `[${msg.type()}] ${msg.text()}`; consoleMessages.push(text); if (msg.type() === 'error' || msg.type() === 'warning') { consoleErrors.push(text); } }); // Capture page errors page.on('pageerror', error => { const text = `[PAGE ERROR] ${error.message}\n${error.stack}`; consoleErrors.push(text); }); // Capture failed network requests page.on('response', response => { if (response.status() >= 400) { const text = `[${response.status()}] ${response.request().method()} ${response.url()}`; failedRequests.push(text); consoleErrors.push(text); } }); }); test.afterEach(async () => { // Print all console output for debugging if (consoleMessages.length > 0) { console.log('\n=== CONSOLE OUTPUT ==='); consoleMessages.forEach(msg => console.log(msg)); } if (failedRequests.length > 0) { console.log('\n=== FAILED HTTP REQUESTS ==='); failedRequests.forEach(req => console.log(req)); } if (consoleErrors.length > 0) { console.log('\n=== CONSOLE ERRORS/WARNINGS ==='); consoleErrors.forEach(err => console.log(err)); } // Reset for next test consoleMessages = []; consoleErrors = []; failedRequests = []; }); test('should navigate from root URL to login and authenticate', async ({ page }) => { console.log('\nšŸ” Starting from root URL: http://localhost:5173/'); // Go to root URL (not /login) await page.goto('http://localhost:5173/', { waitUntil: 'networkidle' }); // Take screenshot of initial page await page.screenshot({ path: 'test-results/auth-flow-01-initial.png', fullPage: true }); // Wait a moment to see what happens await page.waitForTimeout(2000); console.log('šŸ“ø Current URL:', page.url()); console.log('šŸ“„ Page title:', await page.title()); // Check if we're redirected to login const currentUrl = page.url(); if (currentUrl.includes('/login')) { console.log('āœ… Automatically redirected to /login'); } else if (currentUrl.includes('auth0')) { console.log('āœ… Redirected to Auth0 login'); } else { console.log('āŒ NOT redirected to login. Current URL:', currentUrl); // Check what's visible on the page const bodyText = await page.locator('body').textContent(); console.log('šŸ“ Page content:', bodyText?.substring(0, 200)); // Take another screenshot await page.screenshot({ path: 'test-results/auth-flow-02-stuck.png', fullPage: true }); // Look for specific elements const loadingText = await page.locator('text=Loading').count(); if (loadingText > 0) { console.log('āš ļø Found "Loading" text - stuck in loading state'); } const loginButton = await page.locator('button:has-text("Sign in")').count(); if (loginButton > 0) { console.log('āœ… Found login button on page'); } } // Now explicitly navigate to login if not already there if (!currentUrl.includes('/login') && !currentUrl.includes('auth0')) { console.log('šŸ”„ Manually navigating to /login'); await page.goto('http://localhost:5173/login'); await page.waitForLoadState('networkidle'); await page.screenshot({ path: 'test-results/auth-flow-03-login-page.png', fullPage: true }); } // Click Auth0 login button console.log('šŸ”‘ Looking for Auth0 login button'); const auth0Button = page.locator('button:has-text("Sign in with Auth0")'); await expect(auth0Button).toBeVisible({ timeout: 10000 }); await page.screenshot({ path: 'test-results/auth-flow-04-before-click.png', fullPage: true }); await auth0Button.click(); console.log('ā³ Waiting for Auth0 page to load'); await page.waitForTimeout(2000); await page.screenshot({ path: 'test-results/auth-flow-05-auth0-page.png', fullPage: true }); // Fill in Auth0 credentials console.log('šŸ“ Filling in credentials'); await page.locator('input[name="username"]').fill('test@test.com'); await page.locator('input[name="password"]').fill('P@ssw0rd!'); await page.screenshot({ path: 'test-results/auth-flow-06-credentials-filled.png', fullPage: true }); // Submit login (use the primary Continue button, not Google) console.log('āœ‰ļø Submitting login form'); await page.locator('button[type="submit"][data-action-button-primary="true"]').click(); // Wait for redirect back to app console.log('ā³ Waiting for redirect to dashboard'); await page.waitForURL('**/dashboard', { timeout: 30000 }); await page.screenshot({ path: 'test-results/auth-flow-07-dashboard.png', fullPage: true }); // Verify we're on the dashboard console.log('āœ… Checking dashboard loaded'); await expect(page.locator('h1:has-text("Dashboard")')).toBeVisible({ timeout: 10000 }); console.log('šŸŽ‰ Authentication flow completed successfully!'); // Verify user profile loaded const userEmail = await page.locator('text=test@test.com').count(); if (userEmail > 0) { console.log('āœ… User email visible on page'); } // Final screenshot await page.screenshot({ path: 'test-results/auth-flow-08-final.png', fullPage: true }); }); test('should show console errors when accessing root URL', async ({ page }) => { console.log('\nšŸ” Testing root URL for console errors'); // Go to root URL await page.goto('http://localhost:5173/', { waitUntil: 'domcontentloaded' }); // Wait to capture console output await page.waitForTimeout(5000); // Take screenshot await page.screenshot({ path: 'test-results/auth-console-errors.png', fullPage: true }); console.log(`\nšŸ“Š Captured ${consoleMessages.length} console messages`); console.log(`šŸ“Š Captured ${consoleErrors.length} console errors/warnings`); // The afterEach hook will print all console output }); test('should detect "Loading user profile" stuck state', async ({ page, context }) => { console.log('\nšŸ” Testing for stuck "Loading user profile..." state'); // First, login normally to get Auth0 state await page.goto('http://localhost:5173/login'); await page.locator('button:has-text("Sign in with Auth0")').click(); await page.waitForTimeout(2000); await page.locator('input[name="username"]').fill('test@test.com'); await page.locator('input[name="password"]').fill('P@ssw0rd!'); await page.locator('button[type="submit"][data-action-button-primary="true"]').click(); // Wait for successful login await page.waitForURL('**/dashboard', { timeout: 30000 }); console.log('āœ… Successfully logged in'); // Now close and reopen to simulate browser refresh await page.close(); const newPage = await context.newPage(); // Set up console capture on new page newPage.on('console', msg => { const text = `[${msg.type()}] ${msg.text()}`; consoleMessages.push(text); if (msg.type() === 'error' || msg.type() === 'warning') { consoleErrors.push(text); } }); newPage.on('pageerror', error => { const text = `[PAGE ERROR] ${error.message}\n${error.stack}`; consoleErrors.push(text); }); console.log('šŸ”„ Reopening app (simulating browser refresh)'); await newPage.goto('http://localhost:5173/', { waitUntil: 'domcontentloaded' }); // Check if stuck on loading await newPage.waitForTimeout(3000); const loadingVisible = await newPage.locator('text=Loading user profile').isVisible().catch(() => false); if (loadingVisible) { console.log('āš ļø STUCK on "Loading user profile..." screen!'); await newPage.screenshot({ path: 'test-results/auth-stuck-loading.png', fullPage: true }); // Wait longer to see if it resolves await newPage.waitForTimeout(5000); const stillLoading = await newPage.locator('text=Loading user profile').isVisible().catch(() => false); if (stillLoading) { console.log('āŒ Still stuck after 8 seconds total'); } else { console.log('āœ… Eventually loaded successfully'); } } else { console.log('āœ… No loading state detected - app loaded successfully'); const dashboardVisible = await newPage.locator('h1:has-text("Dashboard")').isVisible().catch(() => false); if (dashboardVisible) { console.log('āœ… Dashboard is visible'); } } await newPage.screenshot({ path: 'test-results/auth-after-refresh.png', fullPage: true }); }); });