AvanzaCast/packages/broadcast-panel/e2e/dify-plugin-playwright.mjs
Cesar Mendivil 8b458a3ddf feat: add initial LiveKit Meet integration with utility scripts, configs, and core components
- Add Next.js app structure with base configs, linting, and formatting
- Implement LiveKit Meet page, types, and utility functions
- Add Docker, Compose, and deployment scripts for backend and token server
- Provide E2E and smoke test scaffolding with Puppeteer and Playwright helpers
- Include CSS modules and global styles for UI
- Add postMessage and studio integration utilities
- Update package.json with dependencies and scripts for development and testing
2025-11-20 12:50:38 -07:00

123 lines
5.0 KiB
JavaScript

#!/usr/bin/env node
// packages/broadcast-panel/e2e/dify-plugin-playwright.mjs
// Minimal Playwright "plugin" runner inspired by dify-plugin-playwright
// Usage (CLI):
// node dify-plugin-playwright.mjs --ws ws://localhost:3003 --url http://localhost:5176 --out /tmp/dify-shot.png
// Or import and call runPlaywright(options)
import { chromium } from 'playwright';
import fs from 'fs';
import path from 'path';
async function runPlaywright({ wsEndpoint, url, out = '/tmp/dify-playwright-shot.png', steps = [] }){
const result = { success: false, wsEndpoint, url, out, steps: [], error: null, used: null };
let browser;
try{
// Try to connect to remote Playwright server if wsEndpoint provided
if(wsEndpoint){
result.steps.push(`attempt_connect:${wsEndpoint}`);
try{
browser = await chromium.connect({ wsEndpoint, timeout: 30000 });
result.used = 'remote';
result.steps.push({ action: 'connect', ok: true, meta: { wsEndpoint } });
}catch(connectErr){
// Log the error and fallback to launching local browser
const em = String(connectErr && (connectErr.stack || connectErr.message || connectErr));
result.steps.push({ action: 'connect', ok: false, meta: { error: em } });
result.steps.push({ action: 'fallback', ok: true, meta: { reason: 'connect-failed, launching local chromium' } });
try{
browser = await chromium.launch({ headless: true });
result.used = 'local-launch';
result.steps.push({ action: 'launch', ok: true, meta: { launched: true } });
}catch(launchErr){
result.error = 'Failed to connect remote and failed to launch local chromium: ' + String(launchErr && (launchErr.stack || launchErr.message));
return result;
}
}
} else {
// No wsEndpoint provided -> launch local
result.steps.push('no-wsendpoint-launch-local');
browser = await chromium.launch({ headless: true });
result.used = 'local-launch';
result.steps.push({ action: 'launch', ok: true });
}
const context = await browser.newContext();
const page = await context.newPage();
// default flow if no custom steps
if(!steps || steps.length === 0){
steps = [
{ action: 'goto', url },
{ action: 'wait', ms: 1000 },
{ action: 'clickText', text: 'Entrar al Estudio' },
{ action: 'wait', ms: 1000 },
{ action: 'screenshot', path: out }
];
}
for(const s of steps){
const step = { action: s.action || 'unknown', ok: false, meta: null };
try{
if(s.action === 'goto'){
await page.goto(s.url, { waitUntil: 'networkidle', timeout: s.timeout || 30000 });
step.ok = true; step.meta = { url: page.url() };
} else if(s.action === 'wait'){
await page.waitForTimeout(s.ms || 500);
step.ok = true;
} else if(s.action === 'clickText'){
const locator = page.locator(`text=${s.text}`);
const c = await locator.count();
if(c > 0){ await locator.first().click({ timeout: 5000 }); step.ok = true; } else { step.ok = false; step.meta = { found: 0 }; }
} else if(s.action === 'type'){
await page.locator(s.selector).fill(s.text); step.ok = true;
} else if(s.action === 'screenshot'){
const p = s.path || out;
await page.screenshot({ path: p, fullPage: true }); step.ok = true; step.meta = { path: p };
} else if(s.action === 'eval'){
const r = await page.evaluate(s.fn);
step.ok = true; step.meta = { result: r };
} else {
// unknown
step.ok = false; step.meta = { reason: 'unknown action' };
}
}catch(err){
step.ok = false; step.meta = { error: String(err && (err.stack || err.message || err)) };
}
result.steps.push(step);
}
result.success = result.steps.every(st => typeof st === 'object' ? st.ok || st.action==='connect' : true);
await context.close();
try{ await browser.close(); }catch(e){}
return result;
}catch(err){
if(browser){ try{ await browser.close(); }catch(e){} }
result.error = String(err && (err.stack || err.message || err));
return result;
}
}
// CLI runner
if(process.argv[1] && process.argv[1].endsWith('dify-plugin-playwright.mjs')){
// parse args simply
const args = process.argv.slice(2);
const opts = {};
for(let i=0;i<args.length;i++){
if(args[i] === '--ws') opts.wsEndpoint = args[++i];
if(args[i] === '--url') opts.url = args[++i];
if(args[i] === '--out') opts.out = args[++i];
}
if(!opts.url) opts.url = process.env.BROADCAST_URL || 'http://localhost:5176';
if(!opts.wsEndpoint) opts.wsEndpoint = process.env.PW_WS || 'ws://localhost:3003';
(async ()=>{
const res = await runPlaywright({ wsEndpoint: opts.wsEndpoint, url: opts.url, out: opts.out });
console.log(JSON.stringify(res, null, 2));
if(!res.success) process.exit(2);
process.exit(0);
})();
}
export { runPlaywright };