@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.
Files changed (2) hide show
  1. package/dist/index.cjs +131 -59
  2. 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 warnings = [];
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
- warnings.push(`For snapshot ${snapshot.name}, no element found for selector ${selector}`);
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
- const urlPattern = new RegExp("^(https?:\\/\\/)?((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|((\\d{1,3}\\.){3}\\d{1,3}))(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*(\\?[;&a-z\\d%_.~+=-]*)?(\\#[-a-z\\d_]*)?$", "i");
154
- return urlPattern.test(url.trim());
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", "options"],
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({ port: 8080 });
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
- SMARTUI_LOG_LEVEL,
369
- SMARTUI_DEBUG
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
- SMARTUI_LOG_LEVEL,
375
- SMARTUI_DEBUG
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.SMARTUI_DEBUG === "true" ? "debug" : void 0;
387
- return debug || env.SMARTUI_LOG_LEVEL || "info";
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
- if (logContext && Object.keys(logContext).length) {
396
- contextString = Object.values(logContext).join(" | ");
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
- let message = `[${contextString}:${info.level}] `;
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.File({ filename: "smartui.log" })]
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
- if (error.code === "EADDRINUSE") {
420
- task.output = chalk__default.default.gray(`port 8080 is already in use`);
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.message);
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.5";
508
- var HTTP_SCHEME = "https:";
509
- var HTTP_SCHEME_PREFIX = "https://";
510
- var WWW = "www.";
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.message);
898
+ ctx2.log.debug(error);
843
899
  task.output = chalk__default.default.gray(error.message);
844
- throw new Error("Finalize build error");
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
- console.log(`Error: Command not found "${execCommand[0]}"`);
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
- console.log("\nRefer docs: https://www.lambdatest.com/support/docs/smart-visual-regression-testing/");
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
- if (screenshot.url) {
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
- // src/index.ts
1049
- commander_default.parse();
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
+ })();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lambdatest/smartui-cli",
3
- "version": "2.0.5",
3
+ "version": "2.0.7",
4
4
  "description": "A command line interface (CLI) to run SmartUI tests on LambdaTest",
5
5
  "files": [
6
6
  "dist/**/*"