this repo has no description
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);