diff --git a/src/test/webServer.ts b/src/test/webServer.ts index 31226c56f1..12824f1dff 100644 --- a/src/test/webServer.ts +++ b/src/test/webServer.ts @@ -54,7 +54,7 @@ export class WebServer { let processExitedReject = (error: Error) => { }; this._processExitedPromise = new Promise((_, reject) => processExitedReject = reject); - const portIsUsed = !await canBindPort(this.config.port); + const portIsUsed = await isPortUsed(this.config.port); if (portIsUsed) { if (this.config.reuseExistingServer) return; @@ -104,31 +104,23 @@ export class WebServer { } } -async function canBindPort(port: number): Promise { +async function isPortUsed(port: number): Promise { return new Promise(resolve => { - const server = net.createServer(); - server.on('error', () => resolve(false)); - server.listen(port, () => { - server.close(() => { - resolve(true); - }); - }); + const conn = net + .connect(port) + .on('error', () => { + resolve(false); + }) + .on('connect', () => { + conn.end(); + resolve(true); + }); }); } async function waitForSocket(port: number, delay: number, cancellationToken: { canceled: boolean }) { while (!cancellationToken.canceled) { - const connected = await new Promise(resolve => { - const conn = net - .connect(port) - .on('error', () => { - resolve(false); - }) - .on('connect', () => { - conn.end(); - resolve(true); - }); - }); + const connected = await isPortUsed(port); if (connected) return; await new Promise(x => setTimeout(x, delay)); diff --git a/tests/playwright-test/web-server.spec.ts b/tests/playwright-test/web-server.spec.ts index 0391d692fa..ecd462cd3a 100644 --- a/tests/playwright-test/web-server.spec.ts +++ b/tests/playwright-test/web-server.spec.ts @@ -225,3 +225,37 @@ test('should throw when a server is already running on the given port and strict expect(result.output).toContain(`Port ${port} is used, make sure that nothing is running on the port`); await new Promise(resolve => server.close(resolve)); }); + +for (const host of ['localhost', '127.0.0.1', '0.0.0.0']) { + test(`should detect the server if a web-server is already running on ${host}`, async ({ runInlineTest }, { workerIndex }) => { + const port = workerIndex + 10500; + const server = http.createServer((req: http.IncomingMessage, res: http.ServerResponse) => { + res.end('hello'); + }); + await new Promise(resolve => server.listen(port, host, resolve)); + try { + const result = await runInlineTest({ + 'test.spec.ts': ` + const { test } = pwt; + test('connect to the server via the baseURL', async ({baseURL, page}) => { + await page.goto('/hello'); + expect(await page.textContent('body')).toBe('hello'); + }); + `, + 'playwright.config.ts': ` + module.exports = { + webServer: { + command: 'node -e "process.exit(1)"', + port: ${port}, + reuseExistingServer: false, + } + }; + `, + }); + expect(result.exitCode).toBe(1); + expect(result.output).toContain(`Port ${port} is used, make sure that nothing is running on the port`); + } finally { + await new Promise(resolve => server.close(resolve)); + } + }); +}