// Simple E2E that uses backend-api to create a session, then opens a data: HTML page // with a button "Entrar al Estudio" that opens the studioUrl. It clicks the button and // verifies a new page/tab opened with that URL. const fetch = require('node-fetch'); const puppeteer = require('puppeteer-core'); const fs = require('fs'); const path = require('path'); const LOG_DIR = path.resolve(process.cwd(), 'packages', 'broadcast-panel', 'tmp'); if (!fs.existsSync(LOG_DIR)) fs.mkdirSync(LOG_DIR, { recursive: true }); const LOG_FILE = path.join(LOG_DIR, 'e2e_mock_ui.log'); function log(...args) { const s = `[${new Date().toISOString()}] ${args.join(' ')}\n`; fs.appendFileSync(LOG_FILE, s); console.log(...args); } (async () => { try { const backend = process.env.BACKEND_URL || 'http://127.0.0.1:4000'; log('Using backend:', backend); // create session const createResp = await fetch(`${backend}/api/session`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ room: 'mock-room', username: 'e2e-mock' }) }); if (!createResp.ok) { const t = await createResp.text(); throw new Error('Create session failed: ' + createResp.status + ' ' + t); } const createJson = await createResp.json(); log('Create response:', JSON.stringify(createJson)); const studioUrl = createJson.studioUrl || createJson.redirectUrl; if (!studioUrl) throw new Error('studioUrl not found in create response'); // Prepare mock HTML with override hook placeholder (we will set override from puppeteer) const html = `Mock Broadcast

Mock Broadcast Panel

`; // connect to browser const browserUrl = process.env.PUPPETEER_BROWSER_URL; // e.g. http://127.0.0.1:9222 const browserWSEndpoint = process.env.BROWSERLESS_WSE || (process.env.BROWSERLESS_TOKEN ? `wss://browserless.bfzqqk.easypanel.host?token=${process.env.BROWSERLESS_TOKEN}` : undefined); let browser; if (browserUrl) { log('Connecting to browser via browserURL:', browserUrl); browser = await puppeteer.connect({ browserURL: browserUrl, defaultViewport: { width: 1280, height: 800 } }); } else if (browserWSEndpoint) { log('Connecting to browserless via WSEndpoint:', browserWSEndpoint); browser = await puppeteer.connect({ browserWSEndpoint, defaultViewport: { width: 1280, height: 800 } }); } else { // fallback: try to launch local chrome (may fail in CI) log('No remote browser configured, attempting local launch'); browser = await puppeteer.launch({ headless: false }); } const page = await browser.newPage(); page.on('console', msg => log('PAGE_CONSOLE', msg.type(), msg.text())); page.on('pageerror', err => log('PAGE_ERROR', err && err.stack ? err.stack : err)); // Ensure override is present before any script runs on the page await page.evaluateOnNewDocument(() => { (window as any).__TEST_OPEN = (u: string) => { (window as any).__LAST_OPENED = u; }; }); // set page content (more reliable than data URL for popup handling) log('Setting page content (html)'); await page.setContent(html, { waitUntil: 'networkidle0' }); log('Mock page loaded.'); const btn = await page.waitForSelector('#enter', { timeout: 5000 }); await btn.click(); log('Clicked enter button. Waiting for __LAST_OPENED...'); // give a small delay for the page script to call __TEST_OPEN await page.waitForTimeout(500); const openedUrl = await page.evaluate(() => (window as any).__LAST_OPENED || ''); log('Captured openedUrl from page context:', openedUrl); if (!openedUrl) { log('WARNING: No opened URL captured from page context. Trying to detect popup...'); const pages = await browser.pages(); log('Open pages count after click:', pages.length); if (pages.length > 1) { const popup = pages[pages.length - 1]; const popupUrl = popup.url(); log('Popup URL:', popupUrl); } } else { if (openedUrl.indexOf(studioUrl) === -1 && openedUrl.indexOf('/' + createJson.id) === -1) { log('WARNING: opened URL does not match expected studioUrl', studioUrl); } else { log('SUCCESS: openedUrl matches expected studioUrl/session'); } } // cleanup try { await browser.disconnect(); } catch(e) { try { await browser.close(); } catch(e2) {} } process.exit(0); } catch (err) { log('FATAL', err && err.stack ? err.stack : err); process.exit(1); } })();