/** * Batch widget render verification — mimics a real PDF/DOCX export's * _renderWidgets() call to /api/render_charts with several widgets. * Confirms the shared singleton browser handles concurrent pages correctly. */ const http = require('http'); const BASE = process.env.BASE_URL || 'http://localhost:17861'; function chartWidget(title, type, labels) { return { type: 'chart', title, html: `
` }; } function mermaidWidget(title, def) { return { type: 'mermaid', title, html: `
${def}
` }; } const widgets = [ chartWidget('bar', 'bar', ['A', 'B', 'C']), chartWidget('line', 'line', ['1', '2', '3']), chartWidget('pie', 'pie', ['X', 'Y', 'Z']), mermaidWidget('flow', 'graph TD\n A[Start] --> B{Check}\n B -->|Yes| C[Go]\n B -->|No| D[Stop]'), chartWidget('doughnut', 'doughnut', ['P', 'Q']), ]; const body = JSON.stringify({ widgets, theme: 'light' }); const started = Date.now(); const req = http.request({ hostname: 'localhost', port: 17861, path: '/api/render_charts', method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) }, timeout: 180000, }, (res) => { const chunks = []; res.on('data', (c) => chunks.push(c)); res.on('end', () => { const elapsed = ((Date.now() - started) / 1000).toFixed(2); const data = JSON.parse(Buffer.concat(chunks).toString()); const results = data.results || []; const ok = results.filter((r) => r.success).length; console.log(`HTTP ${res.statusCode} in ${elapsed}s: ${ok}/${results.length} widgets OK`); for (const r of results) { console.log(` [${r.index}] ${r.type}/${r.title}: ${r.success ? 'OK len=' + r.dataUrl.length : 'FAIL ' + (r.error || '')}`); } }); }); req.on('error', (e) => { console.error('ERR', e.message); process.exit(1); }); req.write(body); req.end();