Skip to content

Commit 9ea1aee

Browse files
authored
Merge pull request #376 from parthlambdatest/Dot-6308
[Dot-6308] dynamically handle port in CLI
2 parents 073b901 + b4d3682 commit 9ea1aee

File tree

3 files changed

+52
-7
lines changed

3 files changed

+52
-7
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@lambdatest/smartui-cli",
3-
"version": "4.1.33",
3+
"version": "4.1.34",
44
"description": "A command line interface (CLI) to run SmartUI tests on LambdaTest",
55
"files": [
66
"dist/**/*"
@@ -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/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ export default {
4646
EDGE: 'edge',
4747
EDGE_CHANNEL: 'msedge',
4848
WEBKIT: 'webkit',
49+
MIN_PORT_RANGE: 49100,
50+
MAX_PORT_RANGE: 60000,
4951

5052
// discovery browser launch arguments
5153
LAUNCH_ARGS: [

src/lib/server.ts

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,43 @@ 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+
import constants from './constants.js';
10+
var fp = require("find-free-port")
811

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

1245
const server: FastifyInstance<Server, IncomingMessage, ServerResponse> = fastify({
@@ -307,12 +340,21 @@ export default async (ctx: Context): Promise<FastifyInstance<Server, IncomingMes
307340
}
308341
});
309342

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}`;
343+
// Use the helper function to find and start server on available port
344+
if (ctx.sourceCommand && ctx.sourceCommand === 'exec-start') {
345+
346+
await server.listen({ port: ctx.options.port });
347+
let { port } = server.addresses()[0];
348+
process.env.SMARTUI_SERVER_ADDRESS = `http://localhost:${port}`;
349+
process.env.CYPRESS_SMARTUI_SERVER_ADDRESS = `http://localhost:${port}`;
350+
ctx.log.debug(`Server started successfully on port ${port}`);
351+
352+
} else {
353+
const actualPort = await findAvailablePort(server, ctx.options.port, ctx.log);
354+
process.env.SMARTUI_SERVER_ADDRESS = `http://localhost:${actualPort}`;
355+
process.env.CYPRESS_SMARTUI_SERVER_ADDRESS = `http://localhost:${actualPort}`;
356+
ctx.log.debug(`Server started successfully on port ${actualPort}`);
357+
}
316358

317359
return server;
318360
}

0 commit comments

Comments
 (0)