@lambdatest/smartui-cli 3.0.11 → 3.0.12

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 +461 -367
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -4,11 +4,10 @@
4
4
  var commander = require('commander');
5
5
  var which = require('which');
6
6
  var listr2 = require('listr2');
7
- var chalk8 = require('chalk');
7
+ var chalk7 = require('chalk');
8
8
  var path2 = require('path');
9
9
  var fastify = require('fastify');
10
10
  var fs5 = require('fs');
11
- var test = require('@playwright/test');
12
11
  var Ajv = require('ajv');
13
12
  var addErrors = require('ajv-errors');
14
13
  var winston = require('winston');
@@ -16,11 +15,12 @@ var FormData = require('form-data');
16
15
  var axios = require('axios');
17
16
  var child_process = require('child_process');
18
17
  var spawn = require('cross-spawn');
18
+ var test = require('@playwright/test');
19
19
 
20
20
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
21
21
 
22
22
  var which__default = /*#__PURE__*/_interopDefault(which);
23
- var chalk8__default = /*#__PURE__*/_interopDefault(chalk8);
23
+ var chalk7__default = /*#__PURE__*/_interopDefault(chalk7);
24
24
  var path2__default = /*#__PURE__*/_interopDefault(path2);
25
25
  var fastify__default = /*#__PURE__*/_interopDefault(fastify);
26
26
  var fs5__default = /*#__PURE__*/_interopDefault(fs5);
@@ -315,327 +315,7 @@ var constants_default = {
315
315
  }
316
316
  };
317
317
 
