import type { Subprocess } from "bun";
import { expect, test } from "bun:test";
import { bunEnv, bunExe, tempDirWithFiles } from "harness";
async function getServerUrl(process: Subprocess) {
// Read the port number from stdout
const decoder = new TextDecoder();
let serverUrl = "";
let text = "";
for await (const chunk of process.stdout) {
const textChunk = decoder.decode(chunk, { stream: true });
text += textChunk;
console.log(textChunk);
if (text.includes("http://")) {
serverUrl = text.trim();
serverUrl = serverUrl.slice(serverUrl.indexOf("http://"));
serverUrl = serverUrl.slice(0, serverUrl.indexOf("\n"));
if (URL.canParse(serverUrl)) {
break;
}
serverUrl = serverUrl.slice(0, serverUrl.indexOf("/n"));
serverUrl = serverUrl.slice(0, serverUrl.lastIndexOf("/"));
serverUrl = serverUrl.trim();
if (URL.canParse(serverUrl)) {
break;
}
}
}
if (!serverUrl) {
throw new Error("Could not find server URL in stdout");
}
return serverUrl;
}
test.concurrent("bun ./index.html", async () => {
const dir = tempDirWithFiles("html-entry-test", {
"index.html": /*html*/ `
HTML Entry Test
Hello from Bun!
`,
"styles.css": /*css*/ `
.container {
max-width: 800px;
margin: 2rem auto;
text-align: center;
font-family: system-ui, sans-serif;
}
button {
padding: 0.5rem 1rem;
font-size: 1.25rem;
border-radius: 0.25rem;
border: 2px solid #000;
background: #fff;
cursor: pointer;
transition: all 0.2s;
}
button:hover {
background: #000;
color: #fff;
}
`,
"app.js": /*js*/ `
const button = document.getElementById('counter');
let count = 0;
button.addEventListener('click', () => {
count++;
button.textContent = \`Click me: \${count}\`;
});
`,
});
// Start the server by running bun with the HTML file
await using process = Bun.spawn({
cmd: [bunExe(), "index.html", "--port=0"],
env: {
...bunEnv,
NODE_ENV: "production",
},
cwd: dir,
stdout: "pipe",
});
const serverUrl = await getServerUrl(process);
try {
// Make a request to the server using the detected URL
const response = await fetch(serverUrl);
expect(response.status).toBe(200);
expect(response.headers.get("content-type")).toContain("text/html");
const html = await response.text();
// Verify the HTML content
expect(html).toContain("HTML Entry Test");
expect(html).toContain('');
// The bundler should have processed the CSS and JS files and injected them
expect(html).toMatch(/
/);
expect(html).toMatch(/
Welcome Home
About