@lambdatest/smartui-cli 4.1.57 → 4.1.58

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 +411 -112
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -306,6 +306,15 @@ var constants_default = {
306
306
  // Disallowed file extension
307
307
  FILE_EXTENSION_ZIP: ".zip",
308
308
  FILE_EXTENSION_GIFS: "gif",
309
+ // command types
310
+ COMMAND_TYPE_EXEC: "exec",
311
+ COMMAND_TYPE_EXEC_START: "exec-start",
312
+ COMMAND_TYPE_CAPTURE: "capture",
313
+ COMMAND_TYPE_UPLOAD: "upload",
314
+ COMMAND_TYPE_UPLOAD_FIGMA: "upload-figma",
315
+ COMMAND_TYPE_UPLOAD_PDF: "upload-pdf",
316
+ COMMAND_TYPE_MERGE: "merge",
317
+ ALLOWED_CUSTOM_VIEWPORT_COMMANDS: ["exec", "exec-start"],
309
318
  // Default scrollTime
310
319
  DEFAULT_SCROLL_TIME: 8,
311
320
  // Default page load time
@@ -631,11 +640,16 @@ var ConfigSchema = {
631
640
  type: "array",
632
641
  items: { type: "string", enum: [constants_default.CHROME, constants_default.FIREFOX, constants_default.SAFARI, constants_default.EDGE] },
633
642
  uniqueItems: true,
643
+ minItems: 1,
634
644
  maxItems: 4,
635
- errorMessage: `Invalid config; allowed browsers - ${constants_default.CHROME}, ${constants_default.FIREFOX}, ${constants_default.SAFARI}, ${constants_default.EDGE}`
645
+ errorMessage: {
646
+ minItems: "Invalid config; browsers must have at least one entry",
647
+ _: `Invalid config; allowed browsers - ${constants_default.CHROME}, ${constants_default.FIREFOX}, ${constants_default.SAFARI}, ${constants_default.EDGE}`
648
+ }
636
649
  },
637
650
  viewports: {
638
651
  type: "array",
652
+ minItems: 1,
639
653
  items: {
640
654
  type: "array",
641
655
  oneOf: [
@@ -657,11 +671,51 @@ var ConfigSchema = {
657
671
  },
658
672
  uniqueItems: true,
659
673
  maxItems: 5,
660
- errorMessage: "Invalid config; max unique viewports allowed - 5"
674
+ errorMessage: {
675
+ minItems: "Invalid config; viewports must have at least one entry",
676
+ maxItems: "Invalid config; max unique viewports allowed - 5"
677
+ }
678
+ },
679
+ customViewports: {
680
+ type: "array",
681
+ minItems: 1,
682
+ items: {
683
+ type: "object",
684
+ properties: {
685
+ browser: {
686
+ type: "string",
687
+ enum: [constants_default.CHROME, constants_default.FIREFOX, constants_default.SAFARI, constants_default.EDGE],
688
+ errorMessage: `Invalid config; allowed browsers - ${constants_default.CHROME}, ${constants_default.FIREFOX}, ${constants_default.SAFARI}, ${constants_default.EDGE}`
689
+ },
690
+ viewport: {
691
+ type: "array",
692
+ oneOf: [
693
+ {
694
+ items: [{ type: "number", minimum: 320, maximum: 7680 }],
695
+ minItems: 1,
696
+ maxItems: 1
697
+ },
698
+ {
699
+ items: [
700
+ { type: "number", minimum: 320, maximum: 7680 },
701
+ { type: "number", minimum: 320, maximum: 7680 }
702
+ ],
703
+ minItems: 2,
704
+ maxItems: 2
705
+ }
706
+ ],
707
+ errorMessage: "Invalid config; customViewports viewport width/height must be >= 320 and <= 7680"
708
+ }
709
+ },
710
+ required: ["browser", "viewport"],
711
+ additionalProperties: false
712
+ },
713
+ errorMessage: {
714
+ minItems: "Invalid config; customViewports must have at least one entry",
715
+ _: "Invalid config; customViewports must be an array of {browser, viewport} objects"
716
+ }
661
717
  }
662
- },
663
- required: ["browsers", "viewports"],
664
- additionalProperties: false
718
+ }
665
719
  },
666
720
  mobile: {
667
721
  type: "object",
@@ -1171,10 +1225,30 @@ var SnapshotSchema = {
1171
1225
  },
1172
1226
  uniqueItems: true,
1173
1227
  errorMessage: "Invalid snapshot options; viewports must be an array of unique arrays."
1228
+ },
1229
+ customViewports: {
1230
+ type: "array",
1231
+ items: {
1232
+ type: "object",
1233
+ properties: {
1234
+ browser: {
1235
+ type: "string",
1236
+ enum: [constants_default.CHROME, constants_default.FIREFOX, constants_default.SAFARI, constants_default.EDGE]
1237
+ },
1238
+ viewport: {
1239
+ type: "array",
1240
+ items: { type: "number", minimum: 1 },
1241
+ minItems: 1,
1242
+ maxItems: 2
1243
+ }
1244
+ },
1245
+ required: ["browser", "viewport"],
1246
+ additionalProperties: false
1247
+ },
1248
+ errorMessage: "Invalid snapshot options; customViewports must be an array of {browser, viewport} objects"
1174
1249
  }
1175
1250
  },
1176
- required: ["viewports"],
1177
- errorMessage: "Invalid snapshot options; web must include viewports property."
1251
+ errorMessage: "Invalid snapshot options; web must include viewports or customViewports property."
1178
1252
  },
