const http = require('http') const path = require('path') const url = require('url') const fs = require('fs') const js = fs.readFileSync(path.join(__dirname, '..', '..', 'npm', 'esbuild-wasm', 'lib', 'browser.js')) const jsMin = fs.readFileSync(path.join(__dirname, '..', '..', 'npm', 'esbuild-wasm', 'lib', 'browser.min.js')) const esm = fs.readFileSync(path.join(__dirname, '..', '..', 'npm', 'esbuild-wasm', 'esm', 'browser.js')) const esmMin = fs.readFileSync(path.join(__dirname, '..', '..', 'npm', 'esbuild-wasm', 'esm', 'browser.min.js')) const wasm = fs.readFileSync(path.join(__dirname, '..', '..', 'npm', 'esbuild-wasm', 'esbuild.wasm')) const html = fs.readFileSync(path.join(__dirname, '..', '..', 'scripts', 'browser', 'index.html')) const server = http.createServer((req, res) => { console.log(`[http] ${req.method} ${req.url}`) try { if (req.method === 'GET' && req.url) { const parsed = url.parse(req.url) if (parsed.pathname === '/npm/esbuild-wasm/lib/browser.js') { res.writeHead(200, { 'Content-Type': 'text/javascript' }) res.end(js) return } if (parsed.pathname === '/npm/esbuild-wasm/lib/browser.min.js') { res.writeHead(200, { 'Content-Type': 'text/javascript' }) res.end(jsMin) return } if (parsed.pathname === '/npm/esbuild-wasm/esm/browser.js') { res.writeHead(200, { 'Content-Type': 'text/javascript' }) res.end(esm) return } if (parsed.pathname === '/npm/esbuild-wasm/esm/browser.min.js') { res.writeHead(200, { 'Content-Type': 'text/javascript' }) res.end(esmMin) return } if (parsed.pathname === '/npm/esbuild-wasm/esbuild.wasm') { res.writeHead(200, { 'Content-Type': 'application/wasm' }) res.end(wasm) return } if (parsed.pathname === '/scripts/browser/index.html') { res.writeHead(200, { 'Content-Type': 'text/html' }) res.end(html) return } if (parsed.pathname === '/scripts/browser/esbuild.wasm.bagel') { res.writeHead(200, { 'Content-Type': 'application/octet-stream' }) res.end(wasm) return } } res.writeHead(404) res.end('404 Not Found') } catch (err) { res.writeHead(500) res.end('500 Internal Server Error') console.error(err) } }) server.listen() const { address, port } = server.address() const serverURL = url.format({ protocol: 'http', hostname: address, port }) console.log(`[http] listening on ${serverURL}`) async function main() { let allTestsPassed = true try { const browser = await require('puppeteer').launch({ // This is here because since December 2024, GitHub changed something about // their CI that causes this error: // // [FATAL:zygote_host_impl_linux.cc(128)] No usable sandbox! If you are running // on Ubuntu 23.10+ or another Linux distro that has disabled unprivileged user // namespaces with AppArmor, see https://chromium.googlesource.com/chromium/src/+/main/docs/security/apparmor-userns-restrictions.md. // Otherwise see https://chromium.googlesource.com/chromium/src/+/main/docs/linux/suid_sandbox_development.md // for more information on developing with the (older) SUID sandbox. If you want // to live dangerously and need an immediate workaround, you can try using // --no-sandbox. args: ['--no-sandbox'], }) const page = await browser.newPage() page.on('console', obj => { console.log(`[console.${obj.type()}] ${obj.text()}`) }) page.exposeFunction('testBegin', args => { const config = Object.entries(JSON.parse(args)).map(([k, v]) => `${k}=${v}`).join(', ') console.log(`💬 config: ${config}`) }) page.exposeFunction('testEnd', args => { if (args === null) console.log(`👍 success`) else { const { test, error } = JSON.parse(args) console.log(`❌ error${test ? ` [${test}]` : ``}: ${error}`) allTestsPassed = false } }) const testDone = new Promise(resolve => { page.exposeFunction('testDone', resolve) }) await page.goto(`${serverURL}/scripts/browser/index.html`, { waitUntil: 'domcontentloaded' }) await testDone await page.close() await browser.close() } catch (e) { allTestsPassed = false console.log(`❌ error: ${e && e.stack || e && e.message || e}`) } server.close() if (!allTestsPassed) { console.error(`❌ browser test failed`) process.exit(1) } else { console.log(`✅ browser test passed`) } } main().catch(error => setTimeout(() => { throw error }))