@lambdatest/smartui-cli 4.1.55 → 4.1.56-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +162 -21
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -18,10 +18,10 @@ var stringify = require('json-stringify-safe');
|
|
|
18
18
|
var FormData = require('form-data');
|
|
19
19
|
var axios = require('axios');
|
|
20
20
|
var https = require('https');
|
|
21
|
+
var uuid = require('uuid');
|
|
21
22
|
var child_process = require('child_process');
|
|
22
23
|
var spawn = require('cross-spawn');
|
|
23
24
|
var NodeCache = require('node-cache');
|
|
24
|
-
var uuid = require('uuid');
|
|
25
25
|
var sharp = require('sharp');
|
|
26
26
|
var http = require('http');
|
|
27
27
|
|
|
@@ -2432,16 +2432,28 @@ function findAvailablePort(server, startPort, log2) {
|
|
|
2432
2432
|
return currentPort;
|
|
2433
2433
|
} catch (error) {
|
|
2434
2434
|
if (error.code === "EADDRINUSE") {
|
|
2435
|
-
log2.debug(`Port ${currentPort} is in use, finding available port in range
|
|
2436
|
-
const
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2435
|
+
log2.debug(`Port ${currentPort} is in use, finding available port in range ${constants_default.MIN_PORT_RANGE}-${constants_default.MAX_PORT_RANGE}`);
|
|
2436
|
+
const maxRetries = 3;
|
|
2437
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
2438
|
+
try {
|
|
2439
|
+
const availablePorts = yield fp(constants_default.MIN_PORT_RANGE, constants_default.MAX_PORT_RANGE);
|
|
2440
|
+
if (availablePorts.length > 0) {
|
|
2441
|
+
const freePort = availablePorts[0];
|
|
2442
|
+
yield server.listen({ port: freePort });
|
|
2443
|
+
log2.debug(`Found and started server on port ${freePort}`);
|
|
2444
|
+
return freePort;
|
|
2445
|
+
} else {
|
|
2446
|
+
throw new Error(`No available ports found in range ${constants_default.MIN_PORT_RANGE}-${constants_default.MAX_PORT_RANGE}`);
|
|
2447
|
+
}
|
|
2448
|
+
} catch (retryError) {
|
|
2449
|
+
if (retryError.code === "EADDRINUSE" && attempt < maxRetries) {
|
|
2450
|
+
log2.debug(`Port race condition on attempt ${attempt}, retrying...`);
|
|
2451
|
+
continue;
|
|
2452
|
+
}
|
|
2453
|
+
throw retryError;
|
|
2454
|
+
}
|
|
2444
2455
|
}
|
|
2456
|
+
throw new Error("Failed to find available port after max retries");
|
|
2445
2457
|
} else {
|
|
2446
2458
|
throw error;
|
|
2447
2459
|
}
|
|
@@ -2700,6 +2712,68 @@ var server_default = (ctx) => __async(null, null, function* () {
|
|
|
2700
2712
|
return reply.code(replyCode).send(replyBody);
|
|
2701
2713
|
}
|
|
2702
2714
|
}));
|
|
2715
|
+
server.get("/smartui/results", opts, (request, reply) => __async(null, null, function* () {
|
|
2716
|
+
var _a;
|
|
2717
|
+
let replyCode;
|
|
2718
|
+
let replyBody;
|
|
2719
|
+
try {
|
|
2720
|
+
const { sessionId } = request.query;
|
|
2721
|
+
ctx.log.debug(`smartui results request: sessionId=${sessionId || "none"}`);
|
|
2722
|
+
let resolvedBuildId = "";
|
|
2723
|
+
let projectToken = "";
|
|
2724
|
+
if (sessionId) {
|
|
2725
|
+
if ((_a = ctx.sessionCapabilitiesMap) == null ? void 0 : _a.has(sessionId)) {
|
|
2726
|
+
const cachedCapabilities = ctx.sessionCapabilitiesMap.get(sessionId);
|
|
2727
|
+
resolvedBuildId = (cachedCapabilities == null ? void 0 : cachedCapabilities.buildId) || "";
|
|
2728
|
+
projectToken = (cachedCapabilities == null ? void 0 : cachedCapabilities.projectToken) || "";
|
|
2729
|
+
ctx.log.debug(`Resolved from sessionCapabilitiesMap for sessionId ${sessionId}: buildId=${resolvedBuildId}, projectToken=${projectToken ? "present" : "missing"}`);
|
|
2730
|
+
} else {
|
|
2731
|
+
try {
|
|
2732
|
+
const fetchedCapabilitiesResp = yield ctx.client.getSmartUICapabilities(sessionId, ctx.config, ctx.git, ctx.log, ctx.isStartExec, ctx.options.baselineBuild);
|
|
2733
|
+
resolvedBuildId = (fetchedCapabilitiesResp == null ? void 0 : fetchedCapabilitiesResp.buildId) || "";
|
|
2734
|
+
projectToken = (fetchedCapabilitiesResp == null ? void 0 : fetchedCapabilitiesResp.projectToken) || "";
|
|
2735
|
+
ctx.log.debug(`Fetched caps for sessionId: ${sessionId} are ${JSON.stringify(fetchedCapabilitiesResp)}`);
|
|
2736
|
+
if (resolvedBuildId) {
|
|
2737
|
+
ctx.sessionCapabilitiesMap.set(sessionId, fetchedCapabilitiesResp);
|
|
2738
|
+
} else if (fetchedCapabilitiesResp && (fetchedCapabilitiesResp == null ? void 0 : fetchedCapabilitiesResp.sessionId)) {
|
|
2739
|
+
ctx.sessionCapabilitiesMap.set(sessionId, fetchedCapabilitiesResp);
|
|
2740
|
+
}
|
|
2741
|
+
} catch (error) {
|
|
2742
|
+
ctx.log.debug(`Failed to fetch capabilities for sessionId ${sessionId}: ${JSON.stringify(error)}`);
|
|
2743
|
+
}
|
|
2744
|
+
}
|
|
2745
|
+
}
|
|
2746
|
+
if ((!resolvedBuildId || resolvedBuildId.length <= 30) && ctx.build && ctx.build.id) {
|
|
2747
|
+
resolvedBuildId = ctx.build.id;
|
|
2748
|
+
}
|
|
2749
|
+
if (!projectToken) {
|
|
2750
|
+
projectToken = ctx.env.PROJECT_TOKEN || "";
|
|
2751
|
+
}
|
|
2752
|
+
ctx.log.debug(`smartui results params: sessionId=${sessionId || "none"}, buildId=${resolvedBuildId}, projectToken=${projectToken ? "present" : "missing"}`);
|
|
2753
|
+
if (!resolvedBuildId) {
|
|
2754
|
+
replyCode = 404;
|
|
2755
|
+
replyBody = { error: { message: "Unable to determine buildId. Ensure a SmartUI build is active." } };
|
|
2756
|
+
return reply.code(replyCode).send(replyBody);
|
|
2757
|
+
}
|
|
2758
|
+
const resp = yield ctx.client.getScreenshotData(
|
|
2759
|
+
resolvedBuildId,
|
|
2760
|
+
false,
|
|
2761
|
+
ctx.log,
|
|
2762
|
+
projectToken,
|
|
2763
|
+
"",
|
|
2764
|
+
sessionId || "",
|
|
2765
|
+
"smartui-results"
|
|
2766
|
+
);
|
|
2767
|
+
replyCode = 200;
|
|
2768
|
+
replyBody = resp;
|
|
2769
|
+
} catch (error) {
|
|
2770
|
+
const errMsg = (error == null ? void 0 : error.message) || (typeof error === "string" ? error : JSON.stringify(error));
|
|
2771
|
+
ctx.log.debug(`smartui results failed; ${errMsg}`);
|
|
2772
|
+
replyCode = 500;
|
|
2773
|
+
replyBody = { error: { message: `smartui results failed; ${errMsg}` } };
|
|
2774
|
+
}
|
|
2775
|
+
return reply.code(replyCode).send(replyBody);
|
|
2776
|
+
}));
|
|
2703
2777
|
server.get("/build/info", opts, (request, reply) => __async(null, null, function* () {
|
|
2704
2778
|
let replyCode;
|
|
2705
2779
|
let replyBody;
|
|
@@ -2838,6 +2912,24 @@ var logger = winston.createLogger({
|
|
|
2838
2912
|
})
|
|
2839
2913
|
]
|
|
2840
2914
|
});
|
|
2915
|
+
function removeFileTransport() {
|
|
2916
|
+
logger.transports.forEach((transport) => {
|
|
2917
|
+
if (transport instanceof winston.transports.File) {
|
|
2918
|
+
logger.remove(transport);
|
|
2919
|
+
}
|
|
2920
|
+
});
|
|
2921
|
+
}
|
|
2922
|
+
function reconfigureLogFile(newFilePath) {
|
|
2923
|
+
logger.transports.forEach((transport) => {
|
|
2924
|
+
if (transport instanceof winston.transports.File) {
|
|
2925
|
+
logger.remove(transport);
|
|
2926
|
+
}
|
|
2927
|
+
});
|
|
2928
|
+
logger.add(new winston.transports.File({
|
|
2929
|
+
level: "debug",
|
|
2930
|
+
filename: newFilePath
|
|
2931
|
+
}));
|
|
2932
|
+
}
|
|
2841
2933
|
var logger_default = logger;
|
|
2842
2934
|
|
|
2843
2935
|
// src/tasks/startServer.ts
|
|
@@ -2895,7 +2987,7 @@ var authExec_default = (ctx) => {
|
|
|
2895
2987
|
};
|
|
2896
2988
|
|
|
2897
2989
|
// package.json
|
|
2898
|
-
var version = "4.1.
|
|
2990
|
+
var version = "4.1.56-beta.2";
|
|
2899
2991
|
var package_default = {
|
|
2900
2992
|
name: "@lambdatest/smartui-cli",
|
|
2901
2993
|
version,
|
|
@@ -3185,12 +3277,19 @@ var httpClient = class {
|
|
|
3185
3277
|
}
|
|
3186
3278
|
}, log2);
|
|
3187
3279
|
}
|
|
3188
|
-
getScreenshotData(buildId, baseline, log2, projectToken, buildName) {
|
|
3280
|
+
getScreenshotData(buildId, baseline, log2, projectToken, buildName, sessionId, type) {
|
|
3189
3281
|
log2.debug(`Fetching screenshot data for buildId: ${buildId} having buildName: ${buildName} with baseline: ${baseline}`);
|
|
3282
|
+
const params = { buildId, baseline, buildName };
|
|
3283
|
+
if (sessionId) {
|
|
3284
|
+
params.sessionId = sessionId;
|
|
3285
|
+
}
|
|
3286
|
+
if (type) {
|
|
3287
|
+
params.type = type;
|
|
3288
|
+
}
|
|
3190
3289
|
return this.request({
|
|
3191
3290
|
url: "/screenshot",
|
|
3192
3291
|
method: "GET",
|
|
3193
|
-
params
|
|
3292
|
+
params,
|
|
3194
3293
|
headers: { projectToken }
|
|
3195
3294
|
}, log2);
|
|
3196
3295
|
}
|
|
@@ -3509,8 +3608,13 @@ var httpClient = class {
|
|
|
3509
3608
|
}, ctx.log);
|
|
3510
3609
|
}
|
|
3511
3610
|
uploadLogs(ctx, uploadURL) {
|
|
3512
|
-
|
|
3513
|
-
|
|
3611
|
+
if (!ctx.logFilePath) {
|
|
3612
|
+
ctx.log.debug("Log file disabled, skipping log upload");
|
|
3613
|
+
return Promise.resolve();
|
|
3614
|
+
}
|
|
3615
|
+
const logPath = ctx.logFilePath;
|
|
3616
|
+
const fileStream = fs6__default.default.createReadStream(logPath);
|
|
3617
|
+
const { size } = fs6__default.default.statSync(logPath);
|
|
3514
3618
|
return this.request({
|
|
3515
3619
|
url: uploadURL,
|
|
3516
3620
|
method: "PUT",
|
|
@@ -3526,8 +3630,13 @@ var httpClient = class {
|
|
|
3526
3630
|
}, ctx.log);
|
|
3527
3631
|
}
|
|
3528
3632
|
uploadLogsForCaps(ctx, uploadURL) {
|
|
3529
|
-
|
|
3530
|
-
|
|
3633
|
+
if (!ctx.logFilePath) {
|
|
3634
|
+
ctx.log.debug("Log file disabled, skipping log upload");
|
|
3635
|
+
return Promise.resolve();
|
|
3636
|
+
}
|
|
3637
|
+
const logPath = ctx.logFilePath;
|
|
3638
|
+
const logContent = fs6__default.default.readFileSync(logPath);
|
|
3639
|
+
const { size } = fs6__default.default.statSync(logPath);
|
|
3531
3640
|
return this.request({
|
|
3532
3641
|
url: uploadURL,
|
|
3533
3642
|
method: "PUT",
|
|
@@ -3543,7 +3652,12 @@ var httpClient = class {
|
|
|
3543
3652
|
}, ctx.log);
|
|
3544
3653
|
}
|
|
3545
3654
|
sendCliLogsToLSRS(ctx) {
|
|
3546
|
-
|
|
3655
|
+
if (!ctx.logFilePath) {
|
|
3656
|
+
ctx.log.debug("Log file disabled, skipping log upload");
|
|
3657
|
+
return Promise.resolve();
|
|
3658
|
+
}
|
|
3659
|
+
const logPath = ctx.logFilePath;
|
|
3660
|
+
const logContent = fs6__default.default.readFileSync(logPath, "utf-8");
|
|
3547
3661
|
return this.request({
|
|
3548
3662
|
url: `/upload/logs`,
|
|
3549
3663
|
method: "POST",
|
|
@@ -3555,7 +3669,12 @@ var httpClient = class {
|
|
|
3555
3669
|
}, ctx.log);
|
|
3556
3670
|
}
|
|
3557
3671
|
sendCliLogsToLSRSForCaps(ctx, capsBuildId, capsProjectToken) {
|
|
3558
|
-
|
|
3672
|
+
if (!ctx.logFilePath) {
|
|
3673
|
+
ctx.log.debug("Log file disabled, skipping log upload");
|
|
3674
|
+
return Promise.resolve();
|
|
3675
|
+
}
|
|
3676
|
+
const logPath = ctx.logFilePath;
|
|
3677
|
+
const logContent = fs6__default.default.readFileSync(logPath, "utf-8");
|
|
3559
3678
|
return this.request({
|
|
3560
3679
|
url: `/upload/logs`,
|
|
3561
3680
|
method: "POST",
|
|
@@ -3851,6 +3970,26 @@ var ctx_default = (options) => {
|
|
|
3851
3970
|
if (config.waitForPageRender && config.waitForPageRender < 3e4) {
|
|
3852
3971
|
config.waitForPageRender = 3e4;
|
|
3853
3972
|
}
|
|
3973
|
+
let disableLogFile = options.disableLogFile ? true : false;
|
|
3974
|
+
if (disableLogFile) {
|
|
3975
|
+
removeFileTransport();
|
|
3976
|
+
logger_default.debug("File logging disabled via --disableLogFile flag");
|
|
3977
|
+
}
|
|
3978
|
+
let logFileUUID;
|
|
3979
|
+
let logFilePath = disableLogFile ? void 0 : constants_default.LOG_FILE_PATH;
|
|
3980
|
+
if (!disableLogFile && options.createUniqueLogFile) {
|
|
3981
|
+
logFileUUID = uuid.v4();
|
|
3982
|
+
logFilePath = `.smartui-${logFileUUID}.log`;
|
|
3983
|
+
reconfigureLogFile(logFilePath);
|
|
3984
|
+
try {
|
|
3985
|
+
if (fs6__default.default.existsSync(logFilePath)) {
|
|
3986
|
+
fs6__default.default.unlinkSync(logFilePath);
|
|
3987
|
+
}
|
|
3988
|
+
} catch (error) {
|
|
3989
|
+
logger_default.debug(`Could not delete existing unique log file: ${error.message}`);
|
|
3990
|
+
}
|
|
3991
|
+
logger_default.debug(`Using unique log file: ${logFilePath} (UUID: ${logFileUUID})`);
|
|
3992
|
+
}
|
|
3854
3993
|
return {
|
|
3855
3994
|
env,
|
|
3856
3995
|
log: logger_default,
|
|
@@ -3947,7 +4086,9 @@ var ctx_default = (options) => {
|
|
|
3947
4086
|
mergeBuildSourceId: "",
|
|
3948
4087
|
mergeBuildTargetId: "",
|
|
3949
4088
|
mergeByBranch: false,
|
|
3950
|
-
mergeByBuild: false
|
|
4089
|
+
mergeByBuild: false,
|
|
4090
|
+
logFileUUID,
|
|
4091
|
+
logFilePath
|
|
3951
4092
|
};
|
|
3952
4093
|
};
|
|
3953
4094
|
|
|
@@ -7642,7 +7783,7 @@ var uploadPdf_default = command10;
|
|
|
7642
7783
|
|
|
7643
7784
|
// src/commander/commander.ts
|
|
7644
7785
|
var program2 = new commander.Command();
|
|
7645
|
-
program2.name("smartui").description("CLI to help you run your SmartUI tests on LambdaTest platform").version(`v${version}`).option("-c --config <filepath>", "Config file path").option("--markBaseline", "Mark this build baseline").option("--baselineBranch <string>", "Mark this build baseline").option("--baselineBuild <string>", "Mark this build baseline").option("--githubURL <string>", "GitHub URL including commitId").option("--gitURL <string>", "Git URL including commitId").option("--userName <string>", "Specify the LT username").option("--accessKey <string>", "Specify the LT accesskey").addCommand(exec_default2).addCommand(capture_default).addCommand(configWeb).addCommand(configStatic).addCommand(upload_default).addCommand(server_default2).addCommand(stopServer_default).addCommand(merge_default).addCommand(ping_default).addCommand(configFigma).addCommand(uploadFigma).addCommand(configWebFigma).addCommand(configAppFigma).addCommand(uploadWebFigmaCommand).addCommand(uploadAppFigmaCommand).addCommand(pingTest_default).addCommand(uploadPdf_default);
|
|
7786
|
+
program2.name("smartui").description("CLI to help you run your SmartUI tests on LambdaTest platform").version(`v${version}`).option("-c --config <filepath>", "Config file path").option("--markBaseline", "Mark this build baseline").option("--baselineBranch <string>", "Mark this build baseline").option("--baselineBuild <string>", "Mark this build baseline").option("--githubURL <string>", "GitHub URL including commitId").option("--gitURL <string>", "Git URL including commitId").option("--userName <string>", "Specify the LT username").option("--accessKey <string>", "Specify the LT accesskey").option("--createUniqueLogFile", "Create a unique log file for each CLI execution to avoid file lock issues in parallel runs").option("--disableLogFile", "Disable writing logs to a file").addCommand(exec_default2).addCommand(capture_default).addCommand(configWeb).addCommand(configStatic).addCommand(upload_default).addCommand(server_default2).addCommand(stopServer_default).addCommand(merge_default).addCommand(ping_default).addCommand(configFigma).addCommand(uploadFigma).addCommand(configWebFigma).addCommand(configAppFigma).addCommand(uploadWebFigmaCommand).addCommand(uploadAppFigmaCommand).addCommand(pingTest_default).addCommand(uploadPdf_default);
|
|
7646
7787
|
var commander_default = program2;
|
|
7647
7788
|
(function() {
|
|
7648
7789
|
return __async(this, null, function* () {
|