test: bind fixture servers to os-assigned ports

The test:* scripts run in parallel on CI, so a pre-picked free port could
be claimed by another suite before the bind (EADDRINUSE). The cdn server
now starts first on port 0 — 404ing until its dist exists — so its real
port can be baked into assetsBase. Also type the file:// image probe.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
pull/5406/head
Divyansh Singh 2 weeks ago
parent bcb3172c29
commit 2fee2b16fb

@ -31,7 +31,9 @@ describe('relative base opened over file://', () => {
)
expect(fontFamily).toContain('Inter')
const logoLoaded = await t.page.evaluate(
() => document.querySelector('img[alt="logo again"]')!.naturalWidth
() =>
document.querySelector<HTMLImageElement>('img[alt="logo again"]')!
.naturalWidth
)
expect(logoLoaded).toBe(1)
})

@ -1,10 +1,10 @@
import { spawnSync } from 'node:child_process'
import { readFile } from 'node:fs/promises'
import { createServer, type Server } from 'node:http'
import type { AddressInfo } from 'node:net'
import { extname, join, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import getPort from 'get-port'
import { chromium, type BrowserServer } from 'playwright-chromium'
import { ALT_PREFIX, SUB_PREFIX } from './constants'
@ -23,8 +23,9 @@ const types: Record<string, string> = {
'.zip': 'application/zip'
}
// listens on an os-assigned port (the other suites run in parallel on CI,
// so a pre-picked "free" port can be taken before we bind it)
function serveStatic(
port: number,
mounts: [prefix: string, root: string][],
cors: boolean
): Promise<Server> {
@ -48,18 +49,19 @@ function serveStatic(
res.writeHead(404)
res.end('not found')
})
return new Promise((r) => server.listen(port, () => r(server)))
return new Promise((r) => server.listen(0, () => r(server)))
}
const portOf = (server: Server) => (server.address() as AddressInfo).port
let browserServer: BrowserServer
let servers: Server[] = []
export async function setup() {
const [subPort, pagesPort, cdnPort] = await Promise.all([
getPort(),
getPort(),
getPort()
])
// the cdn server starts before its dist exists (requests just 404 until
// the build lands) so the real port can be baked into assetsBase
const cdnServer = await serveStatic([['/', dist('cdn')]], true)
const cdnPort = portOf(cdnServer)
// each flavor builds in its own process: the markdown renderer is a
// process-wide singleton, so sequential in-process builds would leak the
@ -82,15 +84,14 @@ export async function setup() {
servers = [
// one relative-base build mounted at two unrelated prefixes
await serveStatic(
subPort,
[
[SUB_PREFIX, dist('relative')],
[ALT_PREFIX, dist('relative')]
],
false
),
await serveStatic(pagesPort, [['/', dist('cdn')]], false),
await serveStatic(cdnPort, [['/', dist('cdn')]], true)
await serveStatic([['/', dist('cdn')]], false),
cdnServer
]
browserServer = await chromium.launchServer({
@ -101,8 +102,8 @@ export async function setup() {
})
process.env['WS_ENDPOINT'] = browserServer.wsEndpoint()
process.env['SUB_PORT'] = String(subPort)
process.env['PAGES_PORT'] = String(pagesPort)
process.env['SUB_PORT'] = String(portOf(servers[0]!))
process.env['PAGES_PORT'] = String(portOf(servers[1]!))
process.env['VP_CDN_PORT'] = String(cdnPort)
}

Loading…
Cancel
Save