318
- // src/lib/utils.ts
319
- function delDir(dir) {
320
- if (fs5__default.default.existsSync(dir)) {
321
- fs5__default.default.rmSync(dir, { recursive: true });
322
- }
323
- }
324
- function scrollToBottomAndBackToTop({
325
- frequency = 100,
326
- timing = 8,
327
- remoteWindow = window
328
- } = {}) {
329
- return new Promise((resolve) => {
330
- let scrolls = 1;
331
- let scrollLength = remoteWindow.document.body.scrollHeight / frequency;
332
- (function scroll() {
333
- let scrollBy = scrollLength * scrolls;
334
- remoteWindow.setTimeout(() => {
335
- remoteWindow.scrollTo(0, scrollBy);
336
- if (scrolls < frequency) {
337
- scrolls += 1;
338
- scroll();
339
- }
340
- if (scrolls === frequency) {
341
- remoteWindow.setTimeout(() => {
342
- remoteWindow.scrollTo(0, 0);
343
- resolve();
344
- }, timing);
345
- }
346
- }, timing);
347
- })();
348
- });
349
- }
350
- function launchBrowsers(ctx) {
351
- return __async(this, null, function* () {
352
- let browsers = {};
353
- let launchOptions = { headless: true };
354
- if (ctx.config.web) {
355
- for (const browser of ctx.config.web.browsers) {
356
- switch (browser) {
357
- case constants_default.CHROME:
358
- browsers[constants_default.CHROME] = yield test.chromium.launch(launchOptions);
359
- break;
360
- case constants_default.SAFARI:
361
- browsers[constants_default.SAFARI] = yield test.webkit.launch(launchOptions);
362
- break;
363
- case constants_default.FIREFOX:
364
- browsers[constants_default.FIREFOX] = yield test.firefox.launch(launchOptions);
365
- break;
366
- case constants_default.EDGE:
367
- browsers[constants_default.EDGE] = yield test.chromium.launch(__spreadValues({ channel: constants_default.EDGE_CHANNEL }, launchOptions));
368
- break;
369
- }
370
- }
371
- }
372
- if (ctx.config.mobile) {
373
- for (const device of ctx.config.mobile.devices) {
374
- if (constants_default.SUPPORTED_MOBILE_DEVICES[device].os === "android" && !browsers[constants_default.CHROME])
375
- browsers[constants_default.CHROME] = yield test.chromium.launch(launchOptions);
376
- else if (constants_default.SUPPORTED_MOBILE_DEVICES[device].os === "ios" && !browsers[constants_default.SAFARI])
377
- browsers[constants_default.SAFARI] = yield test.webkit.launch(launchOptions);
378
- }
379
- }
380
- return browsers;
381
- });
382
- }
383
- function closeBrowsers(browsers) {
384
- return __async(this, null, function* () {
385
- var _a;
386
- for (const browserName of Object.keys(browsers))
387
- yield (_a = browsers[browserName]) == null ? void 0 : _a.close();
388
- });
389
- }
390
- function getWebRenderViewports(ctx) {
391
- let webRenderViewports = [];
392
- if (ctx.config.web) {
393
- for (const viewport of ctx.config.web.viewports) {
394
- webRenderViewports.push({
395
- viewport,
396
- viewportString: `${viewport.width}${viewport.height ? "x" + viewport.height : ""}`,
397
- fullPage: viewport.height ? false : true,
398
- device: false
399
- });
400
- }
401
- }
402
- return webRenderViewports;
403
- }
404
- function getMobileRenderViewports(ctx) {
405
- var _a;
406
- let mobileRenderViewports = {};
407
- mobileRenderViewports[constants_default.MOBILE_OS_IOS] = [];
408
- mobileRenderViewports[constants_default.MOBILE_OS_ANDROID] = [];
409
- if (ctx.config.mobile) {
410
- for (const device of ctx.config.mobile.devices) {
411
- let os = constants_default.SUPPORTED_MOBILE_DEVICES[device].os;
412
- let { width, height } = constants_default.SUPPORTED_MOBILE_DEVICES[device].viewport;
413
- let portrait = ctx.config.mobile.orientation === constants_default.MOBILE_ORIENTATION_PORTRAIT ? true : false;
414
- (_a = mobileRenderViewports[os]) == null ? void 0 : _a.push({
415
- viewport: { width: portrait ? width : height, height: portrait ? height : width },
416
- viewportString: `${device} (${ctx.config.mobile.orientation})`,
417
- fullPage: ctx.config.mobile.fullPage,
418
- device: true,
419
- os
420
- });
421
- }
422
- }
423
- return mobileRenderViewports;
424
- }
425
- function getRenderViewports(ctx) {
426
- let mobileRenderViewports = getMobileRenderViewports(ctx);
427
- return [
428
- ...getWebRenderViewports(ctx),
429
- ...mobileRenderViewports[constants_default.MOBILE_OS_IOS],
430
- ...mobileRenderViewports[constants_default.MOBILE_OS_ANDROID]
431
- ];
432
- }
433
- var MAX_RESOURCE_SIZE = 15 * 1024 ** 2;
434
- var ALLOWED_RESOURCES = ["document", "stylesheet", "image", "media", "font", "other"];
435
- var ALLOWED_STATUSES = [200, 201];
436
- var REQUEST_TIMEOUT = 1e4;
437
- var MIN_VIEWPORT_HEIGHT = 1080;
438
- var processSnapshot_default = (snapshot, ctx) => __async(void 0, null, function* () {
439
- var _a;
440
- ctx.log.debug(`Processing snapshot ${snapshot.name}`);
441
- let launchOptions = { headless: true };
442
- let contextOptions = {
443
- javaScriptEnabled: ctx.config.enableJavaScript,
444
- userAgent: constants_default.CHROME_USER_AGENT
445
- };
446
- if (!((_a = ctx.browser) == null ? void 0 : _a.isConnected())) {
447
- if (ctx.env.HTTP_PROXY || ctx.env.HTTPS_PROXY)
448
- launchOptions.proxy = { server: ctx.env.HTTP_PROXY || ctx.env.HTTPS_PROXY };
449
- ctx.browser = yield test.chromium.launch(launchOptions);
450
- ctx.log.debug(`Chromium launched with options ${JSON.stringify(launchOptions)}`);
451
- }
452
- const context = yield ctx.browser.newContext(contextOptions);
453
- ctx.log.debug(`Browser context created with options ${JSON.stringify(contextOptions)}`);
454
- const page = yield context.newPage();
455
- let cache = {};
456
- yield page.route("**/*", (route, request) => __async(void 0, null, function* () {
457
- const requestUrl = request.url();
458
- const requestHostname = new URL(requestUrl).hostname;
459
- try {
460
- if (/\.(mp3|mp4|wav|ogg|webm)$/i.test(request.url())) {
461
- throw new Error("resource type mp3/mp4/wav/ogg/webm");
462
- }
463
- ctx.config.allowedHostnames.push(new URL(snapshot.url).hostname);
464
- if (ctx.config.enableJavaScript)
465
- ALLOWED_RESOURCES.push("script");
466
- const response = yield page.request.fetch(request, { timeout: REQUEST_TIMEOUT });
467
- const body = yield response.body();
468
- if (!body) {
469
- ctx.log.debug(`Handling request ${requestUrl}
470
- - skipping no response`);
471
- } else if (!body.length) {
472
- ctx.log.debug(`Handling request ${requestUrl}
473
- - skipping empty response`);
474
- } else if (requestUrl === snapshot.url) {
475
- ctx.log.debug(`Handling request ${requestUrl}
476
- - skipping root resource`);
477
- } else if (!ctx.config.allowedHostnames.includes(requestHostname)) {
478
- ctx.log.debug(`Handling request ${requestUrl}
479
- - skipping remote resource`);
480
- } else if (cache[requestUrl]) {
481
- ctx.log.debug(`Handling request ${requestUrl}
482
- - skipping already cached resource`);
483
- } else if (body.length > MAX_RESOURCE_SIZE) {
484
- ctx.log.debug(`Handling request ${requestUrl}
485
- - skipping resource larger than 15MB`);
486
- } else if (!ALLOWED_STATUSES.includes(response.status())) {
487
- ctx.log.debug(`Handling request ${requestUrl}
488
- - skipping disallowed status [${response.status()}]`);
489
- } else if (!ALLOWED_RESOURCES.includes(request.resourceType())) {
490
- ctx.log.debug(`Handling request ${requestUrl}
491
- - skipping disallowed resource type [${request.resourceType()}]`);
492
- } else {
493
- ctx.log.debug(`Handling request ${requestUrl}
494
- - content-type ${response.headers()["content-type"]}`);
495
- cache[requestUrl] = {
496
- body: body.toString("base64"),
497
- type: response.headers()["content-type"]
498
- };
499
- }
500
- route.fulfill({
501
- status: response.status(),
502
- headers: response.headers(),
503
- body
504
- });
505
- } catch (error) {
506
- ctx.log.debug(`Handling request ${requestUrl}
507
- - aborted due to ${error.message}`);
508
- route.abort();
509
- }
510
- }));
511
- let options = snapshot.options;
512
- let optionWarnings = /* @__PURE__ */ new Set();
513
- let processedOptions = {};
514
- let selectors = [];
515
- let ignoreOrSelectDOM;
516
- let ignoreOrSelectBoxes;
517
- if (options && Object.keys(options).length) {
518
- ctx.log.debug(`Snapshot options: ${JSON.stringify(options)}`);
519
- const isNotAllEmpty = (obj) => {
520
- var _a2;
521
- for (let key in obj)
522
- if ((_a2 = obj[key]) == null ? void 0 : _a2.length)
523
- return true;
524
- return false;
525
- };
526
- if (options.element && Object.keys(options.element).length) {
527
- if (options.element.id)
528
- processedOptions.element = "#" + options.element.id;
529
- else if (options.element.class)
530
- processedOptions.element = "." + options.element.class;
531
- else if (options.element.cssSelector)
532
- processedOptions.element = options.element.cssSelector;
533
- else if (options.element.xpath)
534
- processedOptions.element = "xpath=" + options.element.xpath;
535
- } else if (options.ignoreDOM && Object.keys(options.ignoreDOM).length && isNotAllEmpty(options.ignoreDOM)) {
536
- processedOptions.ignoreBoxes = {};
537
- ignoreOrSelectDOM = "ignoreDOM";
538
- ignoreOrSelectBoxes = "ignoreBoxes";
539
- } else if (options.selectDOM && Object.keys(options.selectDOM).length && isNotAllEmpty(options.selectDOM)) {
540
- processedOptions.selectBoxes = {};
541
- ignoreOrSelectDOM = "selectDOM";
542
- ignoreOrSelectBoxes = "selectBoxes";
543
- }
544
- if (ignoreOrSelectDOM) {
545
- for (const [key, value] of Object.entries(options[ignoreOrSelectDOM])) {
546
- switch (key) {
547
- case "id":
548
- selectors.push(...value.map((e) => "#" + e));
549
- break;
550
- case "class":
551
- selectors.push(...value.map((e) => "." + e));
552
- break;
553
- case "xpath":
554
- selectors.push(...value.map((e) => "xpath=" + e));
555
- break;
556
- case "cssSelector":
557
- selectors.push(...value);
558
- break;
559
- }
560
- }
561
- }
562
- }
563
- let navigated = false;
564
- let renderViewports = getRenderViewports(ctx);
565
- for (const { viewport, viewportString, fullPage } of renderViewports) {
566
- yield page.setViewportSize({ width: viewport.width, height: viewport.height || MIN_VIEWPORT_HEIGHT });
567
- ctx.log.debug(`Page resized to ${viewport.width}x${viewport.height || MIN_VIEWPORT_HEIGHT}`);
568
- if (!navigated) {
569
- try {
570
- yield page.goto(snapshot.url, { waitUntil: "domcontentloaded" });
571
- yield new Promise((r) => setTimeout(r, 1250));
572
- if (ctx.config.waitForTimeout)
573
- yield page.waitForTimeout(ctx.config.waitForTimeout);
574
- navigated = true;
575
- ctx.log.debug(`Navigated to ${snapshot.url}`);
576
- } catch (error) {
577
- ctx.log.debug(`Navigation to discovery page failed; ${error}`);
578
- throw new Error(error.message);
579
- }
580
- }
581
- if (ctx.config.enableJavaScript && fullPage)
582
- yield page.evaluate(scrollToBottomAndBackToTop);
583
- try {
584
- yield page.waitForLoadState("networkidle", { timeout: 5e3 });
585
- ctx.log.debug("Network idle 500ms");
586
- } catch (error) {
587
- ctx.log.debug(`Network idle failed due to ${error}`);
588
- }
589
- if (processedOptions.element) {
590
- let l = yield page.locator(processedOptions.element).all();
591
- if (l.length === 0) {
592
- throw new Error(`for snapshot ${snapshot.name} viewport ${viewportString}, no element found for selector ${processedOptions.element}`);
593
- } else if (l.length > 1) {
594
- throw new Error(`for snapshot ${snapshot.name} viewport ${viewportString}, multiple elements found for selector ${processedOptions.element}`);
595
- }
596
- } else if (selectors.length) {
597
- let locators = [];
598
- if (!Array.isArray(processedOptions[ignoreOrSelectBoxes][viewportString]))
599
- processedOptions[ignoreOrSelectBoxes][viewportString] = [];
600
- for (const selector of selectors) {
601
- let l = yield page.locator(selector).all();
602
- if (l.length === 0) {
603
- optionWarnings.add(`for snapshot ${snapshot.name} viewport ${viewportString}, no element found for selector ${selector}`);
604
- continue;
605
- }
606
- locators.push(...l);
607
- }
608
- for (const locator of locators) {
609
- let bb = yield locator.boundingBox();
610
- if (bb)
611
- processedOptions[ignoreOrSelectBoxes][viewportString].push({
612
- left: bb.x,
613
- top: bb.y,
614
- right: bb.x + bb.width,
615
- bottom: bb.y + bb.height
616
- });
617
- }
618
- }
619
- }
620
- if (snapshot.dom.resources.length) {
621
- for (let resource of snapshot.dom.resources) {
622
- cache[resource.url] = {
623
- body: resource.content,
624
- type: resource.mimetype
625
- };
626
- }
627
- }
628
- return {
629
- processedSnapshot: {
630
- name: snapshot.name,
631
- url: snapshot.url,
632
- dom: Buffer.from(snapshot.dom.html).toString("base64"),
633
- resources: cache,
634
- options: processedOptions
635
- },
636
- warnings: [...optionWarnings, ...snapshot.dom.warnings]
637
- };
638
- });
318
+ // src/lib/schemaValidation.ts
639
319
  var ajv = new Ajv__default.default({ allErrors: true });
