// e2e/streamyard-flow.js // Playwright standalone script to navigate StreamYard and click "Entrar al estudio" // Usage: // npm i -D playwright // npx playwright install --with-deps // node e2e/streamyard-flow.js const fs = require('fs'); const path = require('path'); const { chromium } = require('playwright'); (async () => { const outDir = path.resolve(__dirname); const results = { startedAt: new Date().toISOString(), console: [], navigations: [] }; const browser = await chromium.launch({ headless: true }); const context = await browser.newContext(); const page = await context.newPage(); page.on('console', msg => { try { results.console.push({ type: msg.type(), text: msg.text(), location: msg.location() }); } catch(e){} }); page.on('pageerror', err => { results.console.push({ type: 'pageerror', text: String(err && err.stack ? err.stack : err) }); }); try { const startUrl = 'https://streamyard.com/'; console.log('goto', startUrl); await page.goto(startUrl, { waitUntil: 'networkidle', timeout: 30000 }); await page.waitForTimeout(1500); // find elements with visible text "Entrar al estudio" const loc = page.locator('text=Entrar al estudio'); const count = await loc.count(); console.log('found', count, 'elements'); results.found = count; for (let i = 0; i < count; i++) { const el = loc.nth(i); const beforeHref = await el.getAttribute('href'); const navRec = { index: i, beforeHref, attempts: [] }; let clicked = false; for (let attempt = 1; attempt <= 3; attempt++) { const att = { attempt, timestamp: new Date().toISOString() }; try { // wait both for potential navigation and for popup events const navPromise = page.waitForNavigation({ waitUntil: 'networkidle', timeout: 10000 }).catch(() => null); await el.click({ force: true, timeout: 5000 }); const nav = await navPromise; att.afterUrl = page.url(); att.navigated = !!nav; att.ok = true; navRec.attempts.push(att); clicked = true; // if navigated, go back to start page for next iteration if (nav) { await page.waitForTimeout(800); await page.goto(startUrl, { waitUntil: 'networkidle', timeout: 30000 }); await page.waitForTimeout(800); } break; } catch (err) { att.ok = false; att.error = String(err.message || err); navRec.attempts.push(att); // short delay then retry await page.waitForTimeout(700); } } navRec.success = clicked; results.navigations.push(navRec); } // screenshot and save results const screenshotPath = path.join(outDir, 'streamyard_flow.png'); await page.screenshot({ path: screenshotPath, fullPage: true }); results.screenshot = screenshotPath; results.endedAt = new Date().toISOString(); const jsonOut = path.join(outDir, 'streamyard-flow-result.json'); fs.writeFileSync(jsonOut, JSON.stringify(results, null, 2)); console.log('Wrote results to', jsonOut); await browser.close(); process.exit(0); } catch (err) { console.error('Error during flow', err); results.error = String(err && err.stack ? err.stack : err); results.endedAt = new Date().toISOString(); fs.writeFileSync(path.join(outDir, 'streamyard-flow-result.json'), JSON.stringify(results, null, 2)); try { await browser.close(); } catch(e){} process.exit(1); } })();