// Script: browserless_e2e.cjs // Conecta a Browserless via WebSocket y navega al broadcast panel para hacer click en "Entrar al Estudio". // Uso: // BROWSERLESS_TOKEN=e2e098863b912f6a178b68e71ec3c58d BROADCAST_URL=http://localhost:5175 node packages/broadcast-panel/scripts/browserless_e2e.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, 'browserless_e2e.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 token = process.env.BROWSERLESS_TOKEN; if (!token) { log('ERROR: No BROWSERLESS_TOKEN provided in env.'); process.exit(1); } const broadcastUrl = process.env.BROADCAST_URL || process.env.VITE_BROADCASTPANEL_URL || 'http://localhost:5175'; const wsEndpoint = process.env.BROWSERLESS_WS || `wss://browserless.bfzqqk.easypanel.host?token=${token}`; log('Connecting to Browserless at', wsEndpoint); const browser = await puppeteer.connect({ browserWSEndpoint: wsEndpoint, defaultViewport: { width: 1280, height: 800 } }); log('Connected to browserless. Opening new page...'); const page = await browser.newPage(); // capture console messages from page into log 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()); // Try several XPaths / selectors matching localized button text 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')]", "//button[contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), '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) { // continue } } if (!handle) { log('ERROR: No "Entrar" button found on page. Dumping top-level buttons for debugging...'); const buttons = 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('BUTTONS_SNAPSHOT:', JSON.stringify(buttons, null, 2)); await browser.disconnect(); process.exit(2); } // Click the control try { await handle.click(); log('Clicked the Entrar control. Waiting for navigation or popup...'); } catch (e) { log('Click failed, trying evaluate click()...', e && e.message); try { await page.evaluate(el => el.click(), handle); log('Clicked via evaluate.'); } catch (e2) { log('Failed to click element:', e2 && e2.message); } } // Wait for possible navigation or popup try { await page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 8000 }); log('Navigation occurred. New URL:', page.url()); } catch (e) { log('No navigation after click (timed out). Checking if a new popup opened...'); } const allPages = await browser.pages(); log('Open pages count:', allPages.length); for (const p of allPages) { log('PAGE:', p.target()._targetId || p.url(), p.url()); } // If a popup or new tab includes /studio or a session id, log it const studioPage = allPages.find(p => /studio|session|y5n0wsr|\/\w{6}/i.test(p.url())); if (studioPage) { log('Detected candidate studio page:', studioPage.url()); // Could attempt to read token from URL param or DOM const url = studioPage.url(); const search = new URL(url).searchParams; const sessionParam = search.get('session') || search.get('token') || null; log('Session param found in URL (if any):', sessionParam); } else { log('No obvious studio page detected by URL pattern. Current page URL:', page.url()); } log('Done. Disconnecting from browserless. Logs saved to', LOG_FILE); await browser.disconnect(); process.exit(0); } catch (err) { log('FATAL ERROR:', err && err.stack ? err.stack : err); process.exit(10); } })();