Skip to content

Commit 4b1dc32

Browse files
dynamically handle port in CLI
1 parent 3153208 commit 4b1dc32

File tree

2 files changed

+50
-6
lines changed

2 files changed

+50
-6
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
"simple-swizzle": "0.2.2"
5454
},
5555
"devDependencies": {
56+
"find-free-port": "^2.0.0",
5657
"typescript": "^5.3.2"
5758
}
5859
}

src/lib/server.ts

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,44 @@ import path from 'path';
33
import fastify, { FastifyInstance, RouteShorthandOptions } from 'fastify';
44
import { readFileSync, truncate } from 'fs'
55
import { Context } from '../types.js'
6+
import { Logger } from 'winston'
67
import { validateSnapshot } from './schemaValidation.js'
78
import { pingIntervalId, startPollingForTunnel, stopTunnelHelper, isTunnelPolling } from './utils.js';
9+
var fp = require("find-free-port")
810

911
const uploadDomToS3ViaEnv = process.env.USE_LAMBDA_INTERNAL || false;
12+
13+
// Helper function to find an available port
14+
async function findAvailablePort(server: FastifyInstance, startPort: number, log: Logger): Promise<number> {
15+
let currentPort = startPort;
16+
let attempts = 0;
17+
let maxAttempts = 10;
18+
19+
// If the default port gives error, use find-free-port with range 49100-60000
20+
try {
21+
await server.listen({ port: currentPort });
22+
return currentPort;
23+
} catch (error: any) {
24+
if (error.code === 'EADDRINUSE') {
25+
log.debug(`Port ${currentPort} is in use, finding available port in range 49100-60000`);
26+
27+
// Use find-free-port to get an available port in the specified range
28+
const availablePorts = await fp(49100, 60000);
29+
if (availablePorts.length > 0) {
30+
const freePort = availablePorts[0];
31+
await server.listen({ port: freePort });
32+
log.debug(`Found and started server on port ${freePort}`);
33+
return freePort;
34+
} else {
35+
throw new Error('No available ports found in range 49100-60000');
36+
}
37+
} else {
38+
// If it's not a port conflict error, rethrow it
39+
throw error;
40+
}
41+
}
42+
}
43+
1044
export default async (ctx: Context): Promise<FastifyInstance<Server, IncomingMessage, ServerResponse>> => {
1145

1246
const server: FastifyInstance<Server, IncomingMessage, ServerResponse> = fastify({
@@ -307,12 +341,21 @@ export default async (ctx: Context): Promise<FastifyInstance<Server, IncomingMes
307341
}
308342
});
309343

310-
311-
await server.listen({ port: ctx.options.port });
312-
// store server's address for SDK
313-
let { port } = server.addresses()[0];
314-
process.env.SMARTUI_SERVER_ADDRESS = `http://localhost:${port}`;
315-
process.env.CYPRESS_SMARTUI_SERVER_ADDRESS = `http://localhost:${port}`;
344+
// Use the helper function to find and start server on available port
345+
if (ctx.sourceCommand && ctx.sourceCommand === 'exec-start') {
346+
347+
await server.listen({ port: ctx.options.port });
348+
let { port } = server.addresses()[0];
349+
process.env.SMARTUI_SERVER_ADDRESS = `http://localhost:${port}`;
350+
process.env.CYPRESS_SMARTUI_SERVER_ADDRESS = `http://localhost:${port}`;
351+
ctx.log.debug(`Server started successfully on port ${port}`);
352+
353+
} else {
354+
const actualPort = await findAvailablePort(server, ctx.options.port, ctx.log);
355+
process.env.SMARTUI_SERVER_ADDRESS = `http://localhost:${actualPort}`;
356+
process.env.CYPRESS_SMARTUI_SERVER_ADDRESS = `http://localhost:${actualPort}`;
357+
ctx.log.debug(`Server started successfully on port ${actualPort}`);
358+
}
316359

317360
return server;
318361
}

0 commit comments

Comments
 (0)