// e2e/simulate_token_query_browserless.js // Simulate E2E by navigating to Broadcast Panel with ?token=... so frontend stores session in sessionStorage, // then open Studio URL with that token and take a screenshot + write results. const fs = require('fs'); const path = require('path'); const puppeteer = require('puppeteer-core'); (async () => { const outDir = path.resolve(__dirname); const results = { startedAt: new Date().toISOString(), console: [], navigations: [] }; let ws = process.env.BROWSERLESS_WS || ''; const btoken = process.env.BROWSERLESS_TOKEN || ''; try { if (ws && btoken) { ws = ws.includes('?') ? `${ws}&token=${encodeURIComponent(btoken)}` : `${ws}?token=${encodeURIComponent(btoken)}`; } } catch(e){} if (!ws) { console.error('BROWSERLESS_WS required'); process.exit(2); } const BROADCAST_URL = process.env.BROADCAST_URL || process.env.VITE_BROADCASTPANEL_URL; const STUDIO_URL = process.env.STUDIO_URL || process.env.VITE_STUDIO_URL; const TOKEN = process.env.TOKEN || process.env.E2E_TOKEN || ''; if (!BROADCAST_URL) { console.error('BROADCAST_URL required'); process.exit(2); } console.log('Connecting to browserless at', ws); const browser = await puppeteer.connect({ browserWSEndpoint: ws, ignoreHTTPSErrors: true, defaultViewport: { width: 1366, height: 768 } }); const page = await browser.newPage(); page.setDefaultNavigationTimeout(30000); page.on('console', msg => { try { results.console.push({ type: msg.type(), text: msg.text() }); } catch(e){} }); page.on('pageerror', err => { results.console.push({ type: 'pageerror', text: String(err && err.stack ? err.stack : err) }); }); try { const urlWithToken = TOKEN ? `${BROADCAST_URL.replace(/\/$/, '')}?token=${encodeURIComponent(TOKEN)}` : BROADCAST_URL; console.log('Navigating to', urlWithToken); await page.goto(urlWithToken, { waitUntil: 'networkidle2' }); await page.waitForTimeout(2500); // snapshot the broadcast page const shot1 = path.join(outDir, 'simulate_broadcast_with_token.png'); await page.screenshot({ path: shot1, fullPage: true }); results.navigations.push({ type: 'broadcast_loaded', url: page.url(), screenshot: shot1 }); // Try to read sessionStorage key const storeKey = process.env.STUDIO_SESSION_KEY || 'avanzacast_studio_session'; const stored = await page.evaluate((k) => { try { return sessionStorage.getItem(k); } catch(e) { return null; } }, storeKey); results.sessionStorage = { key: storeKey, value: stored }; // If STUDIO_URL provided, navigate to it with token if (STUDIO_URL) { const studioWithToken = `${STUDIO_URL.replace(/\/$/, '')}?token=${encodeURIComponent(TOKEN)}`; console.log('Navigating to studio URL', studioWithToken); const newPage = await browser.newPage(); newPage.setDefaultNavigationTimeout(30000); newPage.on('console', msg => { try { results.console.push({ type: msg.type(), text: msg.text() }); } catch(e){} }); newPage.on('pageerror', err => { results.console.push({ type: 'pageerror', text: String(err && err.stack ? err.stack : err) }); }); await newPage.goto(studioWithToken, { waitUntil: 'networkidle2' }); await newPage.waitForTimeout(2500); const shot2 = path.join(outDir, 'simulate_studio_with_token.png'); await newPage.screenshot({ path: shot2, fullPage: true }); results.navigations.push({ type: 'studio_loaded', url: newPage.url(), screenshot: shot2 }); try { await newPage.close(); } catch(e){} } results.endedAt = new Date().toISOString(); const outFile = path.join(outDir, 'simulate_token_query_browserless-result.json'); fs.writeFileSync(outFile, JSON.stringify(results, null, 2)); console.log('Wrote', outFile); try { await browser.disconnect(); } catch(e) { try { await browser.close(); } catch(e){} } process.exit(0); } catch (err) { console.error('Error', err && err.stack ? err.stack : err); results.error = String(err && err.stack ? err.stack : err); results.endedAt = new Date().toISOString(); fs.writeFileSync(path.join(outDir, 'simulate_token_query_browserless-result.json'), JSON.stringify(results, null, 2)); try { await browser.disconnect(); } catch(e) { try { await browser.close(); } catch(e){} } process.exit(1); } })();