640
320
  ajv.addFormat("web-url", {
641
321
  type: "string",
@@ -962,32 +642,22 @@ var server_default = (ctx) => __async(void 0, null, function* () {
962
642
  reply.code(200).send({ data: { dom: SMARTUI_DOM } });
963
643
  });
964
644
  server.post("/snapshot", opts, (request, reply) => __async(void 0, null, function* () {
645
+ var _a;
965
646
  let replyCode;
966
647
  let replyBody;
967
648
  try {
968
649
  let { snapshot, testType } = request.body;
969
650
  if (!validateSnapshot(snapshot))
970
651
  throw new Error(validateSnapshot.errors[0].message);
971
- let { processedSnapshot, warnings } = yield processSnapshot_default(snapshot, ctx);
972
- yield ctx.client.uploadSnapshot(ctx.build.id, processedSnapshot, testType, ctx.log);
973
- ctx.totalSnapshots++;
652
+ ctx.testType = testType;
653
+ (_a = ctx.snapshotQueue) == null ? void 0 : _a.enqueue(snapshot);
974
654
  replyCode = 200;
975
- replyBody = { data: { message: "success", warnings } };
655
+ replyBody = { data: { message: "success", warnings: [] } };
976
656
  } catch (error) {
977
657
  ctx.log.debug(`snapshot failed; ${error}`);
978
658
  replyCode = 500;
979
659
  replyBody = { error: { message: error.message } };
980
660
  }
981
- if (ctx.browser) {
982
- for (let context of ctx.browser.contexts()) {
983
- for (let page of context.pages()) {
984
- yield page.close();
985
- ctx.log.debug(`Closed browser page`);
986
- }
987
- yield context.close();
988
- ctx.log.debug(`Closed browser context`);
989
- }
990
- }
991
661
  return reply.code(replyCode).send(replyBody);
992
662
  }));
993
663
  yield server.listen({ port: ctx.options.port });
@@ -1048,13 +718,13 @@ var logger = winston.createLogger({
1048
718
  let message = typeof info.message === "object" ? JSON.stringify(info.message) : info.message;
1049
719
  switch (info.level) {
1050
720
  case "debug":
1051
- message = chalk8__default.default.blue(message);
721
+ message = chalk7__default.default.blue(message);
1052
722
  break;
1053
723
  case "warn":
1054
- message = chalk8__default.default.yellow(message);
724
+ message = chalk7__default.default.yellow(message);
1055
725
  break;
1056
726
  case "error":
1057
- message = chalk8__default.default.red(message);
727
+ message = chalk7__default.default.red(message);
1058
728
  break;
1059
729
  }
1060
730
  return info.level === "info" ? message : `[${contextString}:${info.level}] ` + message;
@@ -1073,11 +743,11 @@ var startServer_default = (ctx) => {
1073
743
  updateLogContext({ task: "startServer" });
1074
744
  try {
1075
745
  ctx2.server = yield server_default(ctx2);
1076
- task.output = chalk8__default.default.gray(`listening on port ${(_a = ctx2.server.addresses()[0]) == null ? void 0 : _a.port}`);
746
+ task.output = chalk7__default.default.gray(`listening on port ${(_a = ctx2.server.addresses()[0]) == null ? void 0 : _a.port}`);
1077
747
  task.title = "SmartUI started";
1078
748
  } catch (error) {
1079
749
  ctx2.log.debug(error);
1080
- task.output = chalk8__default.default.gray(error.message);
750
+ task.output = chalk7__default.default.gray(error.message);
1081
751
  throw new Error("SmartUI server setup failed");
1082
752
  }
1083
753
  }),
@@ -1091,11 +761,11 @@ var auth_default = (ctx) => {
1091
761
  updateLogContext({ task: "auth" });
1092
762
  try {
1093
763
  yield ctx2.client.auth(ctx2.log);
1094
- task.output = chalk8__default.default.gray(`using project token '******#${ctx2.env.PROJECT_TOKEN.split("#").pop()}'`);
764
+ task.output = chalk7__default.default.gray(`using project token '******#${ctx2.env.PROJECT_TOKEN.split("#").pop()}'`);
1095
765
  task.title = "Authenticated with SmartUI";
1096
766
  } catch (error) {
1097
767
  ctx2.log.debug(error);
1098
- task.output = chalk8__default.default.gray(error.message);
768
+ task.output = chalk7__default.default.gray(error.message);
1099
769
  throw new Error("Authentication failed");
1100
770
  }
1101
771
  }),
@@ -1104,7 +774,7 @@ var auth_default = (ctx) => {
1104
774
  };
1105
775
 
1106
776
  // package.json
1107
- var version = "3.0.11";
777
+ var version = "3.0.12";
1108
778
  var package_default = {
1109
779
  name: "@lambdatest/smartui-cli",
1110
780
  version,
@@ -1214,19 +884,19 @@ var httpClient = class {
1214
884
  params
1215
885
  }, log);
1216
886
  }
1217
- uploadSnapshot(buildId, snapshot, testType, log) {
887
+ uploadSnapshot(ctx, snapshot) {
1218
888
  return this.request({
1219
- url: `/builds/${buildId}/snapshot`,
889
+ url: `/builds/${ctx.build.id}/snapshot`,
1220
890
  method: "POST",
1221
891
  headers: { "Content-Type": "application/json" },
1222
892
  data: {
1223
893
  snapshot,
1224
894
  test: {
1225
- type: testType,
895
+ type: ctx.testType,
1226
896
  source: "cli"
1227
897
  }
1228
898
  }
1229
- }, log);
899
+ }, ctx.log);
1230
900
  }
