// 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);
}
})();