// Local E2E script that connects to a local Chrome remote debugging endpoint (http://127.0.0.1:9222) // Usage: // PUPPETEER_BROWSER_URL=http://127.0.0.1:9222 BROADCAST_URL=http://localhost:5175 node packages/broadcast-panel/scripts/browser_e2e_local.cjs const fs = require('fs'); const path = require('path'); const puppeteer = require('puppeteer-core'); const LOG_DIR = path.resolve(process.cwd(), 'packages', 'broadcast-panel', 'tmp'); const LOG_FILE = path.join(LOG_DIR, 'browser_e2e_local.log'); if (!fs.existsSync(LOG_DIR)) fs.mkdirSync(LOG_DIR, { recursive: true }); function log(...args) { const s = `[${new Date().toISOString()}] ${args.join(' ')}\n`; fs.appendFileSync(LOG_FILE, s); console.log(...args); } (async () => { try { const browserUrl = process.env.PUPPETEER_BROWSER_URL || process.env.BROWSERLESS_BROWSER_URL || 'http://127.0.0.1:9222'; const broadcastUrl = process.env.BROADCAST_URL || 'http://localhost:5175'; log('Connecting to Chrome at', browserUrl); const browser = await puppeteer.connect({ browserURL: browserUrl, defaultViewport: { width: 1280, height: 800 } }); log('Connected to Chrome. Opening new page...'); 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)); log('Navigating to', broadcastUrl); await page.goto(broadcastUrl, { waitUntil: 'networkidle2', timeout: 60000 }); log('Page loaded:', page.url()); const xpaths = [ "//button[contains(normalize-space(.), 'Entrar al Estudio')]", "//button[contains(normalize-space(.), 'Entrar al estudio')]", "//button[contains(normalize-space(.), 'Entrar al Studio')]", "//button[contains(normalize-space(.), 'Entrar')]", "//a[contains(normalize-space(.), 'Entrar al Estudio')]", "//a[contains(normalize-space(.), 'Entrar')]", ]; let handle = null; for (const xp of xpaths) { try { log('Trying XPath:', xp); handle = await page.waitForXPath(xp, { timeout: 3000 }); if (handle) { log('Found element for XPath:', xp); break; } } catch (e) { } } if (!handle) { log('ERROR: No "Entrar" button found. Dumping candidates...'); const candidates = await page.$$eval('button, a', els => els.slice(0,50).map(e => ({ text: e.innerText.trim().slice(0,80), html: e.outerHTML.slice(0,200) }))); log('CANDIDATES:', JSON.stringify(candidates, null, 2)); await browser.disconnect(); process.exit(2); } try { await handle.click(); log('Clicked Entrar'); } catch (e) { try { await page.evaluate(el => el.click(), handle); log('Clicked via evaluate'); } catch (e2) { log('Click failed', e2 && e2.message); } } try { await page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 8000 }); log('Navigation:', page.url()); } catch (e) { log('No navigation, checking popups...'); } const pages = await browser.pages(); log('Open pages count:', pages.length); for (const p of pages) log('PAGE:', p.target()._targetId || p.url(), p.url()); const studioPage = pages.find(p => /studio|session|\/\w{6}/i.test(p.url())); if (studioPage) { log('Detected studio candidate:', studioPage.url()); const u = new URL(studioPage.url()); const sessionParam = u.searchParams.get('session') || u.searchParams.get('token'); log('Session param (if any):', sessionParam); } else { log('No studio page detected. Current page URL:', page.url()); } await browser.disconnect(); log('Done. Logs:', LOG_FILE); process.exit(0); } catch (err) { log('FATAL', err && err.stack ? err.stack : err); process.exit(10); } })();