70 lines
2.6 KiB
JavaScript
70 lines
2.6 KiB
JavaScript
'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);
|
|
});
|