diff --git a/test/regression/issue/24180.test.ts b/test/regression/issue/24180.test.ts index 67dcc571e1..4b87b1b38e 100644 --- a/test/regression/issue/24180.test.ts +++ b/test/regression/issue/24180.test.ts @@ -1,13 +1,16 @@ import { expect, test } from "bun:test"; import fs from "fs"; -import { bunEnv, bunExe, tempDirWithFiles } from "harness"; +import { bunEnv, bunExe, isDebug, tempDirWithFiles } from "harness"; import path from "path"; // https://github.com/oven-sh/bun/issues/24180 // When building fullstack apps with --compile, asset paths in HTML should be // absolute (starting with `/`) not relative (starting with `./`). Relative paths // cause 404 errors when navigating to routes other than `/`. -test("fullstack compile uses absolute asset paths in generated HTML", async () => { +test.skipIf(isDebug)("fullstack compile uses absolute asset paths in generated HTML", { timeout: 60_000 }, async () => { + // Use a fixed port for testing - the compiled app will use this + const port = 49842; + const dir = tempDirWithFiles("24180", { "index.html": ` @@ -33,7 +36,7 @@ console.log("loaded"); import html from "./index.html"; export default { - port: 0, + port: ${port}, static: { "/": html, "/about": html, @@ -66,69 +69,58 @@ export default { expect(buildExitCode).toBe(0); expect(fs.existsSync(outfile)).toBe(true); - // Run the compiled executable - const serverProc = Bun.spawn({ + // Run the compiled executable with await using for automatic cleanup + await using serverProc = Bun.spawn({ cmd: [outfile], cwd: dir, env: bunEnv, - stdout: "pipe", - stderr: "pipe", + stdout: "inherit", + stderr: "inherit", }); - // Wait for the server to start and capture the port - const reader = serverProc.stdout.getReader(); - let output = ""; - let port: number | null = null; - - while (true) { - const { done, value } = await reader.read(); - if (done) break; - output += new TextDecoder().decode(value); - const match = output.match(/localhost:(\d+)/); - if (match) { - port = parseInt(match[1], 10); + // Wait for server to be ready by polling the HTTP endpoint + let res: Response | undefined; + const deadline = Date.now() + 10_000; + while (Date.now() < deadline) { + try { + res = await fetch(`http://localhost:${port}/`); break; + } catch { + await Bun.sleep(100); } } - - expect(port).not.toBeNull(); - - try { - // Fetch the HTML from the root route - const res = await fetch(`http://localhost:${port}/`); - const html = await res.text(); - - // Check that the CSS and JS paths are absolute, not relative - // They should start with `/` not `./` - const cssMatch = html.match(/href="([^"]+\.css)"/); - const jsMatch = html.match(/src="([^"]+\.js)"/); - - expect(cssMatch).not.toBeNull(); - expect(jsMatch).not.toBeNull(); - - const cssPath = cssMatch![1]; - const jsPath = jsMatch![1]; - - // Verify paths are absolute (start with /) - expect(cssPath.startsWith("/")).toBe(true); - expect(jsPath.startsWith("/")).toBe(true); - - // Verify paths don't use relative notation - expect(cssPath.startsWith("./")).toBe(false); - expect(jsPath.startsWith("./")).toBe(false); - - // Also verify the assets are actually accessible - const cssRes = await fetch(`http://localhost:${port}${cssPath}`); - expect(cssRes.status).toBe(200); - const cssContent = await cssRes.text(); - expect(cssContent).toContain("background"); - - const jsRes = await fetch(`http://localhost:${port}${jsPath}`); - expect(jsRes.status).toBe(200); - const jsContent = await jsRes.text(); - expect(jsContent).toContain("loaded"); - } finally { - serverProc.kill(); - await serverProc.exited; + if (!res) { + throw new Error("Server did not start within timeout"); } + const html = await res.text(); + + // Check that the CSS and JS paths are absolute, not relative + // They should start with `/` not `./` + const cssMatch = html.match(/href="([^"]+\.css)"/); + const jsMatch = html.match(/src="([^"]+\.js)"/); + + expect(cssMatch).not.toBeNull(); + expect(jsMatch).not.toBeNull(); + + const cssPath = cssMatch![1]; + const jsPath = jsMatch![1]; + + // Verify paths are absolute (start with /) + expect(cssPath.startsWith("/")).toBe(true); + expect(jsPath.startsWith("/")).toBe(true); + + // Verify paths don't use relative notation + expect(cssPath.startsWith("./")).toBe(false); + expect(jsPath.startsWith("./")).toBe(false); + + // Also verify the assets are actually accessible + const cssRes = await fetch(`http://localhost:${port}${cssPath}`); + expect(cssRes.status).toBe(200); + const cssContent = await cssRes.text(); + expect(cssContent).toContain("background"); + + const jsRes = await fetch(`http://localhost:${port}${jsPath}`); + expect(jsRes.status).toBe(200); + const jsContent = await jsRes.text(); + expect(jsContent).toContain("loaded"); });