153 lines
7.0 KiB
JavaScript
153 lines
7.0 KiB
JavaScript
import fs from 'fs';
|
|
let playwright;
|
|
try { playwright = await import('playwright'); } catch (e) { fs.appendFileSync('/tmp/playwright_debug.log', `Playwright import error: ${e}\n`); process.exit(2); }
|
|
const { chromium } = playwright;
|
|
|
|
const LOG = '/tmp/playwright_debug.log';
|
|
function log(msg){
|
|
const line = `[${new Date().toISOString()}] ${msg}\n`;
|
|
try{ fs.appendFileSync(LOG, line); } catch(e) {}
|
|
}
|
|
|
|
(async ()=>{
|
|
log('Starting playwright_postmessage_test');
|
|
let browser;
|
|
try{
|
|
browser = await chromium.launch({ headless: true, args: ['--no-sandbox','--disable-dev-shm-usage'] });
|
|
log('Chromium launched');
|
|
const context = await browser.newContext();
|
|
const page = await context.newPage();
|
|
page.on('console', m => log('PAGE LOG: ' + m.text()));
|
|
let studioConsoleLogs = [];
|
|
|
|
// Use environment variables if provided, otherwise default to production domains
|
|
const BROADCAST_URL = process.env.BROADCAST_URL || 'https://avanzacast-broadcastpanel.bfzqqk.easypanel.host/post_token_to_studio.html?auto=1';
|
|
const STUDIO_ORIGIN = process.env.STUDIO_ORIGIN || 'https://avanzacast-studio.bfzqqk.easypanel.host';
|
|
|
|
log('Navigating to broadcast URL: ' + BROADCAST_URL);
|
|
await page.goto(BROADCAST_URL, { waitUntil: 'networkidle', timeout: 30000 });
|
|
log('Broadcast page loaded');
|
|
|
|
// Wait briefly for auto-run, otherwise click the open button if present
|
|
try{
|
|
// if the page has a button with id 'run' or 'openSend', try to click it as fallback
|
|
const runBtn = await page.$('#run') || await page.$('#openSend');
|
|
if (runBtn) {
|
|
log('Found run/open button on page; clicking to trigger flow');
|
|
await runBtn.click();
|
|
}
|
|
} catch(e){ log('No run button click fallback: ' + e); }
|
|
|
|
// Wait up to 12s for the redirect to the studio (the broadcast page may open a popup or redirect)
|
|
log('Waiting for a new page whose origin matches ' + STUDIO_ORIGIN + ' (timeout 12s)');
|
|
let studioPage = null;
|
|
const start = Date.now();
|
|
const timeoutMs = 12000;
|
|
while (!studioPage && (Date.now() - start) < timeoutMs){
|
|
const pages = context.pages();
|
|
for (const p of pages){
|
|
try{
|
|
const u = p.url();
|
|
if (u && u.startsWith(STUDIO_ORIGIN)) { studioPage = p; break; }
|
|
}catch(e){}
|
|
}
|
|
if (studioPage) break;
|
|
await new Promise(r=>setTimeout(r, 300));
|
|
}
|
|
|
|
if (!studioPage){
|
|
log('Studio page not opened automatically; attempting to open studio receiver directly at ' + STUDIO_ORIGIN + '/studio_receiver.html');
|
|
// open the studio receiver in the same context
|
|
studioPage = await context.newPage();
|
|
await studioPage.goto(STUDIO_ORIGIN + '/studio_receiver.html', { waitUntil: 'networkidle', timeout: 30000 }).catch(e=>{ log('Goto studio_receiver failed: '+e); });
|
|
}
|
|
|
|
if (!studioPage) {
|
|
log('ERROR: Could not open studio page');
|
|
} else {
|
|
// capture console logs from studio page to detect connected/ACK messages
|
|
studioPage.on('console', m => {
|
|
try { const txt = m.text(); studioConsoleLogs.push(txt); log('STUDIO PAGE LOG: ' + txt); } catch(e) {}
|
|
});
|
|
log('Studio page ready at ' + studioPage.url());
|
|
try{
|
|
// wait for #status element that studio_receiver exposes
|
|
// try a slightly longer wait and fallback to scanning page text
|
|
try {
|
|
await studioPage.waitForSelector('#status', { timeout: 16000 });
|
|
} catch (e) {
|
|
log('waitForSelector #status timed out, will fallback to scanning page content');
|
|
}
|
|
const statusText = await studioPage.evaluate(() => {
|
|
const el = document.getElementById('status');
|
|
if (el) return el.textContent;
|
|
return document.body ? document.body.innerText || document.body.textContent : null;
|
|
}).catch(()=>null);
|
|
log('Studio #status text (initial): ' + statusText);
|
|
} catch(e){ log('No #status element or timeout: ' + (e && e.message)); }
|
|
|
|
// Now wait for the simulator page log (broadcast) to show ACK or for studio to update
|
|
try{
|
|
// Wait up to 10s for ACK to appear in any page logs (simulator) or studio status
|
|
const ackStart = Date.now();
|
|
let ackSeen = false;
|
|
const ackTimeout = 20000; // increase to 20s
|
|
while (!ackSeen && (Date.now() - ackStart) < ackTimeout){
|
|
// check studio console logs first
|
|
try{
|
|
for (const cmsg of studioConsoleLogs){
|
|
if (cmsg && (cmsg.toLowerCase().includes('conectado') || cmsg.toLowerCase().includes('connected') || cmsg.toLowerCase().includes('ack'))) {
|
|
ackSeen = true; log('ACK/connected found in studio console logs: ' + cmsg); break;
|
|
}
|
|
}
|
|
}catch(e){}
|
|
|
|
if (ackSeen) break;
|
|
|
|
// check simulator page (first page) for log element
|
|
try{
|
|
const simulatorPages = context.pages();
|
|
for (const sp of simulatorPages){
|
|
try{
|
|
const content = await sp.evaluate(()=>{
|
|
const el = document.getElementById('log');
|
|
if (el && el.textContent) return el.textContent;
|
|
return document.body ? (document.body.innerText || document.body.textContent) : null;
|
|
});
|
|
if (content && (content.includes('ACK') || /connected/i.test(content) || /conectado/i.test(content))) { ackSeen = true; log('ACK/connected found in simulator page content'); break; }
|
|
}catch(e){}
|
|
}
|
|
}catch(e){ }
|
|
|
|
// also check studio status
|
|
try{
|
|
const s = await studioPage.evaluate(()=>{
|
|
const st = document.getElementById('status');
|
|
if (st && st.textContent) return st.textContent;
|
|
return document.body ? (document.body.innerText || document.body.textContent) : null;
|
|
});
|
|
if (s && (s.toLowerCase().includes('ack') || s.toLowerCase().includes('connected') || s.toLowerCase().includes('conectado'))) { ackSeen = true; log('ACK/connected found in studio content: '+s); }
|
|
}catch(e){}
|
|
|
|
if (!ackSeen) await new Promise(r=>setTimeout(r, 300));
|
|
}
|
|
|
|
if (!ackSeen) log('Timeout waiting for ACK ('+ (ackTimeout/1000) +'s)');
|
|
} catch(e){ log('Error while waiting for ACK: '+e); }
|
|
|
|
// take screenshots
|
|
const simShot = '/tmp/sim_postmessage_simulator.png';
|
|
const studioShot = '/tmp/sim_postmessage_studio.png';
|
|
try{ await page.screenshot({ path: simShot, fullPage: true }); log('Saved simulator screenshot: ' + simShot); } catch(e){ log('Failed saving simulator screenshot: ' + e); }
|
|
try{ await studioPage.screenshot({ path: studioShot, fullPage: true }); log('Saved studio screenshot: ' + studioShot); } catch(e){ log('Failed saving studio screenshot: ' + e); }
|
|
}
|
|
|
|
} catch (err) {
|
|
log('Unhandled error: ' + (err && err.stack ? err.stack : String(err)));
|
|
process.exitCode = 2;
|
|
} finally {
|
|
try { if (browser) await browser.close(); log('Browser closed'); } catch(e) { log('Error closing browser: ' + e); }
|
|
}
|
|
log('Test finished');
|
|
})();
|