1231
901
  uploadScreenshot({ id: buildId, name: buildName, baseline }, ssPath, ssName, browserName, viewport, log) {
1232
902
  browserName = browserName === constants_default.SAFARI ? constants_default.WEBKIT : browserName;
@@ -1423,11 +1093,11 @@ var getGitInfo_default = (ctx) => {
1423
1093
  }
1424
1094
  try {
1425
1095
  ctx2.git = git_default(ctx2);
1426
- task.output = chalk8__default.default.gray(`branch: ${ctx2.git.branch}, commit: ${ctx2.git.commitId}, author: ${ctx2.git.commitAuthor}`);
1096
+ task.output = chalk7__default.default.gray(`branch: ${ctx2.git.branch}, commit: ${ctx2.git.commitId}, author: ${ctx2.git.commitAuthor}`);
1427
1097
  task.title = "Fetched git information";
1428
1098
  } catch (error) {
1429
1099
  ctx2.log.debug(error);
1430
- task.output = chalk8__default.default.gray(`${error.message}`);
1100
+ task.output = chalk7__default.default.gray(`${error.message}`);
1431
1101
  throw new Error("Error fetching git repo details");
1432
1102
  }
1433
1103
  }),
@@ -1447,11 +1117,11 @@ var createBuild_default = (ctx) => {
1447
1117
  url: resp.data.buildURL,
1448
1118
  baseline: resp.data.baseline
1449
1119
  };
1450
- task.output = chalk8__default.default.gray(`build id: ${resp.data.buildId}`);
1120
+ task.output = chalk7__default.default.gray(`build id: ${resp.data.buildId}`);
1451
1121
  task.title = "SmartUI build created";
1452
1122
  } catch (error) {
1453
1123
  ctx2.log.debug(error);
1454
- task.output = chalk8__default.default.gray(error.message);
1124
+ task.output = chalk7__default.default.gray(error.message);
1455
1125
  throw new Error("SmartUI build creation failed");
1456
1126
  }
1457
1127
  }),
