'use strict'; // Drives the app in a real browser (Edge) and reports console errors, page // errors, and all network responses so we can see exactly what the browser // experiences that curl-style tests don't. const { chromium } = require('playwright'); const BASE = 'http://localhost:3000'; const USER = process.env.ADMIN_USERNAME || 'admin'; const PASS = process.env.ADMIN_PASSWORD || 'BowlerAdmin!2026'; (async () => { const browser = await chromium.launch({ channel: 'msedge', headless: true }); const context = await browser.newContext(); const page = await context.newPage(); const log = []; page.on('console', (m) => log.push(` [console.${m.type()}] ${m.text()}`)); page.on('pageerror', (e) => log.push(` [pageerror] ${e.message}`)); page.on('requestfailed', (r) => log.push(` [requestfailed] ${r.method()} ${r.url()} :: ${r.failure() && r.failure().errorText}`) ); page.on('response', (r) => { const u = r.url(); if (u.includes('/api/')) log.push(` [response] ${r.status()} ${r.request().method()} ${u}`); }); function section(t) { log.push(`\n=== ${t} ===`); } section('1) GET / (fresh, no cookies)'); await page.goto(`${BASE}/`, { waitUntil: 'networkidle' }); log.push(` landed on: ${page.url()}`); section('2) Go to /login.html and sign in'); if (!page.url().includes('login.html')) await page.goto(`${BASE}/login.html`, { waitUntil: 'networkidle' }); await page.fill('#username', USER); await page.fill('#password', PASS); await page.click('#login-form button[type="submit"]'); await page.waitForLoadState('networkidle'); log.push(` after login, url: ${page.url()}`); // Inspect cookies the browser is holding. const cookies = await context.cookies(); log.push(` cookies: ${cookies.map((c) => `${c.name}(sameSite=${c.sameSite},secure=${c.secure},httpOnly=${c.httpOnly})`).join(', ') || 'NONE'}`); section('3) On index — wait for chart fetch'); await page.waitForTimeout(1200); log.push(` url: ${page.url()}`); section('4) Click Admin button'); const adminBtn = page.locator('button[title="Admin"]'); if (await adminBtn.count()) { await adminBtn.click(); await page.waitForLoadState('networkidle'); await page.waitForTimeout(1000); log.push(` url after admin click: ${page.url()}`); // Did users/schemes render? const userRows = await page.locator('table tbody tr').count().catch(() => -1); log.push(` admin table rows visible: ${userRows}`); } else { log.push(' Admin button NOT found (not admin, or page not loaded)'); } console.log(log.join('\n')); await browser.close(); })().catch((e) => { console.error('SCRIPT ERROR:', e); process.exit(1); });