const { chromium } = require('playwright'); const { execSync } = require('child_process'); const JWT_SECRET = execSync("grep -oP 'POS_JWT_SECRET=\\K.*' /etc/systemd/system/nexus-pos.service | head -1").toString().trim(); function tok() { const h = { alg: 'HS256', typ: 'JWT' }; const now = Math.floor(Date.now()/1000); const p = { tenant_id: 32, employee_id: 1, name: 'Audit', role: 'owner', branch_id: 1, max_discount_pct: 100, permissions: ['*'], device_id: 'a', type: 'pos_access', exp: now+900, iat: now }; const b64 = o => Buffer.from(JSON.stringify(o)).toString('base64url'); const crypto = require('crypto'); return b64(h)+'.'+b64(p)+'.'+crypto.createHmac('sha256', JWT_SECRET).update(b64(h)+'.'+b64(p)).digest('base64url'); } (async () => { const browser = await chromium.launch(); const page = await browser.newPage(); const errs = []; page.on('pageerror', e => errs.push(String(e).slice(0,120))); page.on('console', m => { if (m.type()==='error' && !/favicon|404|net::ERR|sourcemap/i.test(m.text())) errs.push(m.text().slice(0,120)); }); await page.addInitScript(t => { localStorage.setItem('pos_token', t); localStorage.setItem('pos_employee', JSON.stringify({id:1,name:'Audit',role:'owner'})); localStorage.setItem('pos_tenant_id','32'); document.cookie='pos_role=owner; path=/pos; SameSite=Lax'; }, tok()); for (const p of ['/pos/fleet','/pos/supplier-catalog','/pos/historical-sales','/pos/diagrams']) { errs.length = 0; const resp = await page.goto('http://localhost:5001'+p, {waitUntil:'load', timeout:20000}).catch(e=>null); await page.waitForTimeout(2000); console.log((errs.length?'✗ ':'✓ ') + p + ' [' + (resp?resp.status():'?') + ']' + (errs.length? ' → '+errs[0]:'')); } await browser.close(); })();