@lambdatest/smartui-cli 4.0.14 → 4.0.16

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 +402 -22
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -378,7 +378,42 @@ var constants_default = {
378
378
  "iPhone X": { os: "ios", viewport: { width: 375, height: 812 } },
379
379
  "iPhone XR": { os: "ios", viewport: { width: 414, height: 896 } },
380
380
  "iPhone XS": { os: "ios", viewport: { width: 375, height: 812 } },
381
- "iPhone XS Max": { os: "ios", viewport: { width: 414, height: 896 } }
381
+ "iPhone XS Max": { os: "ios", viewport: { width: 414, height: 896 } },
382
+ "Galaxy A10s": { os: "android", viewport: { width: 360, height: 640 } },
383
+ "Galaxy A11": { os: "android", viewport: { width: 412, height: 732 } },
384
+ "Galaxy A13": { os: "android", viewport: { width: 412, height: 732 } },
385
+ "Galaxy A52s 5G": { os: "android", viewport: { width: 384, height: 718 } },
386
+ "Galaxy A53 5G": { os: "android", viewport: { width: 412, height: 915 } },
387
+ "Galaxy Tab A 10.1 (2019)": { os: "android", viewport: { width: 800, height: 1280 } },
388
+ "Galaxy Tab S9": { os: "android", viewport: { width: 753, height: 1069 } },
389
+ "Honor X9a 5G": { os: "android", viewport: { width: 360, height: 678 } },
390
+ "Huawei P30 Lite": { os: "android", viewport: { width: 360, height: 647 } },
391
+ "Huawei P50 Pro": { os: "android", viewport: { width: 412, height: 915 } },
392
+ "iPad Pro 13 (2024)": { os: "ios", viewport: { width: 1032, height: 1376 } },
393
+ "iPad Pro 11 (2024)": { os: "ios", viewport: { width: 834, height: 1210 } },
394
+ "iPad Air 13 (2024)": { os: "ios", viewport: { width: 1024, height: 1366 } },
395
+ "iPad Air 11 (2024)": { os: "ios", viewport: { width: 820, height: 1180 } },
396
+ "iPad 10.9 (2022)": { os: "ios", viewport: { width: 820, height: 1180 } },
397
+ "iPhone 16": { os: "ios", viewport: { width: 393, height: 852 } },
398
+ "iPhone 16 Plus": { os: "ios", viewport: { width: 430, height: 932 } },
399
+ "iPhone 16 Pro": { os: "ios", viewport: { width: 402, height: 874 } },
400
+ "iPhone 16 Pro Max": { os: "ios", viewport: { width: 440, height: 956 } },
401
+ "Motorola Edge 40": { os: "android", viewport: { width: 412, height: 915 } },
402
+ "Motorola Edge 30": { os: "android", viewport: { width: 432, height: 814 } },
403
+ "Moto G22": { os: "android", viewport: { width: 412, height: 767 } },
404
+ "Moto G54 5G": { os: "android", viewport: { width: 432, height: 810 } },
405
+ "Moto G71 5G": { os: "android", viewport: { width: 412, height: 732 } },
406
+ "Pixel Tablet": { os: "android", viewport: { width: 800, height: 1100 } },
407
+ "Pixel 6a": { os: "android", viewport: { width: 412, height: 766 } },
408
+ "Pixel 7a": { os: "android", viewport: { width: 412, height: 766 } },
409
+ "Pixel 9": { os: "android", viewport: { width: 412, height: 924 } },
410
+ "Pixel 9 Pro": { os: "android", viewport: { width: 412, height: 915 } },
411
+ "Pixel 9 Pro XL": { os: "android", viewport: { width: 448, height: 998 } },
412
+ "Redmi 9A": { os: "android", viewport: { width: 360, height: 800 } },
413
+ "Redmi Note 13 Pro": { os: "android", viewport: { width: 412, height: 869 } },
414
+ "Aquos Sense 5G": { os: "android", viewport: { width: 393, height: 731 } },
415
+ "Xperia 10 IV": { os: "android", viewport: { width: 412, height: 832 } },
416
+ "Honeywell CT40": { os: "android", viewport: { width: 360, height: 512 } }
382
417
  },
