AvanzaCast/e2e/mock_server.js
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

110 lines
3.8 KiB
JavaScript

// e2e/mock_server.js
// Simple Express mock server to emulate token server + broadcast & studio pages for E2E testing
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const app = express();
app.use(bodyParser.json());
const port = process.env.MOCK_PORT ? Number(process.env.MOCK_PORT) : 4001;
const sessions = new Map();
function generateId() { return 's' + Math.random().toString(36).slice(2,9); }
app.post('/api/session', (req, res) => {
const body = req.body || {};
const id = generateId();
const token = 'mocktoken-' + Math.random().toString(36).slice(2,12);
sessions.set(id, { token, room: body.room || 'room', username: body.username || 'user' });
const studioUrl = `http://localhost:${port}/studio/${id}`;
res.json({ id, studioUrl, redirectUrl: studioUrl, ttlSeconds: 300 });
});
app.get('/api/session/:id/token', (req, res) => {
const id = req.params.id;
const s = sessions.get(id);
if (!s) return res.status(404).json({ error: 'not_found' });
res.json({ token: s.token, ttlSeconds: 300, room: s.room, username: s.username, url: `ws://localhost:7880` });
});
// Broadcast page
app.get('/broadcast', (req, res) => {
res.setHeader('Content-Type', 'text/html');
res.send(`<!doctype html>
<html>
<head><meta charset="utf-8"><title>Mock Broadcast</title></head>
<body>
<h1>Broadcast Panel - Mock</h1>
<button id="enter">Entrar al estudio</button>
<script>
document.getElementById('enter').addEventListener('click', async () => {
try {
const r = await fetch('/api/session', { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify({ room: 'mock', username: 'tester' }) });
const j = await r.json();
const win = window.open(j.redirectUrl, '_blank');
// try to send postMessage after a short delay
setTimeout(() => {
try { win.postMessage({ type: 'LIVEKIT_PING' }, '*'); } catch(e){}
}, 500);
} catch (e) { console.error('create session error', e); }
});
window.addEventListener('message', (e) => {
console.log('Broadcast received message', e.data);
});
</script>
</body>
</html>`);
});
// Studio page
app.get('/studio/:id', (req, res) => {
const id = req.params.id;
res.setHeader('Content-Type', 'text/html');
res.send(`<!doctype html>
<html>
<head><meta charset="utf-8"><title>Mock Studio ${id}</title></head>
<body>
<h1>Studio Portal - Mock</h1>
<div id="status">loading...</div>
<script>
async function init() {
const parts = location.pathname.split('/');
const id = parts[parts.length - 1];
// try to parse token from query
const qs = new URLSearchParams(location.search);
let token = qs.get('token');
if (!token) {
try {
const resp = await fetch('/api/session/' + id + '/token');
if (resp.ok) {
const j = await resp.json(); token = j.token;
}
} catch(e) { console.error('token fetch error', e); }
}
document.getElementById('status').innerText = token ? ('token=' + token) : 'no token';
// reply back to opener
try {
if (window.opener) {
window.opener.postMessage({ type: 'LIVEKIT_ACK', status: token ? 'connected' : 'error', token }, '*');
}
} catch(e){}
}
window.addEventListener('message', (e)=>{
if (e.data && e.data.type === 'LIVEKIT_PING') {
// respond ready
try { window.opener && window.opener.postMessage({ type: 'LIVEKIT_READY' }, '*'); } catch(e){}
}
});
init();
</script>
</body>
</html>`);
});
app.get('/', (req, res) => res.redirect('/broadcast'));
app.listen(port, () => console.log('Mock server listening on', port));