1179
1253
  mobile: {
1180
1254
  type: "object",
@@ -1659,20 +1733,55 @@ function closeBrowsers(browsers) {
1659
1733
  function getWebRenderViewports(ctx) {
1660
1734
  let webRenderViewports = [];
1661
1735
  if (ctx.config.web) {
1662
- for (const viewport of ctx.config.web.viewports) {
1663
- webRenderViewports.push({
1664
- viewport,
1665
- viewportString: `${viewport.width}${viewport.height ? "x" + viewport.height : ""}`,
1666
- fullPage: viewport.height ? false : true,
1667
- device: false
1668
- });
1736
+ if (ctx.config.web.browserViewports) {
1737
+ const seen = /* @__PURE__ */ new Set();
1738
+ for (const viewports of Object.values(ctx.config.web.browserViewports)) {
1739
+ for (const viewport of viewports) {
1740
+ const key = `${viewport.width}x${viewport.height}`;
1741
+ if (!seen.has(key)) {
1742
+ seen.add(key);
1743
+ webRenderViewports.push({
1744
+ viewport,
1745
+ viewportString: `${viewport.width}${viewport.height ? "x" + viewport.height : ""}`,
1746
+ fullPage: viewport.height ? false : true,
1747
+ device: false
1748
+ });
1749
+ }
1750
+ }
1751
+ }
1752
+ } else {
1753
+ for (const viewport of ctx.config.web.viewports) {
1754
+ webRenderViewports.push({
1755
+ viewport,
1756
+ viewportString: `${viewport.width}${viewport.height ? "x" + viewport.height : ""}`,
1757
+ fullPage: viewport.height ? false : true,
1758
+ device: false
1759
+ });
1760
+ }
1669
1761
  }
1670
1762
  }
1671
1763
  return webRenderViewports;
1672
1764
  }
1673
1765
  function getWebRenderViewportsForOptions(options) {
1674
1766
  let webRenderViewports = [];
1675
- if (options.web && Array.isArray(options.web.viewports)) {
1767
+ if (options.web && Array.isArray(options.web.customViewports) && options.web.customViewports.length > 0) {
1768
+ const browserViewports = transformCustomViewportsToBrowserViewports(options.web.customViewports);
1769
+ const seen = /* @__PURE__ */ new Set();
1770
+ for (const viewports of Object.values(browserViewports)) {
1771
+ for (const vp of viewports) {
1772
+ const key = `${vp.width}x${vp.height}`;
1773
+ if (!seen.has(key)) {
1774
+ seen.add(key);
1775
+ webRenderViewports.push({
1776
+ viewport: vp,
1777
+ viewportString: `${vp.width}${vp.height ? "x" + vp.height : ""}`,
1778
+ fullPage: vp.height ? false : true,
1779
+ device: false
1780
+ });
1781
+ }
1782
+ }
1783
+ }
1784
+ } else if (options.web && Array.isArray(options.web.viewports)) {
1676
1785
  for (const viewport of options.web.viewports) {
1677
1786
  if (Array.isArray(viewport) && viewport.length > 0) {
1678
1787
  let viewportObj = {
@@ -1692,6 +1801,22 @@ function getWebRenderViewportsForOptions(options) {
1692
1801
  }
1693
1802
  return webRenderViewports;
1694
1803
  }
1804
+ function transformCustomViewportsToBrowserViewports(customViewports) {
1805
+ const browserViewports = {};
1806
+ for (const entry of customViewports) {
1807
+ if (!browserViewports[entry.browser]) {
1808
+ browserViewports[entry.browser] = [];
1809
+ }
1810
+ const vp = { width: entry.viewport[0], height: entry.viewport[1] || 0 };
1811
+ const exists = browserViewports[entry.browser].some(
1812
+ (existing) => existing.width === vp.width && existing.height === vp.height
1813
+ );
1814
+ if (!exists) {
1815
+ browserViewports[entry.browser].push(vp);
1816
+ }
1817
+ }
1818
+ return browserViewports;
1819
+ }
1695
1820
  function getMobileRenderViewports(ctx) {
1696
1821
  var _a;
1697
1822
  let mobileRenderViewports = {};
@@ -1970,9 +2095,15 @@ function stopTunnelHelper(ctx) {
1970
2095
  function calculateVariantCount(config) {
1971
2096
  let variantCount = 0;
1972
2097
  if (config.web) {
1973
- const browsers = config.web.browsers || [];
1974
- const viewports = config.web.viewports || [];
1975
- variantCount += browsers.length * viewports.length;
2098
+ if (config.web.browserViewports) {
2099
+ for (const viewports of Object.values(config.web.browserViewports)) {
2100
+ variantCount += viewports.length;
2101
+ }
2102
+ } else {
2103
+ const browsers = config.web.browsers || [];
2104
+ const viewports = config.web.viewports || [];
2105
+ variantCount += browsers.length * viewports.length;
2106
+ }
1976
2107
  }
1977
2108
  if (config.mobile) {
1978
2109
  const devices = config.mobile.devices || [];
@@ -1984,9 +2115,15 @@ function calculateVariantCountFromSnapshot(snapshot, globalConfig) {
1984
2115
  var _a, _b;
1985
2116
  let variantCount = 0;
1986
2117
  if ((_a = snapshot.options) == null ? void 0 : _a.web) {
1987
- const browsers = snapshot.options.web.browsers || [];
1988
- const viewports = snapshot.options.web.viewports || [];
1989
- variantCount += browsers.length * viewports.length;
2118
+ if (snapshot.options.web.browserViewports) {
2119
+ for (const viewports of Object.values(snapshot.options.web.browserViewports)) {
2120
+ variantCount += viewports.length;
2121
+ }
2122
+ } else {
2123
+ const browsers = snapshot.options.web.browsers || [];
2124
+ const viewports = snapshot.options.web.viewports || [];
2125
+ variantCount += browsers.length * viewports.length;
2126
+ }
1990
2127
  }
1991
2128
  if ((_b = snapshot.options) == null ? void 0 : _b.mobile) {
1992
2129
  const devices = snapshot.options.mobile.devices || [];
@@ -2987,7 +3124,7 @@ var authExec_default = (ctx) => {
2987
3124
  };
2988
3125
 
2989
3126
  // package.json
2990
- var version = "4.1.57";
3127
+ var version = "4.1.58";
2991
3128
  var package_default = {
2992
3129
  name: "@lambdatest/smartui-cli",
2993
3130
  version,
@@ -3844,7 +3981,7 @@ var httpClient = class {
3844
3981
  }
3845
3982
  };
3846
3983
  var ctx_default = (options) => {
3847
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
3984
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
3848
3985
  let env = env_default();
3849
3986
  let webConfig;
3850
3987
  let mobileConfig;
@@ -3922,18 +4059,49 @@ var ctx_default = (options) => {
3922
4059
  env.LT_USERNAME = options.userName;
3923
4060
  env.LT_ACCESS_KEY = options.accessKey;
3924
4061
  }
4062
+ if (((_b = config.web) == null ? void 0 : _b.customViewports) && !constants_default.ALLOWED_CUSTOM_VIEWPORT_COMMANDS.includes(options.commandType)) {
4063
+ throw new Error("customViewports is only supported for the exec command. Use browsers and viewports instead.");
4064
+ }
3925
4065
  } catch (error) {
3926
4066
  console.log(`[smartui] Error: ${error.message}`);
3927
4067
  process.exit(1);
3928
4068
  }
3929
4069
  if (config.web) {
3930
- webConfig = { browsers: config.web.browsers, viewports: [] };
3931
- for (let viewport of (_b = config.web) == null ? void 0 : _b.viewports) webConfig.viewports.push({ width: viewport[0], height: viewport[1] || 0 });
4070
+ const hasCustomViewports = config.web.customViewports && Array.isArray(config.web.customViewports) && config.web.customViewports.length > 0;
4071
+ const hasBrowsersAndViewports = config.web.browsers && config.web.browsers.length > 0 && config.web.viewports && config.web.viewports.length > 0;
4072
+ if (!hasCustomViewports && !hasBrowsersAndViewports) {
4073
+ throw new Error("Invalid config; web config must have either customViewports or both browsers and viewports");
4074
+ }
4075
+ if (hasCustomViewports) {
4076
+ const browserViewports = {};
4077
+ for (const entry of config.web.customViewports) {
4078
+ const vp = { width: entry.viewport[0], height: entry.viewport[1] || 0 };
4079
+ if (!browserViewports[entry.browser]) browserViewports[entry.browser] = [];
4080
+ if (!browserViewports[entry.browser].some((v) => v.width === vp.width && v.height === vp.height)) {
4081
+ browserViewports[entry.browser].push(vp);
4082
+ }
4083
+ }
4084
+ const browsers = Object.keys(browserViewports);
4085
+ const allViewports = [];
4086
+ for (const vps of Object.values(browserViewports)) {
4087
+ for (const vp of vps) {
4088
+ if (!allViewports.some((v) => v.width === vp.width && v.height === vp.height)) {
4089
+ allViewports.push(vp);
4090
+ }
4091
+ }
4092
+ }
4093
+ webConfig = { browsers, viewports: allViewports, browserViewports };
4094
+ } else {
4095
+ webConfig = { browsers: config.web.browsers, viewports: [] };
4096
+ if ((_c = config.web) == null ? void 0 : _c.viewports) {
4097
+ for (let viewport of config.web.viewports) webConfig.viewports.push({ width: viewport[0], height: viewport[1] || 0 });
4098
+ }
4099
+ }
3932
4100
  }
3933
4101
  if (config.mobile) {
3934
4102
  mobileConfig = {
3935
4103
  devices: config.mobile.devices,
3936
- fullPage: (_c = config.mobile.fullPage) != null ? _c : true,
4104
+ fullPage: (_d = config.mobile.fullPage) != null ? _d : true,
3937
4105
  orientation: config.mobile.orientation || constants_default.MOBILE_ORIENTATION_PORTRAIT
3938
4106
  };
3939
4107
  }
@@ -4000,18 +4168,18 @@ var ctx_default = (options) => {
4000
4168
  waitForPageRender: config.waitForPageRender || 0,
4001
4169
  waitForTimeout: config.waitForTimeout || 0,
4002
4170
  waitForDiscovery: config.waitForDiscovery || 3e4,
4003
- enableJavaScript: (_d = config.enableJavaScript) != null ? _d : false,
4004
- cliEnableJavaScript: (_e = config.cliEnableJavaScript) != null ? _e : true,
4171
+ enableJavaScript: (_e = config.enableJavaScript) != null ? _e : false,
4172
+ cliEnableJavaScript: (_f = config.cliEnableJavaScript) != null ? _f : true,
4005
4173
  scrollTime: config.scrollTime || constants_default.DEFAULT_SCROLL_TIME,
4006
4174
  allowedHostnames: config.allowedHostnames || [],
4007
4175
  allowedAssets: config.allowedAssets || [],
4008
4176
  basicAuthorization: basicAuthObj,
4009
4177
  lazyLoadConfiguration: lazyLoadConfigObj,
4010
- smartIgnore: (_f = config.smartIgnore) != null ? _f : false,
4011
- delayedUpload: (_g = config.delayedUpload) != null ? _g : false,
4012
- useGlobalCache: (_h = config.useGlobalCache) != null ? _h : false,
4013
- ignoreHTTPSErrors: (_i = config.ignoreHTTPSErrors) != null ? _i : false,
4014
- skipBuildCreation: (_j = config.skipBuildCreation) != null ? _j : false,
4178
+ smartIgnore: (_g = config.smartIgnore) != null ? _g : false,
4179
+ delayedUpload: (_h = config.delayedUpload) != null ? _h : false,
4180
+ useGlobalCache: (_i = config.useGlobalCache) != null ? _i : false,
4181
+ ignoreHTTPSErrors: (_j = config.ignoreHTTPSErrors) != null ? _j : false,
4182
+ skipBuildCreation: (_k = config.skipBuildCreation) != null ? _k : false,
4015
4183
  tunnel: tunnelObj,
4016
4184
  dedicatedProxyURL: config.dedicatedProxyURL || "",
4017
4185
  geolocation: config.geolocation || "",
@@ -4024,7 +4192,7 @@ var ctx_default = (options) => {
4024
4192
  loadDomContent,
4025
4193
  approvalThreshold: config.approvalThreshold,
4026
4194
  rejectionThreshold: config.rejectionThreshold,
4027
- showRenderErrors: (_k = config.showRenderErrors) != null ? _k : false,
4195
+ showRenderErrors: (_l = config.showRenderErrors) != null ? _l : false,
4028
4196
  customCSS: config.customCSS
4029
4197
  },
4030
4198
  uploadFilePath: "",
@@ -4558,6 +4726,7 @@ var normalizeSameSite = (value) => {
4558
4726
  };
4559
4727
  function prepareSnapshot(snapshot, ctx) {
4560
4728
  return __async(this, null, function* () {
4729
+ var _a;
4561
4730
  let processedOptions = {};
4562
4731
  processedOptions.cliEnableJavascript = ctx.config.cliEnableJavaScript;
4563
4732
  processedOptions.ignoreHTTPSErrors = ctx.config.ignoreHTTPSErrors;
@@ -4579,8 +4748,8 @@ function prepareSnapshot(snapshot, ctx) {
4579
4748
  if (options && Object.keys(options).length) {
4580
4749
  ctx.log.debug(`Snapshot options: ${JSON.stringify(options)}`);
4581
4750
  const isNotAllEmpty = (obj) => {
4582
- var _a;
4583
- for (let key in obj) if ((_a = obj[key]) == null ? void 0 : _a.length) return true;
4751
+ var _a2;
4752
+ for (let key in obj) if ((_a2 = obj[key]) == null ? void 0 : _a2.length) return true;
4584
4753
  return false;
4585
4754
  };
4586
4755
  if (options.loadDomContent) {
@@ -4601,13 +4770,20 @@ function prepareSnapshot(snapshot, ctx) {
4601
4770
  }
4602
4771
  if (options.web && Object.keys(options.web).length) {
4603
4772
  processedOptions.web = {};
4604
- if (options.web.viewports && options.web.viewports.length > 0) {
4605
- processedOptions.web.viewports = options.web.viewports.filter(
4606
- (viewport) => Array.isArray(viewport) && viewport.length > 0
4607
- );
4773
+ if (options.web.customViewports && Array.isArray(options.web.customViewports) && options.web.customViewports.length > 0) {
4774
+ processedOptions.web.browserViewports = transformCustomViewportsToBrowserViewports(options.web.customViewports);
4775
+ } else {
4776
+ if (options.web.viewports && options.web.viewports.length > 0) {
4777
+ processedOptions.web.viewports = options.web.viewports.filter(
4778
+ (viewport) => Array.isArray(viewport) && viewport.length > 0
4779
+ );
4780
+ }
4781
+ if (options.web.browsers && options.web.browsers.length > 0) {
4782
+ processedOptions.web.browsers = options.web.browsers;
4783
+ }
4608
4784
  }
4609
- if (options.web.browsers && options.web.browsers.length > 0) {
4610
- processedOptions.web.browsers = options.web.browsers;
4785
+ if (Object.keys(processedOptions.web).length === 0) {
4786
+ delete processedOptions.web;
4611
4787
  }
4612
4788
  }
4613
4789
  if (options.mobile && Object.keys(options.mobile).length) {
@@ -4663,6 +4839,9 @@ function prepareSnapshot(snapshot, ctx) {
4663
4839
  processedOptions.ignoreType = options.ignoreType;
4664
4840
  }
4665
4841
  }
4842
+ if (!processedOptions.web && ((_a = ctx.config.web) == null ? void 0 : _a.browserViewports)) {
4843
+ processedOptions.web = { browserViewports: ctx.config.web.browserViewports };
4844
+ }
4666
4845
  if (ctx.config.tunnel) {
4667
4846
  if (ctx.tunnelDetails && ctx.tunnelDetails.tunnelPort != -1 && ctx.tunnelDetails.tunnelHost != "") {
4668
4847
  const tunnelAddress = `http://${ctx.tunnelDetails.tunnelHost}:${ctx.tunnelDetails.tunnelPort}`;
@@ -4734,7 +4913,7 @@ function prepareSnapshot(snapshot, ctx) {
4734
4913
  }
4735
4914
  function processSnapshot(snapshot, ctx) {
4736
4915
  return __async(this, null, function* () {
4737
- var _a, _b;
4916
+ var _a, _b, _c;
4738
4917
  updateLogContext({ task: "discovery" });
4739
4918
  ctx.log.debug(`Processing snapshot ${snapshot.name} ${snapshot.url}`);
4740
4919
  const isHeadless = ((_a = process.env.HEADLESS) == null ? void 0 : _a.toLowerCase()) === "false" ? false : true;
@@ -5023,13 +5202,20 @@ function processSnapshot(snapshot, ctx) {
5023
5202
  }
5024
5203
  if (options.web && Object.keys(options.web).length) {
5025
5204
  processedOptions.web = {};
5026
- if (options.web.viewports && options.web.viewports.length > 0) {
5027
- processedOptions.web.viewports = options.web.viewports.filter(
5028
- (viewport) => Array.isArray(viewport) && viewport.length > 0
5029
- );
5205
+ if (options.web.customViewports && Array.isArray(options.web.customViewports) && options.web.customViewports.length > 0) {
5206
+ processedOptions.web.browserViewports = transformCustomViewportsToBrowserViewports(options.web.customViewports);
5207
+ } else {
5208
+ if (options.web.viewports && options.web.viewports.length > 0) {
5209
+ processedOptions.web.viewports = options.web.viewports.filter(
5210
+ (viewport) => Array.isArray(viewport) && viewport.length > 0
5211
+ );
5212
+ }
5213
+ if (options.web.browsers && options.web.browsers.length > 0) {
5214
+ processedOptions.web.browsers = options.web.browsers;
5215
+ }
5030
5216
  }
5031
- if (options.web.browsers && options.web.browsers.length > 0) {
5032
- processedOptions.web.browsers = options.web.browsers;
5217
+ if (Object.keys(processedOptions.web).length === 0) {
5218
+ delete processedOptions.web;
5033
5219
  }
5034
5220
  }
5035
5221
  if (options.mobile && Object.keys(options.mobile).length) {
@@ -5087,6 +5273,9 @@ function processSnapshot(snapshot, ctx) {
5087
5273
  processedOptions.ignoreType = options.ignoreType;
5088
5274
  }
5089
5275
  }
5276
+ if (!processedOptions.web && ((_c = ctx.config.web) == null ? void 0 : _c.browserViewports)) {
5277
+ processedOptions.web = { browserViewports: ctx.config.web.browserViewports };
5278
+ }
5090
5279
  if (ctx.config.tunnel) {
5091
5280
  if (ctx.tunnelDetails && ctx.tunnelDetails.tunnelPort != -1 && ctx.tunnelDetails.tunnelHost != "") {
5092
5281
  const tunnelAddress = `http://${ctx.tunnelDetails.tunnelHost}:${ctx.tunnelDetails.tunnelPort}`;
@@ -5458,28 +5647,42 @@ var Queue = class {
5458
5647
  }
5459
5648
  }
5460
5649
  processGenerateVariants(snapshot) {
5650
+ var _a, _b;
5651
+ let hasWebOptions = ((_a = snapshot.options) == null ? void 0 : _a.web) && Object.keys(snapshot.options.web).length > 0;
5652
+ let hasMobileOptions = ((_b = snapshot.options) == null ? void 0 : _b.mobile) && Object.keys(snapshot.options.mobile).length > 0;
5461
5653
  if (snapshot.options) {
5462
- if (snapshot.options.web) {
5654
+ if (hasWebOptions) {
5463
5655
  this.generateWebVariants(snapshot, snapshot.options.web);
5464
5656
  }
5465
- if (snapshot.options.mobile) {
5657
+ if (hasMobileOptions) {
5466
5658
  this.generateMobileVariants(snapshot, snapshot.options.mobile);
5467
5659
  }
5468
5660
  }
5469
- if (!snapshot.options || snapshot.options && !snapshot.options.web && !snapshot.options.mobile) {
5661
+ if (!snapshot.options || !hasWebOptions && !hasMobileOptions) {
5470
5662
  this.generateVariants(snapshot, this.ctx.config);
5471
5663
  }
5472
5664
  }
5473
5665
  generateVariants(snapshot, config) {
5474
5666
  if (config.web) {
5475
- const browsers = config.web.browsers || [];
5476
- const viewports = config.web.viewports || [];
5477
- for (const browser of browsers) {
5478
- for (const viewport of viewports) {
5479
- const width = viewport.width;
5480
- const height = viewport.height || 0;
5481
- const variant = `${snapshot.name}_${browser}_viewport[${width}]_viewport[${height}]`;
5482
- this.variants.push(variant);
5667
+ if (config.web.browserViewports) {
5668
+ for (const [browser, viewports] of Object.entries(config.web.browserViewports)) {
5669
+ for (const viewport of viewports) {
5670
+ const width = viewport.width;
5671
+ const height = viewport.height || 0;
5672
+ const variant = `${snapshot.name}_${browser}_viewport[${width}]_viewport[${height}]`;
5673
+ this.variants.push(variant);
5674
+ }
5675
+ }
5676
+ } else {
5677
+ const browsers = config.web.browsers || [];
5678
+ const viewports = config.web.viewports || [];
5679
+ for (const browser of browsers) {
5680
+ for (const viewport of viewports) {
5681
+ const width = viewport.width;
5682
+ const height = viewport.height || 0;
5683
+ const variant = `${snapshot.name}_${browser}_viewport[${width}]_viewport[${height}]`;
5684
+ this.variants.push(variant);
5685
+ }
5483
5686
  }
5484
5687
  }
5485
5688
  }
@@ -5494,15 +5697,24 @@ var Queue = class {
5494
5697
  }
5495
5698
  generateWebVariants(snapshot, webConfig) {
5496
5699
  var _a, _b, _c;
5497
- const browsers = (_c = (_b = webConfig.browsers) != null ? _b : (_a = this.ctx.config.web) == null ? void 0 : _a.browsers) != null ? _c : [constants_default.CHROME, constants_default.EDGE, constants_default.FIREFOX, constants_default.SAFARI];
5498
- const viewports = webConfig.viewports || [];
5499
- for (const browser of browsers) {
5500
- for (const viewport of viewports) {
5501
- const width = viewport[0];
5502
- const height = viewport[1] || 0;
5503
- const variant = `${snapshot.name}_${browser}_viewport[${width}]_viewport[${height}]`;
5700
+ if (webConfig.customViewports && Array.isArray(webConfig.customViewports) && webConfig.customViewports.length > 0) {
5701
+ for (const entry of webConfig.customViewports) {
5702
+ const width = entry.viewport[0];
5703
+ const height = entry.viewport[1] || 0;
5704
+ const variant = `${snapshot.name}_${entry.browser}_viewport[${width}]_viewport[${height}]`;
5504
5705
  this.variants.push(variant);
5505
5706
  }
5707
+ } else {
5708
+ const browsers = (_c = (_b = webConfig.browsers) != null ? _b : (_a = this.ctx.config.web) == null ? void 0 : _a.browsers) != null ? _c : [constants_default.CHROME, constants_default.EDGE, constants_default.FIREFOX, constants_default.SAFARI];
5709
+ const viewports = webConfig.viewports || [];
5710
+ for (const browser of browsers) {
5711
+ for (const viewport of viewports) {
5712
+ const width = viewport[0];
5713
+ const height = viewport[1] || 0;
5714
+ const variant = `${snapshot.name}_${browser}_viewport[${width}]_viewport[${height}]`;
5715
+ this.variants.push(variant);
5716
+ }
5717
+ }
5506
5718
  }
5507
5719
  }
5508
5720
  generateMobileVariants(snapshot, mobileConfig) {
@@ -5515,16 +5727,19 @@ var Queue = class {
5515
5727
  }
5516
5728
  }
5517
5729
  filterExistingVariants(snapshot, config) {
5730
+ var _a, _b;
5518
5731
  let drop = true;
5519
- if (snapshot.options && snapshot.options.web) {
5732
+ let hasWebOptions = ((_a = snapshot.options) == null ? void 0 : _a.web) && Object.keys(snapshot.options.web).length > 0;
5733
+ let hasMobileOptions = ((_b = snapshot.options) == null ? void 0 : _b.mobile) && Object.keys(snapshot.options.mobile).length > 0;
5734
+ if (snapshot.options && hasWebOptions) {
5520
5735
  const webDrop = this.filterWebVariants(snapshot, snapshot.options.web);
5521
5736
  if (!webDrop) drop = false;
5522
5737
  }
5523
- if (snapshot.options && snapshot.options.mobile) {
5738
+ if (snapshot.options && hasMobileOptions) {
5524
5739
  const mobileDrop = this.filterMobileVariants(snapshot, snapshot.options.mobile);
5525
5740
  if (!mobileDrop) drop = false;
5526
5741
  }
5527
- if (!snapshot.options || snapshot.options && !snapshot.options.web && !snapshot.options.mobile) {
5742
+ if (!snapshot.options || !hasWebOptions && !hasMobileOptions) {
5528
5743
  const configDrop = this.filterVariants(snapshot, config);
5529
5744
  if (!configDrop) drop = false;
5530
5745
  }
@@ -5534,28 +5749,63 @@ var Queue = class {
5534
5749
  var _a;
5535
5750
  let allVariantsDropped = true;
5536
5751
  if (config.web) {
5537
- const browsers = config.web.browsers || [];
5538
- const viewports = config.web.viewports || [];
5539
- for (const browser of browsers) {
5540
- for (const viewport of viewports) {
5541
- const width = viewport.width;
5542
- const height = viewport.height || 0;
5543
- const variant = `${snapshot.name}_${browser}_viewport[${width}]_viewport[${height}]`;
5544
- if (!this.variants.includes(variant)) {
5545
- allVariantsDropped = false;
5546
- if (!snapshot.options) snapshot.options = {};
5547
- if (!snapshot.options.web) snapshot.options.web = { browsers: [], viewports: [] };
5548
- if (!snapshot.options.web.browsers.includes(browser)) {
5549
- snapshot.options.web.browsers.push(browser);
5752
+ if (config.web.browserViewports) {
5753
+ const customViewports = [];
5754
+ for (const [browser, viewports] of Object.entries(config.web.browserViewports)) {
5755
+ for (const viewport of viewports) {
5756
+ const width = viewport.width;
5757
+ const height = viewport.height || 0;
5758
+ const variant = `${snapshot.name}_${browser}_viewport[${width}]_viewport[${height}]`;
5759
+ if (!this.variants.includes(variant)) {
5760
+ allVariantsDropped = false;
5761
+ if (height > 0) {
5762
+ customViewports.push({ browser, viewport: [width, height] });
5763
+ } else {
5764
+ customViewports.push({ browser, viewport: [width] });
5765
+ }
5550
5766
  }
5767
+ }
5768
+ }
5769
+ if (customViewports.length > 0) {
5770
+ if (!snapshot.options) snapshot.options = {};
5771
+ snapshot.options.web = { browsers: [], viewports: [], customViewports };
5772
+ for (const entry of customViewports) {
5773
+ if (!snapshot.options.web.browsers.includes(entry.browser)) {
5774
+ snapshot.options.web.browsers.push(entry.browser);
5775
+ }
5776
+ const vp = entry.viewport;
5551
5777
  const viewportExists = snapshot.options.web.viewports.some(
5552
- (existingViewport) => existingViewport[0] === width && (existingViewport.length < 2 || existingViewport[1] === height)
5778
+ (ev) => ev[0] === vp[0] && (ev.length < 2 || ev[1] === (vp[1] || 0))
5553
5779
  );
5554
5780
  if (!viewportExists) {
5555
- if (height > 0) {
5556
- snapshot.options.web.viewports.push([width, height]);
5557
- } else {
5558
- snapshot.options.web.viewports.push([width]);
5781
+ snapshot.options.web.viewports.push(vp);
5782
+ }
5783
+ }
5784
+ }
5785
+ } else {
5786
+ const browsers = config.web.browsers || [];
5787
+ const viewports = config.web.viewports || [];
5788
+ for (const browser of browsers) {
5789
+ for (const viewport of viewports) {
5790
+ const width = viewport.width;
5791
+ const height = viewport.height || 0;
5792
+ const variant = `${snapshot.name}_${browser}_viewport[${width}]_viewport[${height}]`;
5793
+ if (!this.variants.includes(variant)) {
5794
+ allVariantsDropped = false;
5795
+ if (!snapshot.options) snapshot.options = {};
5796
+ if (!snapshot.options.web) snapshot.options.web = { browsers: [], viewports: [] };
5797
+ if (!snapshot.options.web.browsers.includes(browser)) {
5798
+ snapshot.options.web.browsers.push(browser);
5799
+ }
5800
+ const viewportExists = snapshot.options.web.viewports.some(
5801
+ (existingViewport) => existingViewport[0] === width && (existingViewport.length < 2 || existingViewport[1] === height)
5802
+ );
5803
+ if (!viewportExists) {
5804
+ if (height > 0) {
5805
+ snapshot.options.web.viewports.push([width, height]);
5806
+ } else {
5807
+ snapshot.options.web.viewports.push([width]);
5808
+ }
5559
5809
  }
5560
5810
  }
5561
5811
  }
@@ -5583,31 +5833,60 @@ var Queue = class {
5583
5833
  }
5584
5834
  filterWebVariants(snapshot, webConfig) {
5585
5835
  var _a, _b, _c;
5586
- const browsers = (_c = (_b = webConfig.browsers) != null ? _b : (_a = this.ctx.config.web) == null ? void 0 : _a.browsers) != null ? _c : [constants_default.CHROME, constants_default.EDGE, constants_default.FIREFOX, constants_default.SAFARI];
5587
- const viewports = webConfig.viewports || [];
5588
5836
  let allVariantsDropped = true;
5589
5837
  if (!snapshot.options) {
5590
5838
  snapshot.options = {};
5591
5839
  }
5592
- snapshot.options.web = { browsers: [], viewports: [] };
5593
- for (const browser of browsers) {
5594
- for (const viewport of viewports) {
5595
- const width = viewport[0];
5596
- const height = viewport[1] || 0;
5597
- const variant = `${snapshot.name}_${browser}_viewport[${width}]_viewport[${height}]`;
5840
+ if (webConfig.customViewports && Array.isArray(webConfig.customViewports) && webConfig.customViewports.length > 0) {
5841
+ const filteredCustomViewports = [];
5842
+ const browsers = [];
5843
+ const viewports = [];
5844
+ for (const entry of webConfig.customViewports) {
5845
+ const width = entry.viewport[0];
5846
+ const height = entry.viewport[1] || 0;
5847
+ const variant = `${snapshot.name}_${entry.browser}_viewport[${width}]_viewport[${height}]`;
5598
5848
  if (!this.variants.includes(variant)) {
5599
5849
  allVariantsDropped = false;
5600
- if (!snapshot.options.web.browsers.includes(browser)) {
5601
- snapshot.options.web.browsers.push(browser);
5850
+ filteredCustomViewports.push(entry);
5851
+ if (!browsers.includes(entry.browser)) {
5852
+ browsers.push(entry.browser);
5602
5853
  }
5603
- const viewportExists = snapshot.options.web.viewports.some(
5604
- (existingViewport) => existingViewport[0] === width && (existingViewport.length < 2 || existingViewport[1] === height)
5854
+ const viewportExists = viewports.some(
5855
+ (ev) => ev[0] === width && (ev.length < 2 || ev[1] === height)
5605
5856
  );
5606
5857
  if (!viewportExists) {
5607
5858
  if (height > 0) {
5608
- snapshot.options.web.viewports.push([width, height]);
5859
+ viewports.push([width, height]);
5609
5860
  } else {
5610
- snapshot.options.web.viewports.push([width]);
5861
+ viewports.push([width]);
5862
+ }
5863
+ }
5864
+ }
5865
+ }
5866
+ snapshot.options.web = { browsers, viewports, customViewports: filteredCustomViewports };
5867
+ } else {
5868
+ snapshot.options.web = { browsers: [], viewports: [] };
5869
+ const browsers = (_c = (_b = webConfig.browsers) != null ? _b : (_a = this.ctx.config.web) == null ? void 0 : _a.browsers) != null ? _c : [constants_default.CHROME, constants_default.EDGE, constants_default.FIREFOX, constants_default.SAFARI];
5870
+ const viewports = webConfig.viewports || [];
5871
+ for (const browser of browsers) {
5872
+ for (const viewport of viewports) {
5873
+ const width = viewport[0];
5874
+ const height = viewport[1] || 0;
5875
+ const variant = `${snapshot.name}_${browser}_viewport[${width}]_viewport[${height}]`;
5876
+ if (!this.variants.includes(variant)) {
5877
+ allVariantsDropped = false;
5878
+ if (!snapshot.options.web.browsers.includes(browser)) {
5879
+ snapshot.options.web.browsers.push(browser);
5880
+ }
5881
+ const viewportExists = snapshot.options.web.viewports.some(
5882
+ (existingViewport) => existingViewport[0] === width && (existingViewport.length < 2 || existingViewport[1] === height)
5883
+ );
5884
+ if (!viewportExists) {
5885
+ if (height > 0) {
5886
+ snapshot.options.web.viewports.push([width, height]);
5887
+ } else {
5888
+ snapshot.options.web.viewports.push([width]);
5889
+ }
5611
5890
  }
5612
5891
  }
5613
5892
  }
@@ -5918,7 +6197,9 @@ command.name("exec").description("Run test commands around SmartUI").argument("<
5918
6197
  console.log(`Error: The '--buildName' option cannot be an empty string.`);
5919
6198
  process.exit(1);
5920
6199
  }
5921
- let ctx = ctx_default(command11.optsWithGlobals());
6200
+ let opts = command11.optsWithGlobals();
6201
+ opts.commandType = constants_default.COMMAND_TYPE_EXEC;
6202
+ let ctx = ctx_default(opts);
5922
6203
  if (!which__default.default.sync(execCommand[0], { nothrow: true })) {
5923
6204
  ctx.log.error(`Error: Command not found "${execCommand[0]}"`);
5924
6205
  return;
@@ -6759,7 +7040,9 @@ command2.name("capture").description("Capture screenshots of static sites").argu
6759
7040
  console.log(`Error: The '--buildName' option cannot be an empty string.`);
6760
7041
  process.exit(1);
6761
7042
  }
6762
- let ctx = ctx_default(command11.optsWithGlobals());
7043
+ let opts = command11.optsWithGlobals();
7044
+ opts.commandType = constants_default.COMMAND_TYPE_CAPTURE;
7045
+ let ctx = ctx_default(opts);
6763
7046
  ctx.isSnapshotCaptured = true;
6764
7047
  if (!fs6__default.default.existsSync(file)) {
6765
7048
  ctx.log.error(`Web Static Config file ${file} not found.`);
@@ -6854,7 +7137,9 @@ command3.name("upload").description("Upload screenshots from given directory").a
6854
7137
  console.log(`Error: The '--buildName' option cannot be an empty string.`);
6855
7138
  process.exit(1);
6856
7139
  }
6857
- let ctx = ctx_default(command11.optsWithGlobals());
7140
+ let opts = command11.optsWithGlobals();
7141
+ opts.commandType = constants_default.COMMAND_TYPE_UPLOAD;
7142
+ let ctx = ctx_default(opts);
6858
7143
  ctx.isSnapshotCaptured = true;
6859
7144
  if (!fs6__default.default.existsSync(directory)) {
6860
7145
  console.log(`Error: The provided directory ${directory} not found.`);
@@ -7137,7 +7422,9 @@ var uploadAppFigmaCommand = new commander.Command();
7137
7422
  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, _, command11) {
7138
7423
  return __async(this, null, function* () {
7139
7424
  var _a, _b;
7140
- let ctx = ctx_default(command11.optsWithGlobals());
7425
+ let opts = command11.optsWithGlobals();
7426
+ opts.commandType = constants_default.COMMAND_TYPE_UPLOAD_FIGMA;
7427
+ let ctx = ctx_default(opts);
7141
7428
  ctx.isSnapshotCaptured = true;
7142
7429
  if (!fs6__default.default.existsSync(file)) {
7143
7430
  console.log(`Error: Figma Config file ${file} not found.`);
@@ -7179,7 +7466,9 @@ uploadFigma.name("upload-figma").description("Capture screenshots of static site
7179
7466
  uploadWebFigmaCommand.name("upload-figma-web").description("Capture figma screenshots into CLI build").argument("<file>", "figma config config file").option("--markBaseline", "Mark the uploaded images as baseline").option("--buildName <buildName>", "Name of the build").option("--fetch-results [filename]", "Fetch results and optionally specify an output file, e.g., <filename>.json").action(function(file, _, command11) {
7180
7467
  return __async(this, null, function* () {
7181
7468
  var _a;
7182
- let ctx = ctx_default(command11.optsWithGlobals());
7469
+ let opts = command11.optsWithGlobals();
7470
+ opts.commandType = constants_default.COMMAND_TYPE_UPLOAD_FIGMA;
7471
+ let ctx = ctx_default(opts);
7183
7472
  if (!fs6__default.default.existsSync(file)) {
7184
7473
  console.log(`Error: figma-web config file ${file} not found.`);
7185
7474
  return;
@@ -7232,7 +7521,9 @@ uploadWebFigmaCommand.name("upload-figma-web").description("Capture figma screen
7232
7521
  uploadAppFigmaCommand.name("upload-figma-app").description("Capture figma screenshots into App Build").argument("<file>", "figma config config file").option("--markBaseline", "Mark the uploaded images as baseline").option("--buildName <buildName>", "Name of the build").option("--fetch-results [filename]", "Fetch results and optionally specify an output file, e.g., <filename>.json").action(function(file, _, command11) {
7233
7522
  return __async(this, null, function* () {
7234
7523
  var _a;
7235
- let ctx = ctx_default(command11.optsWithGlobals());
7524
+ let opts = command11.optsWithGlobals();
7525
+ opts.commandType = constants_default.COMMAND_TYPE_UPLOAD_FIGMA;
7526
+ let ctx = ctx_default(opts);
7236
7527
  if (!fs6__default.default.existsSync(file)) {
7237
7528
  console.log(`Error: figma-app config file ${file} not found.`);
7238
7529
  return;
@@ -7291,7 +7582,9 @@ command4.name("exec:start").description("Start SmartUI server").option("-P, --po
7291
7582
  console.log(`Error: The '--buildName' option cannot be an empty string.`);
7292
7583
  process.exit(1);
7293
7584
  }
7294
- let ctx = ctx_default(command4.optsWithGlobals());
7585
+ let opts = command4.optsWithGlobals();
7586
+ opts.commandType = constants_default.COMMAND_TYPE_EXEC_START;
7587
+ let ctx = ctx_default(opts);
7295
7588
  ctx.snapshotQueue = new Queue(ctx);
7296
7589
  ctx.totalSnapshots = 0;
7297
7590
  ctx.isStartExec = true;
@@ -7491,7 +7784,9 @@ var command7 = new commander.Command();
7491
7784
  command7.name("branch").description("Merge a source branch into the target branch").requiredOption("--source <string>", "Source branch to merge").requiredOption("--target <string>", "Target branch to merge into").action(function(options) {
7492
7785
  return __async(this, null, function* () {
7493
7786
  const { source, target } = options;
7494
- let ctx = ctx_default(command7.optsWithGlobals());
7787
+ let opts = command7.optsWithGlobals();
7788
+ opts.commandType = constants_default.COMMAND_TYPE_MERGE;
7789
+ let ctx = ctx_default(opts);
7495
7790
  if (!source || source.trim() === "") {
7496
7791
  ctx.log.error("Error: The --source option cannot be empty.");
7497
7792
  process.exit(1);
@@ -7574,7 +7869,9 @@ var command8 = new commander.Command();
7574
7869
  command8.name("build").description("Merge a source build into the target build").requiredOption("--source <string>", "Source build to merge").requiredOption("--target <string>", "Target build to merge into").action(function(options) {
7575
7870
  return __async(this, null, function* () {
7576
7871
  const { source, target } = options;
7577
- let ctx = ctx_default(command8.optsWithGlobals());
7872
+ let opts = command8.optsWithGlobals();
7873
+ opts.commandType = constants_default.COMMAND_TYPE_MERGE;
7874
+ let ctx = ctx_default(opts);
7578
7875
  if (!source || source.trim() === "") {
7579
7876
  ctx.log.error("Error: The --source option cannot be empty.");
7580
7877
  process.exit(1);
@@ -7746,7 +8043,9 @@ command10.name("upload-pdf").description("Upload PDFs for visual comparison").ar
7746
8043
  console.log(`Error: The '--buildName' option cannot be an empty string.`);
7747
8044
  process.exit(1);
7748
8045
  }
7749
- let ctx = ctx_default(command11.optsWithGlobals());
8046
+ let opts = command11.optsWithGlobals();
8047
+ opts.commandType = constants_default.COMMAND_TYPE_UPLOAD_PDF;
8048
+ let ctx = ctx_default(opts);
7750
8049
  if (!fs6__default.default.existsSync(directory)) {
7751
8050
  console.log(`Error: The provided directory ${directory} not found.`);
7752
8051
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lambdatest/smartui-cli",
3
- "version": "4.1.57",
3
+ "version": "4.1.58",
4
4
  "description": "A command line interface (CLI) to run SmartUI tests on LambdaTest",
5
5
  "files": [
6
6
  "dist/**/*"