383
418
  FIGMA_API: "https://api.figma.com/v1/",
384
419
  DEFAULT_FIGMA_CONFIG: {
@@ -392,6 +427,31 @@ var constants_default = {
392
427
  ]
393
428
  }
394
429
  ]
430
+ },
431
+ WEB_FIGMA_CONFIG: {
432
+ web: {
433
+ browsers: [
434
+ "chrome",
435
+ "firefox",
436
+ "safari",
437
+ "edge"
438
+ ]
439
+ },
440
+ figma: {
441
+ "depth": 2,
442
+ "configs": [
443
+ {
444
+ "figma_file_token": "<token>",
445
+ "figma_ids": ["id-1", "id-2"],
446
+ "screenshot_names": ["homepage", "about"]
447
+ },
448
+ {
449
+ "figma_file_token": "<token>",
450
+ "figma_ids": ["id-3", "id-4"],
451
+ "screenshot_names": ["xyz", "abc"]
452
+ }
453
+ ]
454
+ }
395
455
  }
396
456
  };
397
457
 
@@ -809,10 +869,97 @@ var FigmaDesignConfigSchema = {
809
869
  required: ["figma_config"],
810
870
  additionalProperties: false
811
871
  };
872
+ var FigmaWebConfigSchema = {
873
+ type: "object",
874
+ "properties": {
875
+ "web": {
876
+ "type": "object",
877
+ "properties": {
878
+ browsers: {
879
+ type: "array",
880
+ items: { type: "string", enum: [constants_default.CHROME, constants_default.FIREFOX, constants_default.SAFARI, constants_default.EDGE] },
881
+ uniqueItems: true,
882
+ maxItems: 4,
883
+ errorMessage: `allowed browsers - ${constants_default.CHROME}, ${constants_default.FIREFOX}, ${constants_default.SAFARI}, ${constants_default.EDGE}`
884
+ },
885
+ "viewports": {
886
+ "type": "array",
887
+ "items": {
888
+ "type": "array",
889
+ "items": {
890
+ "type": "integer",
891
+ "minimum": 1
892
+ },
893
+ "minItems": 1
894
+ }
895
+ }
896
+ },
897
+ "required": ["browsers"]
898
+ },
899
+ "figma": {
900
+ "type": "object",
901
+ "properties": {
902
+ depth: {
903
+ type: "integer",
904
+ minimum: 2,
905
+ errorMessage: "Depth must be an integer and greater than 1"
906
+ },
907
+ "configs": {
908
+ "type": "array",
909
+ "items": {
910
+ "type": "object",
911
+ "properties": {
912
+ "figma_file_token": {
913
+ "type": "string",
914
+ minLength: 1,
915
+ errorMessage: "figma_file_token is mandatory and cannot be empty"
916
+ },
917
+ "figma_ids": {
918
+ "type": "array",
919
+ "items": {
920
+ "type": "string",
921
+ minLength: 1,
922
+ errorMessage: "Each ID in figma_ids must be a non-empty string"
923
+ },
924
+ minItems: 1,
925
+ uniqueItems: true,
926
+ errorMessage: {
927
+ type: "figma_ids must be an array of strings",
928
+ minItems: "figma_ids cannot be empty",
929
+ uniqueItems: "figma_ids must contain unique values"
930
+ }
931
+ },
932
+ "screenshot_names": {
933
+ "type": "array",
934
+ "items": {
935
+ "type": "string"
936
+ },
937
+ uniqueItems: false
938
+ }
939
+ },
940
+ "required": ["figma_file_token", "figma_ids"]
941
+ },
942
+ uniqueItems: true,
943
+ errorMessage: {
944
+ uniqueItems: "Each entry in the figma configs must be unique"
945
+ }
946
+ }
947
+ },
948
+ "required": ["configs"]
949
+ },
950
+ smartIgnore: {
951
+ type: "boolean",
952
+ errorMessage: "Invalid config; smartIgnore must be true/false"
953
+ }
954
+ },
955
+ "required": ["web", "figma"],
956
+ additionalProperties: false
957
+ };
812
958
  var validateConfig = ajv.compile(ConfigSchema);
