@lambdatest/smartui-cli 4.1.55-beta.0 → 4.1.56-beta.1
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 +150 -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,52 @@ 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 && ((_a = ctx.sessionCapabilitiesMap) == null ? void 0 : _a.has(sessionId))) {
|
|
2725
|
+
const cachedCapabilities = ctx.sessionCapabilitiesMap.get(sessionId);
|
|
2726
|
+
resolvedBuildId = (cachedCapabilities == null ? void 0 : cachedCapabilities.buildId) || "";
|
|
2727
|
+
projectToken = (cachedCapabilities == null ? void 0 : cachedCapabilities.projectToken) || "";
|
|
2728
|
+
ctx.log.debug(`Resolved from sessionCapabilitiesMap for sessionId ${sessionId}: buildId=${resolvedBuildId}, projectToken=${projectToken ? "present" : "missing"}`);
|
|
2729
|
+
}
|
|
2730
|
+
if ((!resolvedBuildId || resolvedBuildId.length <= 30) && ctx.build && ctx.build.id) {
|
|
2731
|
+
resolvedBuildId = ctx.build.id;
|
|
2732
|
+
}
|
|
2733
|
+
if (!projectToken) {
|
|
2734
|
+
projectToken = ctx.env.PROJECT_TOKEN || "";
|
|
2735
|
+
}
|
|
2736
|
+
ctx.log.debug(`smartui results params: sessionId=${sessionId || "none"}, buildId=${resolvedBuildId}, projectToken=${projectToken ? "present" : "missing"}`);
|
|
2737
|
+
if (!resolvedBuildId) {
|
|
2738
|
+
replyCode = 404;
|
|
2739
|
+
replyBody = { error: { message: "Unable to determine buildId. Ensure a SmartUI build is active." } };
|
|
2740
|
+
return reply.code(replyCode).send(replyBody);
|
|
2741
|
+
}
|
|
2742
|
+
const resp = yield ctx.client.getScreenshotData(
|
|
2743
|
+
resolvedBuildId,
|
|
2744
|
+
false,
|
|
2745
|
+
ctx.log,
|
|
2746
|
+
projectToken,
|
|
2747
|
+
"",
|
|
2748
|
+
sessionId || "",
|
|
2749
|
+
"smartui-results"
|
|
2750
|
+
);
|
|
2751
|
+
replyCode = 200;
|
|
2752
|
+
replyBody = resp;
|
|
2753
|
+
} catch (error) {
|
|
2754
|
+
const errMsg = (error == null ? void 0 : error.message) || (typeof error === "string" ? error : JSON.stringify(error));
|
|
2755
|
+
ctx.log.debug(`smartui results failed; ${errMsg}`);
|
|
2756
|
+
replyCode = 500;
|
|
2757
|
+
replyBody = { error: { message: `smartui results failed; ${errMsg}` } };
|
|
2758
|
+
}
|
|
2759
|
+
return reply.code(replyCode).send(replyBody);
|
|
2760
|
+
}));
|
|
2703
2761
|
server.get("/build/info", opts, (request, reply) => __async(null, null, function* () {
|
|
2704
2762
|
let replyCode;
|
|
2705
2763
|
let replyBody;
|
|
@@ -2838,6 +2896,24 @@ var logger = winston.createLogger({
|
|
|
2838
2896
|
})
|
|
2839
2897
|
]
|
|
2840
2898
|
});
|
|
2899
|
+
function removeFileTransport() {
|
|
2900
|
+
logger.transports.forEach((transport) => {
|
|
2901
|
+
if (transport instanceof winston.transports.File) {
|
|
2902
|
+
logger.remove(transport);
|
|
2903
|
+
}
|
|
2904
|
+
});
|
|
2905
|
+
}
|
|
2906
|
+
function reconfigureLogFile(newFilePath) {
|
|
2907
|
+
logger.transports.forEach((transport) => {
|
|
2908
|
+
if (transport instanceof winston.transports.File) {
|
|
2909
|
+
logger.remove(transport);
|
|
2910
|
+
}
|
|
2911
|
+
});
|
|
2912
|
+
logger.add(new winston.transports.File({
|
|
2913
|
+
level: "debug",
|
|
2914
|
+
filename: newFilePath
|
|
2915
|
+
}));
|
|
2916
|
+
}
|
|
2841
2917
|
var logger_default = logger;
|
|
2842
2918
|
|
|
2843
2919
|
// src/tasks/startServer.ts
|
|
@@ -2895,7 +2971,7 @@ var authExec_default = (ctx) => {
|
|
|
2895
2971
|
};
|
|
2896
2972
|
|
|
2897
2973
|
// package.json
|
|
2898
|
-
var version = "4.1.
|
|
2974
|
+
var version = "4.1.56-beta.1";
|
|
2899
2975
|
var package_default = {
|
|
2900
2976
|
name: "@lambdatest/smartui-cli",
|
|
2901
2977
|
version,
|
|
@@ -3185,12 +3261,19 @@ var httpClient = class {
|
|
|
3185
3261
|
}
|
|
3186
3262
|
}, log2);
|
|
3187
3263
|
}
|
|
3188
|
-
getScreenshotData(buildId, baseline, log2, projectToken, buildName) {
|
|
3264
|
+
getScreenshotData(buildId, baseline, log2, projectToken, buildName, sessionId, type) {
|
|
3189
3265
|
log2.debug(`Fetching screenshot data for buildId: ${buildId} having buildName: ${buildName} with baseline: ${baseline}`);
|
|
3266
|
+
const params = { buildId, baseline, buildName };
|
|
3267
|
+
if (sessionId) {
|
|
3268
|
+
params.sessionId = sessionId;
|
|
3269
|
+
}
|
|
3270
|
+
if (type) {
|
|
3271
|
+
params.type = type;
|
|
3272
|
+
}
|
|
3190
3273
|
return this.request({
|
|
3191
3274
|
url: "/screenshot",
|
|
3192
3275
|
method: "GET",
|
|
3193
|
-
params
|
|
3276
|
+
params,
|
|
3194
3277
|
headers: { projectToken }
|
|
3195
3278
|
}, log2);
|
|
3196
3279
|
}
|
|
@@ -3509,8 +3592,13 @@ var httpClient = class {
|
|
|
3509
3592
|
}, ctx.log);
|
|
3510
3593
|
}
|
|
3511
3594
|
uploadLogs(ctx, uploadURL) {
|
|
3512
|
-
|
|
3513
|
-
|
|
3595
|
+
if (!ctx.logFilePath) {
|
|
3596
|
+
ctx.log.debug("Log file disabled, skipping log upload");
|
|
3597
|
+
return Promise.resolve();
|
|
3598
|
+
}
|
|
3599
|
+
const logPath = ctx.logFilePath;
|
|
3600
|
+
const fileStream = fs6__default.default.createReadStream(logPath);
|
|
3601
|
+
const { size } = fs6__default.default.statSync(logPath);
|
|
3514
3602
|
return this.request({
|
|
3515
3603
|
url: uploadURL,
|
|
3516
3604
|
method: "PUT",
|
|
@@ -3526,8 +3614,13 @@ var httpClient = class {
|
|
|
3526
3614
|
}, ctx.log);
|
|
3527
3615
|
}
|
|
3528
3616
|
uploadLogsForCaps(ctx, uploadURL) {
|
|
3529
|
-
|
|
3530
|
-
|
|
3617
|
+
if (!ctx.logFilePath) {
|
|
3618
|
+
ctx.log.debug("Log file disabled, skipping log upload");
|
|
3619
|
+
return Promise.resolve();
|
|
3620
|
+
}
|
|
3621
|
+
const logPath = ctx.logFilePath;
|
|
3622
|
+
const logContent = fs6__default.default.readFileSync(logPath);
|
|
3623
|
+
const { size } = fs6__default.default.statSync(logPath);
|
|
3531
3624
|
return this.request({
|
|
3532
3625
|
url: uploadURL,
|
|
3533
3626
|
method: "PUT",
|
|
@@ -3543,7 +3636,12 @@ var httpClient = class {
|
|
|
3543
3636
|
}, ctx.log);
|
|
3544
3637
|
}
|
|
3545
3638
|
sendCliLogsToLSRS(ctx) {
|
|
3546
|
-
|
|
3639
|
+
if (!ctx.logFilePath) {
|
|
3640
|
+
ctx.log.debug("Log file disabled, skipping log upload");
|
|
3641
|
+
return Promise.resolve();
|
|
3642
|
+
}
|
|
3643
|
+
const logPath = ctx.logFilePath;
|
|
3644
|
+
const logContent = fs6__default.default.readFileSync(logPath, "utf-8");
|
|
3547
3645
|
return this.request({
|
|
3548
3646
|
url: `/upload/logs`,
|
|
3549
3647
|
method: "POST",
|
|
@@ -3555,7 +3653,12 @@ var httpClient = class {
|
|
|
3555
3653
|
}, ctx.log);
|
|
3556
3654
|
}
|
|
3557
3655
|
sendCliLogsToLSRSForCaps(ctx, capsBuildId, capsProjectToken) {
|
|
3558
|
-
|
|
3656
|
+
if (!ctx.logFilePath) {
|
|
3657
|
+
ctx.log.debug("Log file disabled, skipping log upload");
|
|
3658
|
+
return Promise.resolve();
|
|
3659
|
+
}
|
|
3660
|
+
const logPath = ctx.logFilePath;
|
|
3661
|
+
const logContent = fs6__default.default.readFileSync(logPath, "utf-8");
|
|
3559
3662
|
return this.request({
|
|
3560
3663
|
url: `/upload/logs`,
|
|
3561
3664
|
method: "POST",
|
|
@@ -3851,6 +3954,26 @@ var ctx_default = (options) => {
|
|
|
3851
3954
|
if (config.waitForPageRender && config.waitForPageRender < 3e4) {
|
|
3852
3955
|
config.waitForPageRender = 3e4;
|
|
3853
3956
|
}
|
|
3957
|
+
let disableLogFile = options.disableLogFile ? true : false;
|
|
3958
|
+
if (disableLogFile) {
|
|
3959
|
+
removeFileTransport();
|
|
3960
|
+
logger_default.debug("File logging disabled via --disableLogFile flag");
|
|
3961
|
+
}
|
|
3962
|
+
let logFileUUID;
|
|
3963
|
+
let logFilePath = disableLogFile ? void 0 : constants_default.LOG_FILE_PATH;
|
|
3964
|
+
if (!disableLogFile && options.createUniqueLogFile) {
|
|
3965
|
+
logFileUUID = uuid.v4();
|
|
3966
|
+
logFilePath = `.smartui-${logFileUUID}.log`;
|
|
3967
|
+
reconfigureLogFile(logFilePath);
|
|
3968
|
+
try {
|
|
3969
|
+
if (fs6__default.default.existsSync(logFilePath)) {
|
|
3970
|
+
fs6__default.default.unlinkSync(logFilePath);
|
|
3971
|
+
}
|
|
3972
|
+
} catch (error) {
|
|
3973
|
+
logger_default.debug(`Could not delete existing unique log file: ${error.message}`);
|
|
3974
|
+
}
|
|
3975
|
+
logger_default.debug(`Using unique log file: ${logFilePath} (UUID: ${logFileUUID})`);
|
|
3976
|
+
}
|
|
3854
3977
|
return {
|
|
3855
3978
|
env,
|
|
3856
3979
|
log: logger_default,
|
|
@@ -3947,7 +4070,9 @@ var ctx_default = (options) => {
|
|
|
3947
4070
|
mergeBuildSourceId: "",
|
|
3948
4071
|
mergeBuildTargetId: "",
|
|
3949
4072
|
mergeByBranch: false,
|
|
3950
|
-
mergeByBuild: false
|
|
4073
|
+
mergeByBuild: false,
|
|
4074
|
+
logFileUUID,
|
|
4075
|
+
logFilePath
|
|
3951
4076
|
};
|
|
3952
4077
|
};
|
|
3953
4078
|
|
|
@@ -4565,6 +4690,10 @@ function prepareSnapshot(snapshot, ctx) {
|
|
|
4565
4690
|
processedOptions.selectors = selectors;
|
|
4566
4691
|
processedOptions.ignoreDOM = options == null ? void 0 : options.ignoreDOM;
|
|
4567
4692
|
processedOptions.selectDOM = options == null ? void 0 : options.selectDOM;
|
|
4693
|
+
if ((options == null ? void 0 : options.customCookies) && Array.isArray(options.customCookies) && options.customCookies.length > 0) {
|
|
4694
|
+
ctx.log.debug(`Setting ${options.customCookies.length} custom cookies`);
|
|
4695
|
+
processedOptions.customCookies = options.customCookies;
|
|
4696
|
+
}
|
|
4568
4697
|
ctx.log.debug(`Processed options: ${JSON.stringify(processedOptions)}`);
|
|
4569
4698
|
let renderViewports;
|
|
4570
4699
|
if (snapshot.options && snapshot.options.web || snapshot.options && snapshot.options.mobile) {
|
|
@@ -7638,7 +7767,7 @@ var uploadPdf_default = command10;
|
|
|
7638
7767
|
|
|
7639
7768
|
// src/commander/commander.ts
|
|
7640
7769
|
var program2 = new commander.Command();
|
|
7641
|
-
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);
|
|
7770
|
+
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);
|
|
7642
7771
|
var commander_default = program2;
|
|
7643
7772
|
(function() {
|
|
7644
7773
|
return __async(this, null, function* () {
|