@@ -1470,13 +1140,13 @@ var exec_default = (ctx) => {
1470
1140
  let totalOutput = "";
1471
1141
  const output = listr2.createWritable((chunk) => {
1472
1142
  totalOutput += chunk;
1473
- task.output = chalk8__default.default.gray(totalOutput);
1143
+ task.output = chalk7__default.default.gray(totalOutput);
1474
1144
  });
1475
1145
  (_b = childProcess.stdout) == null ? void 0 : _b.pipe(output);
1476
1146
  (_c = childProcess.stderr) == null ? void 0 : _c.pipe(output);
1477
1147
  childProcess.on("error", (error) => {
1478
1148
  var _a3;
1479
- task.output = chalk8__default.default.gray(`error: ${error.message}`);
1149
+ task.output = chalk7__default.default.gray(`error: ${error.message}`);
1480
1150
  throw new Error(`Execution of '${(_a3 = ctx2.args.execCommand) == null ? void 0 : _a3.join(" ")}' failed`);
1481
1151
  });
1482
1152
  childProcess.on("close", (code, signal) => __async(void 0, null, function* () {
@@ -1494,6 +1164,46 @@ var exec_default = (ctx) => {
1494
1164
  exitOnError: false
1495
1165
  };
1496
1166
  };
1167
+ var processSnapshot_default = (ctx) => {
1168
+ return {
1169
+ title: `Processing snapshots`,
1170
+ task: (ctx2, task) => __async(void 0, null, function* () {
1171
+ var _a;
1172
+ try {
1173
+ yield new Promise((resolve) => {
1174
+ let output2 = "";
1175
+ const intervalId = setInterval(() => {
1176
+ var _a2, _b, _c;
1177
+ if (((_a2 = ctx2.snapshotQueue) == null ? void 0 : _a2.isEmpty()) && !((_b = ctx2.snapshotQueue) == null ? void 0 : _b.isProcessing())) {
1178
+ clearInterval(intervalId);
1179
+ resolve();
1180
+ } else {
1181
+ task.title = `Processing snapshot ${(_c = ctx2.snapshotQueue) == null ? void 0 : _c.getProcessingSnapshot()}`;
1182
+ }
1183
+ }, 500);
1184
+ });
1185
+ let output = "";
1186
+ for (let snapshot of (_a = ctx2.snapshotQueue) == null ? void 0 : _a.getProcessedSnapshots()) {
1187
+ if (snapshot.error)
1188
+ output += `${chalk7__default.default.red("\u2717")} ${chalk7__default.default.gray(`${snapshot.name}
1189
+ [error] ${snapshot.error}`)}
1190
+ `;
1191
+ else
1192
+ output += `${chalk7__default.default.green("\u2713")} ${chalk7__default.default.gray(snapshot.name)}
1193
+ ${snapshot.warnings.length ? chalk7__default.default.gray(`[warning] ${snapshot.warnings.join("\n[warning] ")}
1194
+ `) : ""}`;
1195
+ }
1196
+ task.output = output;
1197
+ task.title = "Processed snapshots";
1198
+ } catch (error) {
1199
+ ctx2.log.debug(error);
1200
+ task.output = chalk7__default.default.gray(error.message);
1201
+ throw new Error("Processing of snapshots failed");
1202
+ }
1203
+ }),
1204
+ rendererOptions: { persistentOutput: true }
1205
+ };
1206
+ };
1497
1207
  var finalizeBuild_default = (ctx) => {
1498
1208
  return {
1499
1209
  title: `Finalizing build`,
@@ -1502,17 +1212,397 @@ var finalizeBuild_default = (ctx) => {
1502
1212
  try {
1503
1213
  yield new Promise((resolve) => setTimeout(resolve, 2e3));
1504
1214
  yield ctx2.client.finalizeBuild(ctx2.build.id, ctx2.totalSnapshots, ctx2.log);
1505
- task.output = chalk8__default.default.gray(`build url: ${ctx2.build.url}`);
1215
+ task.output = chalk7__default.default.gray(`build url: ${ctx2.build.url}`);
1506
1216
  task.title = "Finalized build";
1507
1217
  } catch (error) {
1508
1218
  ctx2.log.debug(error);
1509
- task.output = chalk8__default.default.gray(error.message);
1219
+ task.output = chalk7__default.default.gray(error.message);
1510
1220
  throw new Error("Finalize build failed");
1511
1221
  }
1512
1222
  }),
1513
1223
  rendererOptions: { persistentOutput: true }
1514
1224
  };
1515
1225
  };
1226
+ function delDir(dir) {
1227
+ if (fs5__default.default.existsSync(dir)) {
1228
+ fs5__default.default.rmSync(dir, { recursive: true });
1229
+ }
1230
+ }
1231
+ function scrollToBottomAndBackToTop({
1232
+ frequency = 100,
1233
+ timing = 8,
1234
+ remoteWindow = window
1235
+ } = {}) {
1236
+ return new Promise((resolve) => {
1237
+ let scrolls = 1;
1238
+ let scrollLength = remoteWindow.document.body.scrollHeight / frequency;
1239
+ (function scroll() {
1240
+ let scrollBy = scrollLength * scrolls;
1241
+ remoteWindow.setTimeout(() => {
1242
+ remoteWindow.scrollTo(0, scrollBy);
1243
+ if (scrolls < frequency) {
1244
+ scrolls += 1;
1245
+ scroll();
1246
+ }
1247
+ if (scrolls === frequency) {
1248
+ remoteWindow.setTimeout(() => {
1249
+ remoteWindow.scrollTo(0, 0);
1250
+ resolve();
1251
+ }, timing);
1252
+ }
1253
+ }, timing);
1254
+ })();
1255
+ });
1256
+ }
1257
+ function launchBrowsers(ctx) {
1258
+ return __async(this, null, function* () {
1259
+ let browsers = {};
1260
+ let launchOptions = { headless: true };
1261
+ if (ctx.config.web) {
1262
+ for (const browser of ctx.config.web.browsers) {
1263
+ switch (browser) {
1264
+ case constants_default.CHROME:
1265
+ browsers[constants_default.CHROME] = yield test.chromium.launch(launchOptions);
1266
+ break;
1267
+ case constants_default.SAFARI:
1268
+ browsers[constants_default.SAFARI] = yield test.webkit.launch(launchOptions);
1269
+ break;
1270
+ case constants_default.FIREFOX:
1271
+ browsers[constants_default.FIREFOX] = yield test.firefox.launch(launchOptions);
1272
+ break;
1273
+ case constants_default.EDGE:
1274
+ browsers[constants_default.EDGE] = yield test.chromium.launch(__spreadValues({ channel: constants_default.EDGE_CHANNEL }, launchOptions));
1275
+ break;
1276
+ }
1277
+ }
1278
+ }
1279
+ if (ctx.config.mobile) {
1280
+ for (const device of ctx.config.mobile.devices) {
1281
+ if (constants_default.SUPPORTED_MOBILE_DEVICES[device].os === "android" && !browsers[constants_default.CHROME])
1282
+ browsers[constants_default.CHROME] = yield test.chromium.launch(launchOptions);
1283
+ else if (constants_default.SUPPORTED_MOBILE_DEVICES[device].os === "ios" && !browsers[constants_default.SAFARI])
1284
+ browsers[constants_default.SAFARI] = yield test.webkit.launch(launchOptions);
1285
+ }
1286
+ }
1287
+ return browsers;
1288
+ });
1289
+ }
1290
+ function closeBrowsers(browsers) {
1291
+ return __async(this, null, function* () {
1292
+ var _a;
1293
+ for (const browserName of Object.keys(browsers))
1294
+ yield (_a = browsers[browserName]) == null ? void 0 : _a.close();
1295
+ });
1296
+ }
1297
+ function getWebRenderViewports(ctx) {
1298
+ let webRenderViewports = [];
1299
+ if (ctx.config.web) {
1300
+ for (const viewport of ctx.config.web.viewports) {
1301
+ webRenderViewports.push({
1302
+ viewport,
1303
+ viewportString: `${viewport.width}${viewport.height ? "x" + viewport.height : ""}`,
1304
+ fullPage: viewport.height ? false : true,
1305
+ device: false
1306
+ });
1307
+ }
1308
+ }
1309
+ return webRenderViewports;
1310
+ }
1311
+ function getMobileRenderViewports(ctx) {
1312
+ var _a;
1313
+ let mobileRenderViewports = {};
1314
+ mobileRenderViewports[constants_default.MOBILE_OS_IOS] = [];
1315
+ mobileRenderViewports[constants_default.MOBILE_OS_ANDROID] = [];
1316
+ if (ctx.config.mobile) {
1317
+ for (const device of ctx.config.mobile.devices) {
1318
+ let os = constants_default.SUPPORTED_MOBILE_DEVICES[device].os;
1319
+ let { width, height } = constants_default.SUPPORTED_MOBILE_DEVICES[device].viewport;
1320
+ let portrait = ctx.config.mobile.orientation === constants_default.MOBILE_ORIENTATION_PORTRAIT ? true : false;
1321
+ (_a = mobileRenderViewports[os]) == null ? void 0 : _a.push({
1322
+ viewport: { width: portrait ? width : height, height: portrait ? height : width },
1323
+ viewportString: `${device} (${ctx.config.mobile.orientation})`,
1324
+ fullPage: ctx.config.mobile.fullPage,
1325
+ device: true,
1326
+ os
1327
+ });
1328
+ }
1329
+ }
1330
+ return mobileRenderViewports;
1331
+ }
1332
+ function getRenderViewports(ctx) {
1333
+ let mobileRenderViewports = getMobileRenderViewports(ctx);
1334
+ return [
1335
+ ...getWebRenderViewports(ctx),
1336
+ ...mobileRenderViewports[constants_default.MOBILE_OS_IOS],
1337
+ ...mobileRenderViewports[constants_default.MOBILE_OS_ANDROID]
1338
+ ];
1339
+ }
1340
+ var MAX_RESOURCE_SIZE = 15 * 1024 ** 2;
1341
+ var ALLOWED_RESOURCES = ["document", "stylesheet", "image", "media", "font", "other"];
1342
+ var ALLOWED_STATUSES = [200, 201];
1343
+ var REQUEST_TIMEOUT = 1e4;
1344
+ var MIN_VIEWPORT_HEIGHT = 1080;
1345
+ var Queue = class {
1346
+ constructor(ctx) {
1347
+ this.snapshots = [];
1348
+ this.processedSnapshots = [];
1349
+ this.processing = false;
1350
+ this.processingSnapshot = "";
1351
+ this.ctx = ctx;
1352
+ }
1353
+ enqueue(item) {
1354
+ this.snapshots.push(item);
1355
+ if (!this.processing) {
1356
+ this.processing = true;
1357
+ this.processNext();
1358
+ }
1359
+ }
1360
+ processNext() {
1361
+ return __async(this, null, function* () {
1362
+ if (!this.isEmpty()) {
1363
+ const snapshot = this.snapshots.shift();
1364
+ try {
1365
+ this.processingSnapshot = snapshot == null ? void 0 : snapshot.name;
1366
+ let { processedSnapshot, warnings } = yield processSnapshot(snapshot, this.ctx);
1367
+ yield this.ctx.client.uploadSnapshot(this.ctx, processedSnapshot);
1368
+ this.ctx.totalSnapshots++;
1369
+ this.processedSnapshots.push({ name: snapshot.name, warnings });
1370
+ } catch (error) {
1371
+ this.ctx.log.debug(`snapshot failed; ${error}`);
1372
+ this.processedSnapshots.push({ name: snapshot.name, error: error.message });
1373
+ }
1374
+ if (this.ctx.browser) {
1375
+ for (let context of this.ctx.browser.contexts()) {
1376
+ for (let page of context.pages()) {
1377
+ yield page.close();
1378
+ this.ctx.log.debug(`Closed browser page for snapshot ${snapshot.name}`);
1379
+ }
1380
+ yield context.close();
1381
+ this.ctx.log.debug(`Closed browser context for snapshot ${snapshot.name}`);
1382
+ }
1383
+ }
1384
+ this.processNext();
1385
+ } else {
1386
+ this.processing = false;
1387
+ }
1388
+ });
1389
+ }
1390
+ isProcessing() {
1391
+ return this.processing;
1392
+ }
1393
+ getProcessingSnapshot() {
1394
+ return this.processingSnapshot;
1395
+ }
1396
+ getProcessedSnapshots() {
1397
+ return this.processedSnapshots;
1398
+ }
1399
+ isEmpty() {
1400
+ return this.snapshots.length ? false : true;
1401
+ }
1402
+ };
1403
+ function processSnapshot(snapshot, ctx) {
1404
+ return __async(this, null, function* () {
1405
+ var _a;
1406
+ ctx.log.debug(`Processing snapshot ${snapshot.name}`);
1407
+ let launchOptions = { headless: true };
1408
+ let contextOptions = {
1409
+ javaScriptEnabled: ctx.config.enableJavaScript,
1410
+ userAgent: constants_default.CHROME_USER_AGENT
1411
+ };
1412
+ if (!((_a = ctx.browser) == null ? void 0 : _a.isConnected())) {
1413
+ if (ctx.env.HTTP_PROXY || ctx.env.HTTPS_PROXY)
1414
+ launchOptions.proxy = { server: ctx.env.HTTP_PROXY || ctx.env.HTTPS_PROXY };
1415
+ ctx.browser = yield test.chromium.launch(launchOptions);
1416
+ ctx.log.debug(`Chromium launched with options ${JSON.stringify(launchOptions)}`);
1417
+ }
1418
+ const context = yield ctx.browser.newContext(contextOptions);
1419
+ ctx.log.debug(`Browser context created with options ${JSON.stringify(contextOptions)}`);
1420
+ const page = yield context.newPage();
1421
+ let cache = {};
1422
+ yield page.route("**/*", (route, request) => __async(this, null, function* () {
1423
+ const requestUrl = request.url();
1424
+ const requestHostname = new URL(requestUrl).hostname;
1425
+ try {
1426
+ if (/\.(mp3|mp4|wav|ogg|webm)$/i.test(request.url())) {
1427
+ throw new Error("resource type mp3/mp4/wav/ogg/webm");
1428
+ }
1429
+ ctx.config.allowedHostnames.push(new URL(snapshot.url).hostname);
1430
+ if (ctx.config.enableJavaScript)
1431
+ ALLOWED_RESOURCES.push("script");
1432
+ const response = yield page.request.fetch(request, { timeout: REQUEST_TIMEOUT });
1433
+ const body = yield response.body();
1434
+ if (!body) {
1435
+ ctx.log.debug(`Handling request ${requestUrl}
1436
+ - skipping no response`);
1437
+ } else if (!body.length) {
1438
+ ctx.log.debug(`Handling request ${requestUrl}
1439
+ - skipping empty response`);
1440
+ } else if (requestUrl === snapshot.url) {
1441
+ ctx.log.debug(`Handling request ${requestUrl}
1442
+ - skipping root resource`);
1443
+ } else if (!ctx.config.allowedHostnames.includes(requestHostname)) {
1444
+ ctx.log.debug(`Handling request ${requestUrl}
1445
+ - skipping remote resource`);
1446
+ } else if (cache[requestUrl]) {
1447
+ ctx.log.debug(`Handling request ${requestUrl}
1448
+ - skipping already cached resource`);
1449
+ } else if (body.length > MAX_RESOURCE_SIZE) {
1450
+ ctx.log.debug(`Handling request ${requestUrl}
1451
+ - skipping resource larger than 15MB`);
1452
+ } else if (!ALLOWED_STATUSES.includes(response.status())) {
1453
+ ctx.log.debug(`Handling request ${requestUrl}
1454
+ - skipping disallowed status [${response.status()}]`);
1455
+ } else if (!ALLOWED_RESOURCES.includes(request.resourceType())) {
1456
+ ctx.log.debug(`Handling request ${requestUrl}
1457
+ - skipping disallowed resource type [${request.resourceType()}]`);
1458
+ } else {
1459
+ ctx.log.debug(`Handling request ${requestUrl}
1460
+ - content-type ${response.headers()["content-type"]}`);
1461
+ cache[requestUrl] = {
1462
+ body: body.toString("base64"),
1463
+ type: response.headers()["content-type"]
1464
+ };
1465
+ }
1466
+ route.fulfill({
1467
+ status: response.status(),
1468
+ headers: response.headers(),
1469
+ body
1470
+ });
1471
+ } catch (error) {
1472
+ ctx.log.debug(`Handling request ${requestUrl}
1473
+ - aborted due to ${error.message}`);
1474
+ route.abort();
1475
+ }
1476
+ }));
1477
+ let options = snapshot.options;
1478
+ let optionWarnings = /* @__PURE__ */ new Set();
1479
+ let processedOptions = {};
1480
+ let selectors = [];
1481
+ let ignoreOrSelectDOM;
1482
+ let ignoreOrSelectBoxes;
1483
+ if (options && Object.keys(options).length) {
1484
+ ctx.log.debug(`Snapshot options: ${JSON.stringify(options)}`);
1485
+ const isNotAllEmpty = (obj) => {
1486
+ var _a2;
1487
+ for (let key in obj)
1488
+ if ((_a2 = obj[key]) == null ? void 0 : _a2.length)
1489
+ return true;
1490
+ return false;
1491
+ };
1492
+ if (options.element && Object.keys(options.element).length) {
1493
+ if (options.element.id)
1494
+ processedOptions.element = "#" + options.element.id;
1495
+ else if (options.element.class)
1496
+ processedOptions.element = "." + options.element.class;
1497
+ else if (options.element.cssSelector)
1498
+ processedOptions.element = options.element.cssSelector;
1499
+ else if (options.element.xpath)
1500
+ processedOptions.element = "xpath=" + options.element.xpath;
1501
+ } else if (options.ignoreDOM && Object.keys(options.ignoreDOM).length && isNotAllEmpty(options.ignoreDOM)) {
1502
+ processedOptions.ignoreBoxes = {};
1503
+ ignoreOrSelectDOM = "ignoreDOM";
1504
+ ignoreOrSelectBoxes = "ignoreBoxes";
1505
+ } else if (options.selectDOM && Object.keys(options.selectDOM).length && isNotAllEmpty(options.selectDOM)) {
1506
+ processedOptions.selectBoxes = {};
1507
+ ignoreOrSelectDOM = "selectDOM";
1508
+ ignoreOrSelectBoxes = "selectBoxes";
1509
+ }
1510
+ if (ignoreOrSelectDOM) {
1511
+ for (const [key, value] of Object.entries(options[ignoreOrSelectDOM])) {
1512
+ switch (key) {
1513
+ case "id":
1514
+ selectors.push(...value.map((e) => "#" + e));
1515
+ break;
1516
+ case "class":
1517
+ selectors.push(...value.map((e) => "." + e));
1518
+ break;
1519
+ case "xpath":
1520
+ selectors.push(...value.map((e) => "xpath=" + e));
1521
+ break;
1522
+ case "cssSelector":
1523
+ selectors.push(...value);
1524
+ break;
1525
+ }
1526
+ }
1527
+ }
1528
+ }
1529
+ let navigated = false;
1530
+ let renderViewports = getRenderViewports(ctx);
1531
+ for (const { viewport, viewportString, fullPage } of renderViewports) {
1532
+ yield page.setViewportSize({ width: viewport.width, height: viewport.height || MIN_VIEWPORT_HEIGHT });
1533
+ ctx.log.debug(`Page resized to ${viewport.width}x${viewport.height || MIN_VIEWPORT_HEIGHT}`);
1534
+ if (!navigated) {
1535
+ try {
1536
+ yield page.goto(snapshot.url, { waitUntil: "domcontentloaded" });
1537
+ yield new Promise((r) => setTimeout(r, 1250));
1538
+ if (ctx.config.waitForTimeout)
1539
+ yield page.waitForTimeout(ctx.config.waitForTimeout);
1540
+ navigated = true;
1541
+ ctx.log.debug(`Navigated to ${snapshot.url}`);
1542
+ } catch (error) {
1543
+ ctx.log.debug(`Navigation to discovery page failed; ${error}`);
1544
+ throw new Error(error.message);
1545
+ }
1546
+ }
1547
+ if (ctx.config.enableJavaScript && fullPage)
1548
+ yield page.evaluate(scrollToBottomAndBackToTop);
1549
+ try {
1550
+ yield page.waitForLoadState("networkidle", { timeout: 5e3 });
1551
+ ctx.log.debug("Network idle 500ms");
1552
+ } catch (error) {
1553
+ ctx.log.debug(`Network idle failed due to ${error}`);
1554
+ }
1555
+ if (processedOptions.element) {
1556
+ let l = yield page.locator(processedOptions.element).all();
1557
+ if (l.length === 0) {
1558
+ throw new Error(`for snapshot ${snapshot.name} viewport ${viewportString}, no element found for selector ${processedOptions.element}`);
1559
+ } else if (l.length > 1) {
1560
+ throw new Error(`for snapshot ${snapshot.name} viewport ${viewportString}, multiple elements found for selector ${processedOptions.element}`);
1561
+ }
1562
+ } else if (selectors.length) {
1563
+ let locators = [];
1564
+ if (!Array.isArray(processedOptions[ignoreOrSelectBoxes][viewportString]))
1565
+ processedOptions[ignoreOrSelectBoxes][viewportString] = [];
1566
+ for (const selector of selectors) {
1567
+ let l = yield page.locator(selector).all();
1568
+ if (l.length === 0) {
1569
+ optionWarnings.add(`for snapshot ${snapshot.name} viewport ${viewportString}, no element found for selector ${selector}`);
1570
+ continue;
1571
+ }
1572
+ locators.push(...l);
1573
+ }
1574
+ for (const locator of locators) {
1575
+ let bb = yield locator.boundingBox();
1576
+ if (bb)
1577
+ processedOptions[ignoreOrSelectBoxes][viewportString].push({
1578
+ left: bb.x,
1579
+ top: bb.y,
1580
+ right: bb.x + bb.width,
1581
+ bottom: bb.y + bb.height
1582
+ });
1583
+ }
1584
+ }
1585
+ }
1586
+ if (snapshot.dom.resources.length) {
1587
+ for (let resource of snapshot.dom.resources) {
1588
+ cache[resource.url] = {
1589
+ body: resource.content,
1590
+ type: resource.mimetype
1591
+ };
1592
+ }
1593
+ }
1594
+ return {
1595
+ processedSnapshot: {
1596
+ name: snapshot.name,
1597
+ url: snapshot.url,
1598
+ dom: Buffer.from(snapshot.dom.html).toString("base64"),
1599
+ resources: cache,
1600
+ options: processedOptions
1601
+ },
1602
+ warnings: [...optionWarnings, ...snapshot.dom.warnings]
1603
+ };
1604
+ });
1605
+ }
1516
1606
 
1517
1607
  // src/commander/exec.ts
1518
1608
  var command = new commander.Command();
@@ -1525,6 +1615,7 @@ command.name("exec").description("Run test commands around SmartUI").argument("<
1525
1615
  return;
1526
1616
  }
1527
1617
  ctx.args.execCommand = execCommand;
1618
+ ctx.snapshotQueue = new Queue(ctx);
1528
1619
  ctx.totalSnapshots = 0;
1529
1620
  let tasks = new listr2.Listr(
1530
1621
  [
@@ -1533,6 +1624,7 @@ command.name("exec").description("Run test commands around SmartUI").argument("<
1533
1624
  getGitInfo_default(),
1534
1625
  createBuild_default(),
1535
1626
  exec_default(ctx),
1627
+ processSnapshot_default(),
1536
1628
  finalizeBuild_default()
1537
1629
  ],
1538
1630
  {
@@ -1551,8 +1643,10 @@ command.name("exec").description("Run test commands around SmartUI").argument("<
1551
1643
  } catch (error) {
1552
1644
  ctx.log.info("\nRefer docs: https://www.lambdatest.com/support/docs/smart-visual-regression-testing/");
1553
1645
  } finally {
1554
- yield (_a = ctx.server) == null ? void 0 : _a.close();
1555
- yield (_b = ctx.browser) == null ? void 0 : _b.close();
1646
+ yield (_a = ctx.browser) == null ? void 0 : _a.close();
1647
+ ctx.log.debug(`Closed browser`);
1648
+ yield (_b = ctx.server) == null ? void 0 : _b.close();
1649
+ ctx.log.debug(`Closed server`);
1556
1650
  }
1557
1651
  });
1558
1652
  });
@@ -1722,13 +1816,13 @@ function captureScreenshots(ctx) {
1722
1816
  else
1723
1817
  yield captureScreenshotsSync(ctx, staticConfig, browsers);
1724
1818
  delDir(`screenshots/${staticConfig.name.toLowerCase().replace(/\s/g, "_")}`);
1725
- output += `${chalk8__default.default.gray(staticConfig.name)} ${chalk8__default.default.green("\u2713")}
1819
+ output += `${chalk7__default.default.gray(staticConfig.name)} ${chalk7__default.default.green("\u2713")}
1726
1820
  `;
1727
1821
  ctx.task.output = output;
1728
1822
  capturedScreenshots++;
1729
1823
  } catch (error) {
1730
1824
  ctx.log.debug(`screenshot capture failed for ${JSON.stringify(staticConfig)}; error: ${error}`);
1731
- output += `${chalk8__default.default.gray(staticConfig.name)} ${chalk8__default.default.red("\u2717")}
1825
+ output += `${chalk7__default.default.gray(staticConfig.name)} ${chalk7__default.default.red("\u2717")}
1732
1826
  `;
1733
1827
  ctx.task.output = output;
1734
1828
  }
@@ -1752,7 +1846,7 @@ var captureScreenshots_default = (ctx) => {
1752
1846
  task.title = "Screenshots captured successfully";
1753
1847
  } catch (error) {
1754
1848
  ctx2.log.debug(error);
1755
- task.output = chalk8__default.default.gray(`${error.message}`);
1849
+ task.output = chalk7__default.default.gray(`${error.message}`);
1756
1850
  throw new Error("Capturing screenshots failed");
1757
1851
  }
1758
1852
  }),
