diff --git a/site/e2e/helpers.ts b/site/e2e/helpers.ts index c5ac7f1abde65..f099d9ff39a5a 100644 --- a/site/e2e/helpers.ts +++ b/site/e2e/helpers.ts @@ -1,5 +1,6 @@ import { type ChildProcess, exec, spawn } from "node:child_process"; import { randomUUID } from "node:crypto"; +import net from "node:net"; import path from "node:path"; import { Duplex } from "node:stream"; import { type BrowserContext, type Page, expect, test } from "@playwright/test"; @@ -685,6 +686,8 @@ export class Awaiter { export const createServer = async ( port: number, ): Promise> => { + await waitForPort(port); // Wait until the port is available + const e = express(); // We need to specify the local IP address as the web server // tends to fail with IPv6 related error: @@ -693,6 +696,44 @@ export const createServer = async ( return e; }; +async function waitForPort( + port: number, + host = "0.0.0.0", + timeout = 30000, +): Promise { + const start = Date.now(); + while (Date.now() - start < timeout) { + const available = await isPortAvailable(port, host); + if (available) { + return; + } + console.warn(`${host}:${port} is in use, checking again in 1s`); + await new Promise((resolve) => setTimeout(resolve, 1000)); // Wait 1 second before retrying + } + throw new Error( + `Timeout: port ${port} is still in use after ${timeout / 1000} seconds.`, + ); +} + +function isPortAvailable(port: number, host = "0.0.0.0"): Promise { + return new Promise((resolve) => { + const probe = net + .createServer() + .once("error", (err: NodeJS.ErrnoException) => { + if (err.code === "EADDRINUSE") { + resolve(false); // port is in use + } else { + resolve(false); // some other error occurred + } + }) + .once("listening", () => { + probe.close(); + resolve(true); // port is available + }) + .listen(port, host); + }); +} + export const findSessionToken = async (page: Page): Promise => { const cookies = await page.context().cookies(); const sessionCookie = cookies.find((c) => c.name === "coder_session_token"); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy