this repo has no description
at main 166 lines 5.0 kB view raw
1#!/usr/bin/env node 2/** 3 * Playwright integration test runner for preloaded package detection. 4 * 5 * Usage: 6 * node run_integ.js [--headed] 7 * 8 * Starts an HTTP server, runs tests in a browser, reports results. 9 */ 10 11const http = require('http'); 12const fs = require('fs'); 13const path = require('path'); 14const { createRequire } = require('module'); 15 16const PORT = 8766; 17const TIMEOUT = 60000; // 60 seconds max test time 18 19// When run by dune, __filename is in _build/default/js_top_worker/test/integration/. 20// We serve files from that build directory. For node_modules (playwright), we 21// compute the source directory by stripping _build/default/ from the path. 22const buildDir = path.dirname(__filename); 23 24// Compute source directory: replace _build/default/ segment with empty 25// e.g. /path/_build/default/js_top_worker/test/integration -> /path/js_top_worker/test/integration 26function computeSourceDir(dir) { 27 const marker = path.sep + '_build' + path.sep + 'default' + path.sep; 28 const idx = dir.indexOf(marker); 29 if (idx >= 0) { 30 return dir.substring(0, idx) + path.sep + dir.substring(idx + marker.length); 31 } 32 return dir; 33} 34 35const sourceDir = computeSourceDir(buildDir); 36 37// Load playwright from source directory's node_modules 38const sourceRequire = createRequire(path.join(sourceDir, 'package.json')); 39const { chromium } = sourceRequire('playwright'); 40 41// MIME types for serving files 42const mimeTypes = { 43 '.html': 'text/html', 44 '.js': 'application/javascript', 45 '.css': 'text/css', 46 '.json': 'application/json', 47}; 48 49function startServer() { 50 return new Promise((resolve, reject) => { 51 const server = http.createServer((req, res) => { 52 let filePath = req.url === '/' ? '/integ_test.html' : req.url; 53 54 // Strip query string 55 filePath = filePath.split('?')[0]; 56 57 // Try build directory first, then source directory 58 let fullPath = path.join(buildDir, filePath); 59 if (!fs.existsSync(fullPath)) { 60 fullPath = path.join(sourceDir, filePath); 61 } 62 63 if (!fs.existsSync(fullPath)) { 64 console.log(`404: ${filePath}`); 65 res.writeHead(404); 66 res.end('Not found: ' + filePath); 67 return; 68 } 69 70 const ext = path.extname(fullPath); 71 const contentType = mimeTypes[ext] || 'application/octet-stream'; 72 73 fs.readFile(fullPath, (err, content) => { 74 if (err) { 75 res.writeHead(500); 76 res.end('Error reading file'); 77 return; 78 } 79 res.writeHead(200, { 'Content-Type': contentType }); 80 res.end(content); 81 }); 82 }); 83 84 server.listen(PORT, () => { 85 console.log(`Integration test server running at http://localhost:${PORT}/`); 86 resolve(server); 87 }); 88 89 server.on('error', reject); 90 }); 91} 92 93async function runTests(headed = false) { 94 let server; 95 let browser; 96 let exitCode = 0; 97 98 try { 99 // Start the HTTP server 100 server = await startServer(); 101 102 // Launch browser 103 browser = await chromium.launch({ headless: !headed }); 104 const page = await browser.newPage(); 105 106 // Collect console messages 107 const logs = []; 108 page.on('console', msg => { 109 const text = msg.text(); 110 logs.push(text); 111 console.log(`[browser] ${text}`); 112 }); 113 114 // Navigate to test page 115 console.log('Loading integration test page...'); 116 await page.goto(`http://localhost:${PORT}/`); 117 118 // Wait for tests to complete 119 console.log('Waiting for tests to complete...'); 120 await page.waitForFunction( 121 () => window.testResults && window.testResults.done, 122 { timeout: TIMEOUT } 123 ); 124 125 // Get final results 126 const testResults = await page.evaluate(() => ({ 127 total: window.testResults.total, 128 passed: window.testResults.passed, 129 failed: window.testResults.failed, 130 })); 131 132 console.log('\n========================================'); 133 console.log(`Integration Test Results: ${testResults.passed}/${testResults.total} passed`); 134 console.log('========================================\n'); 135 136 // Additional check: verify Crc_mismatch appeared in browser console 137 // (worker console.log is captured by Playwright but not by the page's JS) 138 const hasCrcMismatch = logs.some(line => line.includes('Crc_mismatch')); 139 if (!hasCrcMismatch) { 140 console.log('WARNING: Crc_mismatch not found in console logs'); 141 } 142 143 if (testResults.failed > 0) { 144 console.log('FAILED: Some integration tests did not pass'); 145 exitCode = 1; 146 } else if (!hasCrcMismatch) { 147 console.log('FAILED: Crc_mismatch exception was not raised'); 148 exitCode = 1; 149 } else { 150 console.log('SUCCESS: All integration tests passed'); 151 } 152 153 } catch (err) { 154 console.error('Error running integration tests:', err.message); 155 exitCode = 1; 156 } finally { 157 if (browser) await browser.close(); 158 if (server) server.close(); 159 } 160 161 process.exit(exitCode); 162} 163 164// Parse command line args 165const headed = process.argv.includes('--headed'); 166runTests(headed);