@lambdatest/smartui-cli 2.0.5 → 2.0.7
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 +131 -59
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -69,7 +69,7 @@ var __async = (__this, __arguments, generator) => {
|
|
|
69
69
|
var MIN_VIEWPORT_HEIGHT = 1080;
|
|
70
70
|
var processSnapshot_default = (snapshot, ctx) => __async(void 0, null, function* () {
|
|
71
71
|
let options = snapshot.options;
|
|
72
|
-
let
|
|
72
|
+
let optionWarnings = /* @__PURE__ */ new Set();
|
|
73
73
|
let processedOptions = {};
|
|
74
74
|
if (options && Object.keys(options).length !== 0) {
|
|
75
75
|
ctx.log.debug(`Processing options: ${JSON.stringify(options)}`);
|
|
@@ -115,7 +115,7 @@ var processSnapshot_default = (snapshot, ctx) => __async(void 0, null, function*
|
|
|
115
115
|
for (const selector of selectors) {
|
|
116
116
|
let l = yield page.locator(selector).all();
|
|
117
117
|
if (l.length === 0) {
|
|
118
|
-
|
|
118
|
+
optionWarnings.add(`For snapshot ${snapshot.name}, no element found for selector ${selector}`);
|
|
119
119
|
continue;
|
|
120
120
|
}
|
|
121
121
|
locators.push(...l);
|
|
@@ -135,7 +135,6 @@ var processSnapshot_default = (snapshot, ctx) => __async(void 0, null, function*
|
|
|
135
135
|
}
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
|
-
warnings.push(...snapshot.dom.warnings);
|
|
139
138
|
return {
|
|
140
139
|
processedSnapshot: {
|
|
141
140
|
name: snapshot.name,
|
|
@@ -143,15 +142,19 @@ var processSnapshot_default = (snapshot, ctx) => __async(void 0, null, function*
|
|
|
143
142
|
dom: Buffer.from(snapshot.dom.html).toString("base64"),
|
|
144
143
|
options: processedOptions
|
|
145
144
|
},
|
|
146
|
-
warnings
|
|
145
|
+
warnings: [...optionWarnings, ...snapshot.dom.warnings]
|
|
147
146
|
};
|
|
148
147
|
});
|
|
149
148
|
var ajv = new Ajv__default.default({ allErrors: true });
|
|
150
149
|
ajv.addFormat("web-url", {
|
|
151
150
|
type: "string",
|
|
152
151
|
validate: (url) => {
|
|
153
|
-
|
|
154
|
-
|
|
152
|
+
try {
|
|
153
|
+
new URL(url.trim());
|
|
154
|
+
return true;
|
|
155
|
+
} catch (error) {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
155
158
|
}
|
|
156
159
|
});
|
|
157
160
|
addErrors__default.default(ajv);
|
|
@@ -322,7 +325,7 @@ var SnapshotSchema = {
|
|
|
322
325
|
additionalProperties: false
|
|
323
326
|
}
|
|
324
327
|
},
|
|
325
|
-
required: ["name", "url", "dom"
|
|
328
|
+
required: ["name", "url", "dom"],
|
|
326
329
|
additionalProperties: false,
|
|
327
330
|
errorMessage: "Invalid snapshot"
|
|
328
331
|
};
|
|
@@ -354,7 +357,7 @@ var server_default = (ctx) => __async(void 0, null, function* () {
|
|
|
354
357
|
return reply.code(500).send({ error: { message: error.message } });
|
|
355
358
|
}
|
|
356
359
|
}));
|
|
357
|
-
yield server.listen(
|
|
360
|
+
yield server.listen();
|
|
358
361
|
let { port } = server.addresses()[0];
|
|
359
362
|
process.env.SMARTUI_SERVER_ADDRESS = `http://localhost:${port}`;
|
|
360
363
|
return server;
|
|
@@ -365,42 +368,47 @@ var env_default = () => {
|
|
|
365
368
|
const {
|
|
366
369
|
PROJECT_TOKEN = "",
|
|
367
370
|
SMARTUI_CLIENT_API_URL = "https://api.lambdatest.com/visualui/1.0",
|
|
368
|
-
|
|
369
|
-
|
|
371
|
+
LT_SDK_LOG_LEVEL,
|
|
372
|
+
LT_SDK_DEBUG
|
|
370
373
|
} = process.env;
|
|
371
374
|
return {
|
|
372
375
|
PROJECT_TOKEN,
|
|
373
376
|
SMARTUI_CLIENT_API_URL,
|
|
374
|
-
|
|
375
|
-
|
|
377
|
+
LT_SDK_LOG_LEVEL,
|
|
378
|
+
LT_SDK_DEBUG
|
|
376
379
|
};
|
|
377
380
|
};
|
|
378
|
-
|
|
379
|
-
// src/lib/logger.ts
|
|
380
|
-
var logContext = {};
|
|
381
|
+
var logContext = { task: "smartui-cli" };
|
|
381
382
|
function updateLogContext(newContext) {
|
|
382
383
|
logContext = __spreadValues(__spreadValues({}, logContext), newContext);
|
|
383
384
|
}
|
|
384
385
|
var logLevel = () => {
|
|
385
386
|
let env = env_default();
|
|
386
|
-
let debug = env.
|
|
387
|
-
return debug || env.
|
|
387
|
+
let debug = env.LT_SDK_DEBUG === "true" ? "debug" : void 0;
|
|
388
|
+
return debug || env.LT_SDK_LOG_LEVEL || "info";
|
|
388
389
|
};
|
|
389
390
|
var logger = winston.createLogger({
|
|
390
391
|
level: logLevel(),
|
|
391
392
|
format: winston.format.combine(
|
|
392
393
|
winston.format.timestamp(),
|
|
393
394
|
winston.format.printf((info) => {
|
|
394
|
-
let contextString;
|
|
395
|
-
|
|
396
|
-
|
|
395
|
+
let contextString = Object.values(logContext).join(" | ");
|
|
396
|
+
let message = typeof info.message === "object" ? JSON.stringify(info.message) : info.message;
|
|
397
|
+
switch (info.level) {
|
|
398
|
+
case "debug":
|
|
399
|
+
message = chalk__default.default.blue(message);
|
|
400
|
+
break;
|
|
401
|
+
case "warn":
|
|
402
|
+
message = chalk__default.default.yellow(message);
|
|
403
|
+
break;
|
|
404
|
+
case "error":
|
|
405
|
+
message = chalk__default.default.red(message);
|
|
406
|
+
break;
|
|
397
407
|
}
|
|
398
|
-
|
|
399
|
-
message += info.message === "object" ? JSON.stringify(info.message) : info.message;
|
|
400
|
-
return message;
|
|
408
|
+
return info.level === "info" ? message : `[${contextString}:${info.level}] ` + message;
|
|
401
409
|
})
|
|
402
410
|
),
|
|
403
|
-
transports: [new winston.transports.
|
|
411
|
+
transports: [new winston.transports.Console()]
|
|
404
412
|
});
|
|
405
413
|
var logger_default = logger;
|
|
406
414
|
|
|
@@ -416,9 +424,8 @@ var startServer_default = (ctx) => {
|
|
|
416
424
|
task.output = chalk__default.default.gray(`listening on port ${(_a = ctx2.server.addresses()[0]) == null ? void 0 : _a.port}`);
|
|
417
425
|
task.title = "SmartUI started";
|
|
418
426
|
} catch (error) {
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
}
|
|
427
|
+
ctx2.log.debug(error);
|
|
428
|
+
task.output = chalk__default.default.gray(error.message);
|
|
422
429
|
throw new Error("SmartUI server setup failed");
|
|
423
430
|
}
|
|
424
431
|
}),
|
|
@@ -435,7 +442,7 @@ var auth_default = (ctx) => {
|
|
|
435
442
|
task.output = chalk__default.default.gray(`using project token '******#${ctx2.env.PROJECT_TOKEN.split("#").pop()}'`);
|
|
436
443
|
task.title = "Authenticated with SmartUI";
|
|
437
444
|
} catch (error) {
|
|
438
|
-
ctx2.log.debug(error
|
|
445
|
+
ctx2.log.debug(error);
|
|
439
446
|
task.output = chalk__default.default.gray(error.message);
|
|
440
447
|
throw new Error("Authentication failed");
|
|
441
448
|
}
|
|
@@ -504,30 +511,59 @@ function createWebStaticConfig(filepath) {
|
|
|
504
511
|
}
|
|
505
512
|
|
|
506
513
|
// package.json
|
|
507
|
-
var version = "2.0.
|
|
508
|
-
var
|
|
509
|
-
|
|
510
|
-
|
|
514
|
+
var version = "2.0.7";
|
|
515
|
+
var package_default = {
|
|
516
|
+
name: "@lambdatest/smartui-cli",
|
|
517
|
+
version,
|
|
518
|
+
description: "A command line interface (CLI) to run SmartUI tests on LambdaTest",
|
|
519
|
+
files: [
|
|
520
|
+
"dist/**/*"
|
|
521
|
+
],
|
|
522
|
+
scripts: {
|
|
523
|
+
build: "tsup",
|
|
524
|
+
release: "pnpm run build && pnpm publish --access public --no-git-checks"
|
|
525
|
+
},
|
|
526
|
+
bin: {
|
|
527
|
+
smartui: "./dist/index.cjs"
|
|
528
|
+
},
|
|
529
|
+
type: "module",
|
|
530
|
+
keywords: [
|
|
531
|
+
"lambdatest",
|
|
532
|
+
"smartui",
|
|
533
|
+
"cli"
|
|
534
|
+
],
|
|
535
|
+
author: "LambdaTest <keys@lambdatest.com>",
|
|
536
|
+
license: "MIT",
|
|
537
|
+
dependencies: {
|
|
538
|
+
"@playwright/browser-chromium": "^1.40.1",
|
|
539
|
+
"@playwright/browser-firefox": "^1.40.1",
|
|
540
|
+
"@playwright/browser-webkit": "^1.40.1",
|
|
541
|
+
"@playwright/test": "^1.40.1",
|
|
542
|
+
"@types/cross-spawn": "^6.0.4",
|
|
543
|
+
"@types/node": "^20.8.9",
|
|
544
|
+
"@types/which": "^3.0.2",
|
|
545
|
+
ajv: "^8.12.0",
|
|
546
|
+
"ajv-errors": "^3.0.0",
|
|
547
|
+
axios: "^1.6.0",
|
|
548
|
+
chalk: "^4.1.2",
|
|
549
|
+
commander: "^11.1.0",
|
|
550
|
+
"cross-spawn": "^7.0.3",
|
|
551
|
+
fastify: "^4.24.3",
|
|
552
|
+
"form-data": "^4.0.0",
|
|
553
|
+
listr2: "^7.0.1",
|
|
554
|
+
tsup: "^7.2.0",
|
|
555
|
+
which: "^4.0.0",
|
|
556
|
+
winston: "^3.10.0"
|
|
557
|
+
},
|
|
558
|
+
devDependencies: {
|
|
559
|
+
typescript: "^5.3.2"
|
|
560
|
+
}
|
|
561
|
+
};
|
|
511
562
|
function delDir(dir) {
|
|
512
563
|
if (fs__default.default.existsSync(dir)) {
|
|
513
564
|
fs__default.default.rmSync(dir, { recursive: true });
|
|
514
565
|
}
|
|
515
566
|
}
|
|
516
|
-
function ensureHttps(urlString) {
|
|
517
|
-
try {
|
|
518
|
-
if (urlString && urlString.startsWith(WWW)) {
|
|
519
|
-
urlString = HTTP_SCHEME_PREFIX + urlString;
|
|
520
|
-
}
|
|
521
|
-
let url = new URL(urlString);
|
|
522
|
-
if (url.protocol !== HTTP_SCHEME) {
|
|
523
|
-
url.protocol = HTTP_SCHEME;
|
|
524
|
-
}
|
|
525
|
-
return url.toString();
|
|
526
|
-
} catch (error) {
|
|
527
|
-
console.error("Invalid URL: " + urlString, error);
|
|
528
|
-
return null;
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
567
|
function scrollToBottomAndBackToTop({
|
|
532
568
|
frequency = 100,
|
|
533
569
|
timing = 8,
|
|
@@ -575,11 +611,18 @@ var httpClient = class {
|
|
|
575
611
|
return resp.data;
|
|
576
612
|
}).catch((error) => {
|
|
577
613
|
if (error.response) {
|
|
614
|
+
log.debug(`http response: ${JSON.stringify({
|
|
615
|
+
status: error.response.status,
|
|
616
|
+
headers: error.response.headers,
|
|
617
|
+
body: error.response.data
|
|
618
|
+
})}`);
|
|
578
619
|
throw new Error(JSON.stringify(error.response.data));
|
|
579
620
|
}
|
|
580
621
|
if (error.request) {
|
|
622
|
+
log.debug(`http request failed: ${error.toJSON()}`);
|
|
581
623
|
throw new Error(error.toJSON().message);
|
|
582
624
|
}
|
|
625
|
+
log.debug(`http request failed: ${error.message}`);
|
|
583
626
|
throw new Error(error.message);
|
|
584
627
|
});
|
|
585
628
|
});
|
|
@@ -664,6 +707,17 @@ var httpClient = class {
|
|
|
664
707
|
throw new Error(error.message);
|
|
665
708
|
});
|
|
666
709
|
}
|
|
710
|
+
checkUpdate(log) {
|
|
711
|
+
return this.request({
|
|
712
|
+
url: `/packageinfo`,
|
|
713
|
+
method: "GET",
|
|
714
|
+
headers: { "Content-Type": "application/json" },
|
|
715
|
+
params: {
|
|
716
|
+
packageName: package_default.name,
|
|
717
|
+
packageVersion: package_default.version
|
|
718
|
+
}
|
|
719
|
+
}, log);
|
|
720
|
+
}
|
|
667
721
|
};
|
|
668
722
|
var ctx_default = (options) => {
|
|
669
723
|
let env = env_default();
|
|
@@ -762,6 +816,7 @@ var getGitInfo_default = (ctx) => {
|
|
|
762
816
|
task.output = chalk__default.default.gray(`branch: ${ctx2.git.branch}, commit: ${ctx2.git.commitId}, author: ${ctx2.git.commitAuthor}`);
|
|
763
817
|
task.title = "Fetched git information";
|
|
764
818
|
} catch (error) {
|
|
819
|
+
ctx2.log.debug(error);
|
|
765
820
|
task.output = chalk__default.default.gray(`${error.message}`);
|
|
766
821
|
throw new Error("Error fetching git repo details");
|
|
767
822
|
}
|
|
@@ -786,6 +841,7 @@ var createBuild_default = (ctx) => {
|
|
|
786
841
|
task.output = chalk__default.default.gray(`build id: ${resp.data.buildId}`);
|
|
787
842
|
task.title = "SmartUI build created";
|
|
788
843
|
} catch (error) {
|
|
844
|
+
ctx2.log.debug(error);
|
|
789
845
|
task.output = chalk__default.default.gray(JSON.parse(error.message).message);
|
|
790
846
|
throw new Error("SmartUI build creation failed");
|
|
791
847
|
}
|
|
@@ -839,9 +895,9 @@ var finalizeBuild_default = (ctx) => {
|
|
|
839
895
|
task.output = chalk__default.default.gray(`build url: ${ctx2.build.url}`);
|
|
840
896
|
task.title = "Finalized build";
|
|
841
897
|
} catch (error) {
|
|
842
|
-
ctx2.log.debug(error
|
|
898
|
+
ctx2.log.debug(error);
|
|
843
899
|
task.output = chalk__default.default.gray(error.message);
|
|
844
|
-
throw new Error("Finalize build
|
|
900
|
+
throw new Error("Finalize build failed");
|
|
845
901
|
}
|
|
846
902
|
}),
|
|
847
903
|
rendererOptions: { persistentOutput: true }
|
|
@@ -855,7 +911,7 @@ command.name("exec").description("Run test commands around SmartUI").argument("<
|
|
|
855
911
|
var _a, _b;
|
|
856
912
|
let ctx = ctx_default(command3.optsWithGlobals());
|
|
857
913
|
if (!which__default.default.sync(execCommand[0], { nothrow: true })) {
|
|
858
|
-
|
|
914
|
+
ctx.log.error(`Error: Command not found "${execCommand[0]}"`);
|
|
859
915
|
return;
|
|
860
916
|
}
|
|
861
917
|
ctx.args.execCommand = execCommand;
|
|
@@ -883,7 +939,7 @@ command.name("exec").description("Run test commands around SmartUI").argument("<
|
|
|
883
939
|
try {
|
|
884
940
|
yield tasks.run(ctx);
|
|
885
941
|
} catch (error) {
|
|
886
|
-
|
|
942
|
+
ctx.log.info("\nRefer docs: https://www.lambdatest.com/support/docs/smart-visual-regression-testing/");
|
|
887
943
|
} finally {
|
|
888
944
|
yield (_a = ctx.server) == null ? void 0 : _a.close();
|
|
889
945
|
yield (_b = ctx.browser) == null ? void 0 : _b.close();
|
|
@@ -944,11 +1000,7 @@ function captureScreenshots(ctx, screenshots) {
|
|
|
944
1000
|
let screenshot = screenshots[j];
|
|
945
1001
|
let screenshotId = screenshot.name.toLowerCase().replace(/\s/g, "-");
|
|
946
1002
|
const page = yield context.newPage();
|
|
947
|
-
|
|
948
|
-
screenshot.url = screenshot.url.trim();
|
|
949
|
-
screenshot.url = ensureHttps(screenshot.url);
|
|
950
|
-
}
|
|
951
|
-
yield page.goto(screenshot.url, pageOptions);
|
|
1003
|
+
yield page.goto(screenshot.url.trim(), pageOptions);
|
|
952
1004
|
for (let k = 0; k < totalViewports; k++) {
|
|
953
1005
|
let { width, height } = ctx.webConfig.viewports[k];
|
|
954
1006
|
let ssName = `${browserName}-${width}x${height}-${screenshotId}.png`;
|
|
@@ -1044,6 +1096,26 @@ var capture_default = command2;
|
|
|
1044
1096
|
var program = new commander.Command();
|
|
1045
1097
|
program.name("smartui").description("CLI to help you run your SmartUI tests on LambdaTest platform").version(`v${version}`).option("-c --config <filepath>", "Config file path").addCommand(exec_default2).addCommand(capture_default).addCommand(configWeb).addCommand(configStatic);
|
|
1046
1098
|
var commander_default = program;
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1099
|
+
(function() {
|
|
1100
|
+
return __async(this, null, function* () {
|
|
1101
|
+
let client = new httpClient(env_default());
|
|
1102
|
+
let log = logger_default;
|
|
1103
|
+
try {
|
|
1104
|
+
log.info(`
|
|
1105
|
+
LambdaTest SmartUI CLI v${package_default.version}`);
|
|
1106
|
+
let { data: { latestVersion, deprecated } } = yield client.checkUpdate(log);
|
|
1107
|
+
if (deprecated)
|
|
1108
|
+
log.warn(`This version is deprecated. A new version ${latestVersion} is available!
|
|
1109
|
+
`);
|
|
1110
|
+
else if (package_default.version !== latestVersion)
|
|
1111
|
+
log.info(chalk__default.default.gray(`A new version ${latestVersion} is available!
|
|
1112
|
+
`));
|
|
1113
|
+
else
|
|
1114
|
+
log.info(chalk__default.default.gray("https://www.npmjs.com/package/@lambdatest/smartui-cli\n"));
|
|
1115
|
+
} catch (error) {
|
|
1116
|
+
log.debug(error);
|
|
1117
|
+
log.info(chalk__default.default.gray("https://www.npmjs.com/package/@lambdatest/smartui-cli\n"));
|
|
1118
|
+
}
|
|
1119
|
+
commander_default.parse();
|
|
1120
|
+
});
|
|
1121
|
+
})();
|