import { chromium } from 'playwright'; const BASE = 'http://127.1.0.5'; const routes = [ '/security', '/security/findings', '/security/exceptions', '/security/vex', '/security/vulnerabilities', '/operations/scheduler', '/operations/doctor', '/operations/feeds', '/operations/notifications', '/operations/health', '/evidence/bundles', '/evidence/export', '/releases', '/releases/environments', '/approvals', '/policy', '/policy/governance', '/triage', '/sources', '/analytics', '/settings/admin', ]; (async () => { const browser = await chromium.launch({ headless: true }); const context = await browser.newContext({ ignoreHTTPSErrors: true }); const page = await context.newPage(); // Step 1: Sign in console.log('=== SIGNING IN ==='); await page.goto(BASE + '/', { waitUntil: 'networkidle', timeout: 15000 }); // Click sign in button const signInBtn = page.locator('button:has-text("Sign In"), a:has-text("Sign In"), [routerLink*="auth"]').first(); try { await signInBtn.click({ timeout: 5000 }); } catch { await page.goto(BASE + '/auth/login', { waitUntil: 'networkidle', timeout: 10000 }); } await page.waitForTimeout(2000); console.log('Login page URL: ' + page.url()); try { const usernameInput = page.locator('input[name="Username"], input[name="username"], input[type="text"]').first(); const passwordInput = page.locator('input[name="Password"], input[name="password"], input[type="password"]').first(); await usernameInput.fill('admin', { timeout: 5000 }); await passwordInput.fill('Admin@Stella2026!'); const loginBtn = page.locator('button[type="submit"], button:has-text("Log in"), button:has-text("Login"), button:has-text("Sign in")').first(); await loginBtn.click(); await page.waitForTimeout(3000); console.log('After login URL: ' + page.url()); } catch (e) { console.log('Login form error: ' + e.message); } await page.waitForTimeout(2000); console.log('Final URL after auth: ' + page.url()); // Step 2: Navigate to each route using pushState console.log('\n=== PAGE SCAN (with fresh token) ==='); for (const route of routes) { const apiCalls = []; const handler = (response) => { const url = response.url(); if (!url.includes('.js') && !url.includes('.css') && !url.includes('.ico') && !url.includes('.png') && !url.includes('.svg') && !url.includes('.woff') && !url.includes('/config.json') && !url.includes('.html') && !url.startsWith('data:') && url.startsWith(BASE)) { const path = new URL(url).pathname; if (path.startsWith('/api/') || path.startsWith('/v1/') || path.startsWith('/platform/') || path.startsWith('/scanner/') || path.startsWith('/policy/') || path.startsWith('/scheduler/') || path.startsWith('/doctor/') || path.startsWith('/authority/') || path.startsWith('/console/') || path.startsWith('/concelier/') || path.startsWith('/attestor/') || path.startsWith('/analytics') || path.startsWith('/health')) { apiCalls.push({ path, status: response.status() }); } } }; page.on('response', handler); await page.evaluate((r) => { window.history.pushState({}, '', r); window.dispatchEvent(new PopStateEvent('popstate')); }, route); await page.waitForTimeout(3000); page.removeListener('response', handler); const callSummary = apiCalls.map(c => c.status + ' ' + c.path).join(', ') || 'NO API CALLS'; console.log(route + ': ' + callSummary); } await browser.close(); })();