mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
177 lines
4.7 KiB
JavaScript
177 lines
4.7 KiB
JavaScript
const puppeteer = require("puppeteer");
|
|
const http = require("http");
|
|
const path = require("path");
|
|
const url = require("url");
|
|
const fs = require("fs");
|
|
const child_process = require("child_process");
|
|
const snippetsDir = path.resolve(__dirname, "../snippets");
|
|
const serverURL = process.env.TEST_SERVER_URL || "http://localhost:8080";
|
|
const USE_EXISTING_PROCESS = process.env.USE_EXISTING_PROCESS || false;
|
|
const DISABLE_HMR = !!process.env.DISABLE_HMR;
|
|
const bunFlags = ["dev", `--origin=${serverURL}`, DISABLE_HMR && "--disable-hmr"].filter(Boolean);
|
|
const bunExec = process.env.BUN_BIN || "bun";
|
|
|
|
var bunProcess;
|
|
var waitSpawn;
|
|
if (!USE_EXISTING_PROCESS) {
|
|
bunProcess = child_process.spawn(bunExec, bunFlags, {
|
|
cwd: snippetsDir,
|
|
stdio: "pipe",
|
|
env: {
|
|
...process.env,
|
|
DISABLE_BUN_ANALYTICS: "1",
|
|
},
|
|
|
|
shell: false,
|
|
});
|
|
console.log("$", bunExec, bunFlags.join(" "));
|
|
bunProcess.stderr.pipe(process.stderr);
|
|
bunProcess.stdout.pipe(process.stdout);
|
|
var rejecter;
|
|
bunProcess.once("error", err => {
|
|
console.error("❌ bun error", err);
|
|
process.exit(1);
|
|
});
|
|
if (!process.env.CI) {
|
|
waitSpawn = new Promise((resolve, reject) => {
|
|
bunProcess.once("spawn", code => {
|
|
console.log("Spawned");
|
|
resolve();
|
|
});
|
|
});
|
|
}
|
|
process.on("beforeExit", () => {
|
|
bunProcess && bunProcess.kill(0);
|
|
});
|
|
}
|
|
const isDebug = bunExec.endsWith("-debug");
|
|
|
|
function writeSnapshot(name, code) {
|
|
let file = path.join(__dirname, "../snapshots", name);
|
|
|
|
if (!DISABLE_HMR) {
|
|
file = file.substring(0, file.length - path.extname(file).length) + ".hmr" + path.extname(file);
|
|
}
|
|
|
|
if (!fs.existsSync(path.dirname(file))) {
|
|
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
}
|
|
|
|
fs.writeFileSync(
|
|
isDebug ? file.substring(0, file.length - path.extname(file).length) + ".debug" + path.extname(file) : file,
|
|
code,
|
|
);
|
|
}
|
|
|
|
const baseOptions = {
|
|
dumpio: !!process.env.CI_DEBUG,
|
|
|
|
args: [
|
|
"--disable-gpu",
|
|
"--disable-dev-shm-usage",
|
|
"--disable-setuid-sandbox",
|
|
"--no-sandbox",
|
|
"--ignore-certificate-errors",
|
|
"--use-fake-ui-for-media-stream",
|
|
"--use-fake-device-for-media-stream",
|
|
"--disable-sync",
|
|
],
|
|
executablePath: process.env.BROWSER_EXECUTABLE,
|
|
headless: true,
|
|
};
|
|
|
|
async function main() {
|
|
const launchOptions = USE_EXISTING_PROCESS ? { ...baseOptions, devtools: !process.env.CI } : baseOptions;
|
|
const browser = await puppeteer.launch(launchOptions);
|
|
const promises = [];
|
|
let allTestsPassed = true;
|
|
|
|
if (waitSpawn) await waitSpawn;
|
|
var canRetry = true;
|
|
|
|
async function runPage(key) {
|
|
var page;
|
|
try {
|
|
page = await browser.newPage();
|
|
if (USE_EXISTING_PROCESS) {
|
|
await page.evaluate(`
|
|
globalThis.BUN_DEBUG_MODE = true;
|
|
`);
|
|
}
|
|
|
|
var shouldClose = true;
|
|
page.on("console", obj => console.log(`[console.${obj.type()}] ${obj.text()}`));
|
|
page.exposeFunction("testFail", error => {
|
|
console.log(`❌ ${error}`);
|
|
allTestsPassed = false;
|
|
});
|
|
let testDone = new Promise(resolve => {
|
|
page.exposeFunction("testDone", resolve);
|
|
});
|
|
try {
|
|
await page.goto(`${serverURL}/`, {
|
|
waitUntil: "domcontentloaded",
|
|
});
|
|
|
|
await page.evaluate(`
|
|
globalThis.runTest("${key}");
|
|
`);
|
|
await testDone;
|
|
} catch (err) {
|
|
if (canRetry) {
|
|
console.log(
|
|
`❌ ${key} failed once (incase it's still booting on universal binary for the first time). Retrying...`,
|
|
);
|
|
canRetry = false;
|
|
return await runPage(key);
|
|
}
|
|
throw err;
|
|
}
|
|
|
|
console.log(`✅ ${key}`);
|
|
} catch (e) {
|
|
if (USE_EXISTING_PROCESS) shouldClose = false;
|
|
allTestsPassed = false;
|
|
console.log(`❌ ${key}: ${(e && e.message) || e}`);
|
|
} finally {
|
|
try {
|
|
const code = await page.evaluate(`
|
|
globalThis.getModuleScriptSrc("${key}");
|
|
`);
|
|
writeSnapshot(key, code);
|
|
} catch (exception) {
|
|
console.warn(`Failed to update snapshot: ${key}`, exception);
|
|
}
|
|
}
|
|
canRetry = false;
|
|
if (shouldClose) await page.close();
|
|
}
|
|
|
|
const tests = require("./snippets.json");
|
|
tests.reverse();
|
|
|
|
for (let test of tests) {
|
|
await runPage(test);
|
|
}
|
|
|
|
if (!USE_EXISTING_PROCESS || (USE_EXISTING_PROCESS && allTestsPassed)) {
|
|
bunProcess && bunProcess.kill(0);
|
|
|
|
if (!allTestsPassed) {
|
|
console.error(`❌ browser test failed`);
|
|
process.exit(1);
|
|
} else {
|
|
console.log(`✅ browser test passed`);
|
|
bunProcess && bunProcess.kill(0);
|
|
process.exit(0);
|
|
}
|
|
await browser.close();
|
|
}
|
|
}
|
|
|
|
main().catch(error =>
|
|
setTimeout(() => {
|
|
throw error;
|
|
}),
|
|
);
|