813
959
  var validateWebStaticConfig = ajv.compile(WebStaticConfigSchema);
814
960
  var validateSnapshot = ajv.compile(SnapshotSchema);
815
961
  var validateFigmaDesignConfig = ajv.compile(FigmaDesignConfigSchema);
962
+ var validateWebFigmaConfig = ajv.compile(FigmaWebConfigSchema);
816
963
 
817
964
  // src/lib/server.ts
818
965
  var server_default = (ctx) => __async(void 0, null, function* () {
@@ -978,7 +1125,7 @@ var auth_default = (ctx) => {
978
1125
  };
979
1126
 
980
1127
  // package.json
981
- var version = "4.0.14";
1128
+ var version = "4.0.16";
982
1129
  var package_default = {
983
1130
  name: "@lambdatest/smartui-cli",
984
1131
  version,
@@ -1048,6 +1195,9 @@ var httpClient = class {
1048
1195
  request(config, log2) {
1049
1196
  return __async(this, null, function* () {
1050
1197
  log2.debug(`http request: ${config.method} ${config.url}`);
1198
+ if (config && config.data) {
1199
+ log2.debug(config.data);
1200
+ }
1051
1201
  return this.axiosInstance.request(config).then((resp) => {
1052
1202
  log2.debug(`http response: ${JSON.stringify({
1053
1203
  status: resp.status,
@@ -1063,7 +1213,7 @@ var httpClient = class {
1063
1213
  headers: error.response.headers,
1064
1214
  body: error.response.data
1065
1215
  })}`);
1066
- throw new Error(((_a = error.response.data.error) == null ? void 0 : _a.message) || error.response.data.message);
1216
+ throw new Error(((_a = error.response.data.error) == null ? void 0 : _a.message) || error.response.data.message || error.response.data);
1067
1217
  }
1068
1218
  if (error.request) {
1069
1219
  log2.debug(`http request failed: ${error.toJSON()}`);
@@ -1223,6 +1373,26 @@ var httpClient = class {
1223
1373
  // prevent axios from limiting the content size
1224
1374
  }, ctx.log);
1225
1375
  }
1376
+ processWebFigma(requestBody, log2) {
1377
+ return this.request({
1378
+ url: "figma-web/upload",
1379
+ method: "POST",
1380
+ headers: {
1381
+ "Content-Type": "application/json"
1382
+ },
1383
+ data: JSON.stringify(requestBody)
1384
+ }, log2);
1385
+ }
1386
+ fetchWebFigma(buildId, log2) {
1387
+ return this.request({
1388
+ url: "figma-web/fetch",
1389
+ method: "GET",
1390
+ headers: {
1391
+ "Content-Type": "application/json"
1392
+ },
1393
+ params: { buildId }
1394
+ }, log2);
1395
+ }
1226
1396
  };
1227
1397
  var ctx_default = (options) => {
1228
1398
  var _a, _b, _c, _d, _e, _f, _g;
@@ -1341,10 +1511,10 @@ var ctx_default = (options) => {
1341
1511
  totalSnapshots: -1
1342
1512
  };
1343
1513
  };
1344
- function executeCommand(command5) {
1514
+ function executeCommand(command4) {
1345
1515
  let dst = process.cwd();
1346
1516
  try {
1347
- return child_process.execSync(command5, {
1517
+ return child_process.execSync(command4, {
1348
1518
  cwd: dst,
1349
1519
  stdio: ["ignore"],
1350
1520
  encoding: "utf-8"
@@ -1375,8 +1545,8 @@ var git_default = (ctx) => {
1375
1545
  } else {
1376
1546
  const splitCharacter = "<##>";
1377
1547
  const prettyFormat = ["%h", "%H", "%s", "%f", "%b", "%at", "%ct", "%an", "%ae", "%cn", "%ce", "%N", ""];
1378
- const command5 = 'git log -1 --pretty=format:"' + prettyFormat.join(splitCharacter) + '" && git rev-parse --abbrev-ref HEAD && git tag --contains HEAD';
1379
- let res = executeCommand(command5).split(splitCharacter);
1548
+ const command4 = 'git log -1 --pretty=format:"' + prettyFormat.join(splitCharacter) + '" && git rev-parse --abbrev-ref HEAD && git tag --contains HEAD';
1549
+ let res = executeCommand(command4).split(splitCharacter);
1380
1550
  var branchAndTags = res[res.length - 1].split("\n").filter((n) => n);
1381
1551
  var branch = ctx.env.CURRENT_BRANCH || branchAndTags[0];
1382
1552
  branchAndTags.slice(1);
@@ -2420,14 +2590,14 @@ var Queue = class {
2420
2590
 
2421
2591
  // src/commander/exec.ts
2422
2592
  var command = new commander.Command();
2423
- command.name("exec").description("Run test commands around SmartUI").argument("<command...>", "Command supplied for running tests").option("-P, --port <number>", "Port number for the server").option("--fetch-results [filename]", "Fetch results and optionally specify an output file, e.g., <filename>.json").option("--buildName <string>", "Specify the build name").action(function(execCommand, _, command5) {
2593
+ command.name("exec").description("Run test commands around SmartUI").argument("<command...>", "Command supplied for running tests").option("-P, --port <number>", "Port number for the server").option("--fetch-results [filename]", "Fetch results and optionally specify an output file, e.g., <filename>.json").option("--buildName <string>", "Specify the build name").action(function(execCommand, _, command4) {
2424
2594
  return __async(this, null, function* () {
2425
- const options = command5.optsWithGlobals();
2595
+ const options = command4.optsWithGlobals();
2426
2596
  if (options.buildName === "") {
2427
2597
  console.log(`Error: The '--buildName' option cannot be an empty string.`);
2428
2598
  process.exit(1);
2429
2599
  }
2430
- let ctx = ctx_default(command5.optsWithGlobals());
2600
+ let ctx = ctx_default(command4.optsWithGlobals());
2431
2601
  if (!which__default.default.sync(execCommand[0], { nothrow: true })) {
2432
2602
  ctx.log.error(`Error: Command not found "${execCommand[0]}"`);
2433
2603
  return;
@@ -2512,11 +2682,59 @@ function createFigmaConfig(filepath) {
2512
2682
  fs5__default.default.writeFileSync(filepath, JSON.stringify(constants_default.DEFAULT_FIGMA_CONFIG, null, 2) + "\n");
2513
2683
  console.log(`Created designs config: ${filepath}`);
2514
2684
  }
2685
+ function createWebFigmaConfig(filepath) {
2686
+ filepath = filepath || ".smartui.json";
2687
+ let filetype = path2__default.default.extname(filepath);
2688
+ if (filetype != ".json") {
2689
+ console.log("Error: figma config file must have .json extension");
2690
+ return;
2691
+ }
2692
+ if (fs5__default.default.existsSync(filepath)) {
2693
+ console.log(`Error: figma config already exists: ${filepath}`);
2694
+ console.log(`To create a new file, please specify the file name like: 'smartui config:create-figma-web <fileName>.json'`);
2695
+ return;
2696
+ }
2697
+ fs5__default.default.mkdirSync(path2__default.default.dirname(filepath), { recursive: true });
2698
+ fs5__default.default.writeFileSync(filepath, JSON.stringify(constants_default.WEB_FIGMA_CONFIG, null, 2) + "\n");
2699
+ console.log(`Created figma web config: ${filepath}`);
2700
+ }
2701
+ function verifyFigmaWebConfig(ctx) {
2702
+ var _a;
2703
+ if (ctx.env.FIGMA_TOKEN == "") {
2704
+ throw new Error("Missing FIGMA_TOKEN in Environment Variables");
2705
+ }
2706
+ if (ctx.env.LT_USERNAME == "") {
2707
+ throw new Error("Missing LT_USERNAME in Environment Variables");
2708
+ }
2709
+ if (ctx.env.LT_ACCESS_KEY == "") {
2710
+ throw new Error("Missing LT_ACCESS_KEY in Environment Variables");
2711
+ }
2712
+ let figma = ctx.config && ((_a = ctx.config) == null ? void 0 : _a.figma) || {};
2713
+ const screenshots = [];
2714
+ for (let c of figma == null ? void 0 : figma.configs) {
2715
+ if (c.screenshot_names && c.screenshot_names.length > 0 && c.figma_ids && c.figma_ids.length != c.screenshot_names.length) {
2716
+ throw new Error("Mismatch in Figma Ids and Screenshot Names in figma config");
2717
+ }
2718
+ if (isValidArray(c.screenshot_names)) {
2719
+ for (const name of c.screenshot_names) {
2720
+ screenshots.push(name);
2721
+ }
2722
+ }
2723
+ }
2724
+ if (new Set(screenshots).size !== screenshots.length) {
2725
+ throw new Error("Found duplicate screenshot names in figma config");
2726
+ }
2727
+ return true;
2728
+ }
2729
+ function isValidArray(input) {
2730
+ return Array.isArray(input) && input.length > 0;
2731
+ }
2515
2732
 
2516
2733
  // src/commander/config.ts
2517
2734
  var configWeb = new commander.Command();
2518
2735
  var configStatic = new commander.Command();
2519
2736
  var configFigma = new commander.Command();
2737
+ var configWebFigma = new commander.Command();
2520
2738
  configWeb.name("config:create").description("Create SmartUI config file").argument("[filepath]", "Optional config filepath").action(function(filepath, options) {
2521
2739
  return __async(this, null, function* () {
2522
2740
  createConfig(filepath);
@@ -2532,6 +2750,11 @@ configFigma.name("config:create-figma").description("Create figma designs config
2532
2750
  createFigmaConfig(filepath);
2533
2751
  });
2534
2752
  });
2753
+ configWebFigma.name("config:create-figma-web").description("Create figma config file with browsers").argument("[filepath]", "Optional config filepath").action(function(filepath, options) {
2754
+ return __async(this, null, function* () {
2755
+ createWebFigmaConfig(filepath);
2756
+ });
2757
+ });
2535
2758
  function captureScreenshotsForConfig(_0, _1, _2, _3, _4) {
2536
2759
  return __async(this, arguments, function* (ctx, browsers, { name, url, waitForTimeout }, browserName, renderViewports) {
2537
2760
  let pageOptions = { waitUntil: process.env.SMARTUI_PAGE_WAIT_UNTIL_EVENT || "load", timeout: ctx.config.waitForPageRender || constants_default.DEFAULT_PAGE_LOAD_TIMEOUT };
@@ -2864,14 +3087,14 @@ var captureScreenshots_default = (ctx) => {
2864
3087
 
2865
3088
  // src/commander/capture.ts
2866
3089
  var command2 = new commander.Command();
2867
- command2.name("capture").description("Capture screenshots of static sites").argument("<file>", "Web static config file").option("-C, --parallel [number]", "Specify the number of instances per browser", parseInt).option("-F, --force", "forcefully apply the specified parallel instances per browser").option("--fetch-results [filename]", "Fetch results and optionally specify an output file, e.g., <filename>.json").option("--buildName <string>", "Specify the build name").action(function(file, _, command5) {
3090
+ command2.name("capture").description("Capture screenshots of static sites").argument("<file>", "Web static config file").option("-C, --parallel [number]", "Specify the number of instances per browser", parseInt).option("-F, --force", "forcefully apply the specified parallel instances per browser").option("--fetch-results [filename]", "Fetch results and optionally specify an output file, e.g., <filename>.json").option("--buildName <string>", "Specify the build name").action(function(file, _, command4) {
2868
3091
  return __async(this, null, function* () {
2869
- const options = command5.optsWithGlobals();
3092
+ const options = command4.optsWithGlobals();
2870
3093
  if (options.buildName === "") {
2871
3094
  console.log(`Error: The '--buildName' option cannot be an empty string.`);
2872
3095
  process.exit(1);
2873
3096
  }
2874
- let ctx = ctx_default(command5.optsWithGlobals());
3097
+ let ctx = ctx_default(command4.optsWithGlobals());
2875
3098
  if (!fs5__default.default.existsSync(file)) {
2876
3099
  ctx.log.error(`Web Static Config file ${file} not found.`);
2877
3100
  return;
@@ -2945,14 +3168,14 @@ command3.name("upload").description("Upload screenshots from given directory").a
2945
3168
  return val.split(",").map((ext) => ext.trim().toLowerCase());
2946
3169
  }).option("-E, --removeExtensions", "Strips file extensions from snapshot names").option("-i, --ignoreDir <patterns>", "Comma-separated list of directories to ignore", (val) => {
2947
3170
  return val.split(",").map((pattern) => pattern.trim());
2948
- }).option("--fetch-results [filename]", "Fetch results and optionally specify an output file, e.g., <filename>.json").option("--buildName <string>", "Specify the build name").action(function(directory, _, command5) {
3171
+ }).option("--fetch-results [filename]", "Fetch results and optionally specify an output file, e.g., <filename>.json").option("--buildName <string>", "Specify the build name").action(function(directory, _, command4) {
2949
3172
  return __async(this, null, function* () {
2950
- const options = command5.optsWithGlobals();
3173
+ const options = command4.optsWithGlobals();
2951
3174
  if (options.buildName === "") {
2952
3175
  console.log(`Error: The '--buildName' option cannot be an empty string.`);
2953
3176
  process.exit(1);
2954
3177
  }
2955
- let ctx = ctx_default(command5.optsWithGlobals());
3178
+ let ctx = ctx_default(command4.optsWithGlobals());
2956
3179
  if (!fs5__default.default.existsSync(directory)) {
2957
3180
  console.log(`Error: The provided directory ${directory} not found.`);
2958
3181
  return;
@@ -3039,12 +3262,118 @@ var uploadFigmaDesigns_default2 = (ctx) => {
3039
3262
  };
3040
3263
  };
3041
3264
 
3042
- // src/commander/uploadFigma.ts
3043
- var command4 = new commander.Command();
3044
- command4.name("upload-figma").description("Capture screenshots of static sites").argument("<file>", "figma design config file").option("--markBaseline", "Mark the uploaded images as baseline").option("--buildName <buildName>", "Name of the build").action(function(file, _, command5) {
3265
+ // src/lib/uploadWebFigma.ts
3266
+ var uploadWebFigma_default = (ctx) => __async(void 0, null, function* () {
3267
+ var _a, _b;
3268
+ const figmaConfig = ctx.config && ((_a = ctx.config) == null ? void 0 : _a.figma) || {};
3269
+ const webConfig = ctx.config && ((_b = ctx.config) == null ? void 0 : _b.web) || {};
3270
+ let results = "";
3271
+ const buildName = ctx.options.buildName;
3272
+ if (figmaConfig && figmaConfig.configs && figmaConfig.configs.length > 0) {
3273
+ const authToken = `Basic ${Buffer.from(`${ctx.env.LT_USERNAME}:${ctx.env.LT_ACCESS_KEY}`).toString("base64")}`;
3274
+ const requestBody = {
3275
+ figma_token: ctx.env.FIGMA_TOKEN,
3276
+ auth: authToken,
3277
+ build_name: buildName,
3278
+ web: webConfig,
3279
+ figma: figmaConfig,
3280
+ smartIgnore: ctx.config.smartIgnore,
3281
+ git: ctx.git
3282
+ };
3283
+ const responseData = yield ctx.client.processWebFigma(requestBody, ctx.log);
3284
+ ctx.log.debug("responseData : " + JSON.stringify(responseData));
3285
+ if (responseData.data.message == "success") {
3286
+ results = responseData.data.message;
3287
+ ctx.build = {
3288
+ id: responseData.data.buildId,
3289
+ url: responseData.data.buildURL || "https://smartui.lambdatestinternal.com"
3290
+ };
3291
+ }
3292
+ } else {
3293
+ throw new Error("No Figma configuration found in config file");
3294
+ }
3295
+ return results;
3296
+ });
3297
+
3298
+ // src/lib/fetchFigma.ts
3299
+ var fetchFigma_default = (ctx) => __async(void 0, null, function* () {
3300
+ const buildId = ctx.build.id;
3301
+ ctx.log.debug(`Fetching figma results for buildId ${buildId}`);
3302
+ const startTime = Date.now();
3303
+ try {
3304
+ const results = yield callFetchWebFigmaRecursive(startTime, buildId, ctx);
3305
+ return results;
3306
+ } catch (error) {
3307
+ ctx.log.error(`Failed to fetch figma results: ${error}`);
3308
+ return { message: "Failed to fetch figma results" };
3309
+ }
3310
+ });
3311
+ function callFetchWebFigmaRecursive(startTime, buildId, ctx) {
3045
3312
  return __async(this, null, function* () {
3046
3313
  var _a, _b;
3047
- let ctx = ctx_default(command5.optsWithGlobals());
3314
+ const currentTime = Date.now();
3315
+ const elapsedTime = (currentTime - startTime) / 1e3;
3316
+ if (elapsedTime >= 180) {
3317
+ ctx.log.error("Stopping execution after 5 minutes.");
3318
+ throw new Error("Timeout: Fetching figma results took more than 5 minutes.");
3319
+ }
3320
+ try {
3321
+ const response = yield ctx.client.fetchWebFigma(buildId, ctx.log);
3322
+ ctx.log.debug("responseData : " + JSON.stringify(response));
3323
+ const message = ((_a = response == null ? void 0 : response.data) == null ? void 0 : _a.message) || "";
3324
+ if (message === "") {
3325
+ ctx.log.debug("No results yet. Retrying after 5 seconds...");
3326
+ yield new Promise((resolve) => setTimeout(resolve, 5e3));
3327
+ return yield callFetchWebFigmaRecursive(startTime, buildId, ctx);
3328
+ } else {
3329
+ return (_b = response == null ? void 0 : response.data) == null ? void 0 : _b.message;
3330
+ }
3331
+ } catch (error) {
3332
+ ctx.log.error("Error in fetchWebFigma:", error);
3333
+ ctx.log.debug("Retrying after 5 seconds...");
3334
+ yield new Promise((resolve) => setTimeout(resolve, 5e3));
3335
+ return yield callFetchWebFigmaRecursive(startTime, buildId, ctx);
3336
+ }
3337
+ });
3338
+ }
3339
+
3340
+ // src/tasks/uploadWebFigma.ts
3341
+ var uploadWebFigma_default2 = (ctx) => {
3342
+ return {
3343
+ title: "Processing Web Figma",
3344
+ task: (ctx2, task) => __async(void 0, null, function* () {
3345
+ try {
3346
+ ctx2.task = task;
3347
+ updateLogContext({ task: "upload-figma-web" });
3348
+ let results = yield uploadWebFigma_default(ctx2);
3349
+ if (results != "success") {
3350
+ throw new Error("Uploading Web Figma Screenshot failed");
3351
+ }
3352
+ if (ctx2.build.id) {
3353
+ task.output = chalk6__default.default.gray(`Build Id: ${ctx2.build.id}`);
3354
+ let figmaOutput = yield fetchFigma_default(ctx2);
3355
+ const jsonObject = JSON.parse(figmaOutput);
3356
+ let output = JSON.stringify(jsonObject, null, 2);
3357
+ task.output = task.output + "\n" + chalk6__default.default.green(`${output}`);
3358
+ }
3359
+ task.title = "Web Figma images uploaded successfully to SmartUI";
3360
+ ctx2.log.debug(`Web Figma processed: ${results}`);
3361
+ } catch (error) {
3362
+ ctx2.log.debug(error);
3363
+ task.output = chalk6__default.default.gray(`${error.message}`);
3364
+ throw new Error("Uploading Web Figma Screenshots failed");
3365
+ }
3366
+ }),
3367
+ rendererOptions: { persistentOutput: true },
3368
+ exitOnError: true
3369
+ };
3370
+ };
3371
+ var uploadFigma = new commander.Command();
3372
+ var uploadWebFigmaCommand = new commander.Command();
3373
+ uploadFigma.name("upload-figma").description("Capture screenshots of static sites").argument("<file>", "figma design config file").option("--markBaseline", "Mark the uploaded images as baseline").option("--buildName <buildName>", "Name of the build").action(function(file, _, command4) {
3374
+ return __async(this, null, function* () {
3375
+ var _a, _b;
3376
+ let ctx = ctx_default(command4.optsWithGlobals());
3048
3377
  if (!fs5__default.default.existsSync(file)) {
3049
3378
  console.log(`Error: Figma Config file ${file} not found.`);
3050
3379
  return;
@@ -3082,11 +3411,62 @@ command4.name("upload-figma").description("Capture screenshots of static sites")
3082
3411
  }
3083
3412
  });
3084
3413
  });
3085
- var uploadFigma_default = command4;
3414
+ uploadWebFigmaCommand.name("upload-figma-web").description("Capture screenshots of static sites").argument("<file>", "figma config config file").option("--markBaseline", "Mark the uploaded images as baseline").option("--buildName <buildName>", "Name of the build").action(function(file, _, command4) {
3415
+ return __async(this, null, function* () {
3416
+ var _a;
3417
+ let ctx = ctx_default(command4.optsWithGlobals());
3418
+ if (!fs5__default.default.existsSync(file)) {
3419
+ console.log(`Error: figma-web config file ${file} not found.`);
3420
+ return;
3421
+ }
3422
+ try {
3423
+ ctx.config = JSON.parse(fs5__default.default.readFileSync(file, "utf8"));
3424
+ ctx.log.info(JSON.stringify(ctx.config));
3425
+ if (!validateWebFigmaConfig(ctx.config)) {
3426
+ ctx.log.debug(JSON.stringify(validateWebFigmaConfig.errors, null, 2));
3427
+ (_a = validateWebFigmaConfig.errors) == null ? void 0 : _a.forEach((error) => {
3428
+ if (error.keyword === "additionalProperties") {
3429
+ ctx.log.warn(`Additional property "${error.params.additionalProperty}" is not allowed.`);
3430
+ } else {
3431
+ const validationError = error.message;
3432
+ throw new Error(validationError || "Invalid figma-web config found in file : " + file);
3433
+ }
3434
+ });
3435
+ }
3436
+ verifyFigmaWebConfig(ctx);
3437
+ } catch (error) {
3438
+ ctx.log.error(chalk6__default.default.red(`Invalid figma-web config; ${error.message}`));
3439
+ return;
3440
+ }
3441
+ let tasks = new listr2.Listr(
3442
+ [
3443
+ auth_default(),
3444
+ getGitInfo_default(),
3445
+ uploadWebFigma_default2(),
3446
+ finalizeBuild_default()
3447
+ ],
3448
+ {
3449
+ rendererOptions: {
3450
+ icon: {
3451
+ [listr2.ListrDefaultRendererLogLevels.OUTPUT]: `\u2192`
3452
+ },
3453
+ color: {
3454
+ [listr2.ListrDefaultRendererLogLevels.OUTPUT]: listr2.color.gray
3455
+ }
3456
+ }
3457
+ }
3458
+ );
3459
+ try {
3460
+ yield tasks.run(ctx);
3461
+ } catch (error) {
3462
+ console.log("\nRefer docs: https://www.lambdatest.com/support/docs/smart-visual-regression-testing/");
3463
+ }
3464
+ });
3465
+ });
3086
3466
 
3087
3467
  // src/commander/commander.ts
3088
3468
  var program = new commander.Command();
3089
- 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).addCommand(upload_default).addCommand(configFigma).addCommand(uploadFigma_default);
3469
+ 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).addCommand(upload_default).addCommand(configFigma).addCommand(uploadFigma).addCommand(configWebFigma).addCommand(uploadWebFigmaCommand);
3090
3470
  var commander_default = program;
3091
3471
  (function() {
3092
3472
  return __async(this, null, function* () {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lambdatest/smartui-cli",
3
- "version": "4.0.14",
3
+ "version": "4.0.16",
4
4
  "description": "A command line interface (CLI) to run SmartUI tests on LambdaTest",
5
5
  "files": [
6
6
  "dist/**/*"