Files
dify/e2e/support/web-server.ts
2026-03-29 13:40:24 +00:00

84 lines
2.0 KiB
TypeScript

import type { ManagedProcess } from './process'
import { isPortReachable, startLoggedProcess, stopManagedProcess, waitForUrl } from './process'
type WebServerStartOptions = {
baseURL: string
command: string
args?: string[]
cwd: string
logFilePath: string
reuseExistingServer: boolean
timeoutMs: number
}
let activeProcess: ManagedProcess | undefined
const getUrlHostAndPort = (url: string) => {
const parsedUrl = new URL(url)
const isHttps = parsedUrl.protocol === 'https:'
return {
host: parsedUrl.hostname,
port: parsedUrl.port ? Number(parsedUrl.port) : isHttps ? 443 : 80,
}
}
export const startWebServer = async ({
baseURL,
command,
args = [],
cwd,
logFilePath,
reuseExistingServer,
timeoutMs,
}: WebServerStartOptions) => {
const { host, port } = getUrlHostAndPort(baseURL)
if (reuseExistingServer && (await isPortReachable(host, port))) return
activeProcess = await startLoggedProcess({
command,
args,
cwd,
label: 'web server',
logFilePath,
})
let startupError: Error | undefined
activeProcess.childProcess.once('error', (error) => {
startupError = error
})
activeProcess.childProcess.once('exit', (code, signal) => {
if (startupError) return
startupError = new Error(
`Web server exited before readiness (code: ${code ?? 'unknown'}, signal: ${signal ?? 'none'}).`,
)
})
const deadline = Date.now() + timeoutMs
while (Date.now() < deadline) {
if (startupError) {
await stopManagedProcess(activeProcess)
activeProcess = undefined
throw startupError
}
try {
await waitForUrl(baseURL, 1_000, 250, 1_000)
return
} catch {
// Continue polling until timeout or child exit.
}
}
await stopManagedProcess(activeProcess)
activeProcess = undefined
throw new Error(`Timed out waiting for web server readiness at ${baseURL} after ${timeoutMs}ms.`)
}
export const stopWebServer = async () => {
await stopManagedProcess(activeProcess)
activeProcess = undefined
}