@@ -1846,7 +1940,7 @@ var uploadFigmaDesigns_default2 = (ctx) => {
1846
1940
  ctx2.log.debug(`Figma designs processed: ${results}`);
1847
1941
  } catch (error) {
1848
1942
  ctx2.log.debug(error);
1849
- task.output = chalk8__default.default.gray(`${error.message}`);
1943
+ task.output = chalk7__default.default.gray(`${error.message}`);
1850
1944
  throw new Error("Uploading Figma designs failed");
1851
1945
  }
1852
1946
  }),
@@ -1916,13 +2010,13 @@ LambdaTest SmartUI CLI v${package_default.version}`);
1916
2010
  log.warn(`This version is deprecated. A new version ${latestVersion} is available!
1917
2011
  `);
1918
2012
  else if (package_default.version !== latestVersion)
1919
- log.info(chalk8__default.default.gray(`A new version ${latestVersion} is available!
2013
+ log.info(chalk7__default.default.gray(`A new version ${latestVersion} is available!
1920
2014
  `));
1921
2015
  else
1922
- log.info(chalk8__default.default.gray("https://www.npmjs.com/package/@lambdatest/smartui-cli\n"));
2016
+ log.info(chalk7__default.default.gray("https://www.npmjs.com/package/@lambdatest/smartui-cli\n"));
1923
2017
  } catch (error) {
1924
2018
  log.debug(error);
1925
- log.info(chalk8__default.default.gray("https://www.npmjs.com/package/@lambdatest/smartui-cli\n"));
2019
+ log.info(chalk7__default.default.gray("https://www.npmjs.com/package/@lambdatest/smartui-cli\n"));
1926
2020
  }
1927
2021
  commander_default.parse();
1928
2022
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lambdatest/smartui-cli",
3
- "version": "3.0.11",
3
+ "version": "3.0.12",
4
4
  "description": "A command line interface (CLI) to run SmartUI tests on LambdaTest",
5
5
  "files": [
6
6
  "dist/**/*"