(async ()=>{ const mod = await import('puppeteer') const puppeteer = (mod && mod.default) ? mod.default : mod const chromePath = process.env.CHROME_PATH || '/usr/bin/chromium' const url = process.env.VITE_BROADCASTPANEL_URL || 'https://avanzacast-broadcastpanel.bfzqqk.easypanel.host' console.log('Launching chrome at', chromePath, 'and opening', url) const browser = await puppeteer.launch({ executablePath: chromePath, args: ['--no-sandbox','--disable-setuid-sandbox','--disable-dev-shm-usage','--headless=new'], defaultViewport: { width: 1400, height: 900 } }) const page = await browser.newPage() await page.goto(url, { waitUntil: 'networkidle2', timeout: 30000 }) await page.waitForTimeout(1500) const results = await page.evaluate(() => { function norm(s){ return (s||'').replace(/\s+/g,' ').trim() } const nodes = Array.from(document.querySelectorAll('button, a, [role="button"], [aria-label], [data-testid]')) return nodes.slice(0,300).map(n=>({ tag: n.tagName, text: norm(n.textContent||n.innerText||''), aria: n.getAttribute && (n.getAttribute('aria-label') || n.getAttribute('aria-labelledby')), testid: n.getAttribute && n.getAttribute('data-testid'), classes: (n.className||'').toString().slice(0,200), role: n.getAttribute && n.getAttribute('role') || null, visible: (()=>{ const r = n.getBoundingClientRect(); return !!(r.width && r.height); })() })) }) console.log('Found', results.length, 'interactive nodes') for (let i=0;i{ console.error(e && e.stack?e.stack:e); process.exit(2) })