AvanzaCast/packages/broadcast-panel/e2e/session_loader.e2e.js

116 lines
4.6 KiB
JavaScript

#!/usr/bin/env node
// E2E test: session_loader
// - Creates a session via backend-api POST /api/session
// - Opens broadcast panel at /<sessionId>
// - Waits for sessionStorage key and verifies token/url present
const puppeteer = require('puppeteer');
const fetch = require('node-fetch');
(async () => {
const BACKEND = process.env.BACKEND || 'http://localhost:4000';
const BROADCAST = process.env.BROADCAST || 'http://localhost:5175';
const HEADLESS = process.env.HEADLESS !== '0'; // set HEADLESS=0 to see browser
console.log('Using BACKEND=%s BROADCAST=%s HEADLESS=%s', BACKEND, BROADCAST, HEADLESS);
// 1) create session via backend
const room = 'e2e-test-room-' + Math.random().toString(36).slice(2,8);
const username = 'e2e-user';
console.log('Creating session for room=%s username=%s', room, username);
let resp;
try {
resp = await fetch(`${BACKEND.replace(/\/$/, '')}/api/session`, {
method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ room, username })
});
} catch (err) {
console.error('Failed to reach backend to create session:', String(err));
process.exit(2);
}
if (!resp.ok) {
console.error('Failed to create session on backend:', resp.status);
const txt = await resp.text().catch(()=>null);
console.error('Body:', txt);
process.exit(2);
}
const js = await resp.json();
const sessionId = js.id || js.sessionId || js.id;
if (!sessionId) {
console.error('Session creation response missing id:', js);
process.exit(2);
}
console.log('Created session id=', sessionId);
// 2) open broadcast panel at /<id>
const url = `${BROADCAST.replace(/\/$/, '')}/${encodeURIComponent(sessionId)}`;
console.log('Opening', url);
const browser = await puppeteer.launch({ headless: HEADLESS, args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage'] });
const page = await browser.newPage();
page.on('console', msg => console.log('PAGE LOG:', msg.text()));
page.on('pageerror', err => console.error('PAGE ERROR:', err.message));
try {
await page.goto(url, { waitUntil: 'networkidle2', timeout: 30000 });
} catch (e) {
console.error('Failed to open broadcast panel url:', e.message);
// capture screenshot for debugging if possible
try { await page.screenshot({ path: '/tmp/e2e_page_error.png', fullPage: false }); console.log('Saved screenshot to /tmp/e2e_page_error.png'); } catch(e){}
await browser.close();
process.exit(3);
}
// wait for sessionStorage key with retry
const STORE_KEY = process.env.STORE_KEY || 'avanzacast_studio_session';
console.log('Waiting for sessionStorage key=', STORE_KEY);
let found = null;
try {
found = await page.waitForFunction((k) => { try { return !!sessionStorage.getItem(k); } catch (e) { return false } }, { timeout: 15000 }, STORE_KEY).catch(()=>null);
} catch (err) { found = null }
if (!found) {
console.error('sessionStorage key not found within timeout');
try { const html = await page.content(); console.error('Page content snapshot length:', html.length); } catch(e){}
try { await page.screenshot({ path: '/tmp/e2e_no_sessionstorage.png' }); console.log('Saved screenshot to /tmp/e2e_no_sessionstorage.png'); } catch(e){}
await browser.close();
process.exit(4);
}
const stored = await page.evaluate((k) => sessionStorage.getItem(k), STORE_KEY);
console.log('Stored value (truncated):', stored && stored.slice(0, 400));
let parsed = null;
try { parsed = JSON.parse(stored); } catch (e) { console.error('Failed to parse stored JSON', e); }
if (!parsed) {
console.error('No valid session stored');
await browser.close();
process.exit(5);
}
// Accept either token or participantToken
const token = parsed.token || parsed.participantToken || parsed.access_token || parsed.token;
const urlField = parsed.url || parsed.serverUrl || parsed.studioUrl || parsed.redirectUrl;
console.log('Extracted token prefix:', token ? token.slice(0, 24) + '...' : '(none)');
console.log('Extracted url:', urlField || '(none)');
if (!token) {
console.error('Token not found in stored session');
await browser.close();
process.exit(6);
}
// Optionally validate token via backend validate proxy
try {
const v = await fetch(`${BACKEND.replace(/\/$/, '')}/api/session/validate?token=${encodeURIComponent(token)}`);
const vt = await v.text();
console.log('Validate response (first 400 chars):', vt && vt.slice(0,400));
} catch (e) {
console.warn('Validate proxy call failed:', e.message);
}
console.log('E2E test succeeded');
await browser.close();
process.exit(0);
})();