// test_multiverse.js — Playwright test for multiverse demo (per-package layout) const { chromium } = require('playwright'); (async () => { const browser = await chromium.launch(); const page = await browser.newPage(); const consoleMessages = []; page.on('console', msg => consoleMessages.push(msg.text())); const errors = []; page.on('pageerror', err => errors.push(err.message)); console.log('Navigating to demo5_multiverse.html...'); await page.goto('http://localhost:8080/odoc-interactive-extension/demo5_multiverse.html'); // Wait for cells to render and execute (worker init + universe linking + eval) console.log('Waiting for cells to execute...'); await page.waitForTimeout(15000); // Check multiverse-specific behavior in console const hasWorkerFrom9090 = consoleMessages.some(m => m.includes('9090')); const hasStdlibFallback = consoleMessages.some(m => m.includes('stdlib_dcs not found') && m.includes('findlib discovery')); const hasStdlibDiscovered = consoleMessages.some(m => m.includes('Found stdlib dcs via findlib')); const hasDcsRewrite = consoleMessages.some(m => m.includes('Rewriting dcs_url')); const hasUniverseLinking = consoleMessages.some(m => m.includes('universes')); const hasInitFinished = consoleMessages.some(m => m.includes('init() finished')); const hasSetupFinished = consoleMessages.some(m => m.includes('setup() finished')); const hasInitError = consoleMessages.some(m => m.includes('init_error')); // Check for correct outputs const hasInt7 = consoleMessages.some(m => m.includes('int = 7')); const hasGreeting = consoleMessages.some(m => m.includes('Hello, Multiverse World')); const hasYojsonLoaded = consoleMessages.some(m => m.includes('Custom #require: yojson loaded')); const hasJsonOutput = consoleMessages.some(m => m.includes('"source": "multiverse"') || m.includes('multiverse')); console.log(''); console.log('=== Results ==='); console.log(` Worker loaded from port 9090: ${hasWorkerFrom9090 ? 'YES' : 'NO'}`); console.log(` stdlib_dcs fallback triggered: ${hasStdlibFallback ? 'YES' : 'NO'}`); console.log(` Stdlib discovered via findlib: ${hasStdlibDiscovered ? 'YES' : 'NO'}`); console.log(` dcs_url rewritten to absolute: ${hasDcsRewrite ? 'YES' : 'NO'}`); console.log(` Universe linking used: ${hasUniverseLinking ? 'YES' : 'NO'}`); console.log(` Init completed: ${hasInitFinished ? 'YES' : 'NO'}`); console.log(` Setup completed: ${hasSetupFinished ? 'YES' : 'NO'}`); console.log(` Init error: ${hasInitError ? 'YES (BAD)' : 'NO (good)'}`); console.log(` Output "int = 7": ${hasInt7 ? 'YES' : 'NO'}`); console.log(` Output "Hello, Multiverse": ${hasGreeting ? 'YES' : 'NO'}`); console.log(` Yojson loaded via #require: ${hasYojsonLoaded ? 'YES' : 'NO'}`); console.log(` JSON output with "multiverse": ${hasJsonOutput ? 'YES' : 'NO'}`); let passed = true; if (!hasStdlibFallback) { console.log('\nFAIL: stdlib_dcs fallback was not triggered (multiverse needs it)'); passed = false; } if (!hasStdlibDiscovered) { console.log('\nFAIL: Stdlib was not discovered via findlib universe linking'); passed = false; } if (!hasDcsRewrite) { console.log('\nFAIL: dcs_url was not rewritten to absolute URL'); passed = false; } if (!hasInitFinished) { console.log('\nFAIL: Worker init did not complete'); passed = false; } if (!hasSetupFinished) { console.log('\nFAIL: Worker setup did not complete'); passed = false; } if (hasInitError) { console.log('\nFAIL: Worker reported init_error'); const errMsg = consoleMessages.find(m => m.includes('init_error')); console.log(` ${errMsg}`); passed = false; } if (!hasInt7) { console.log('\nFAIL: Expected output "int = 7" not found'); passed = false; } if (!hasGreeting) { console.log('\nFAIL: Expected output "Hello, Multiverse World" not found'); passed = false; } if (!hasYojsonLoaded) { console.log('\nFAIL: Yojson was not loaded via #require'); passed = false; } if (passed) { console.log('\nPASS: Multiverse demo working correctly'); } else { console.log('\n--- Console messages (last 50) ---'); consoleMessages.slice(-50).forEach(m => console.log(` ${m.substring(0, 200)}`)); } await browser.close(); process.exit(passed ? 0 : 1); })();