@lambdatest/smartui-cli 4.1.56-beta.2 → 4.1.56

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 +425 -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.56-beta.2";
3127
+ var version = "4.1.56";
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, _b;
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,16 @@ 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
+ }
4845
+ if (!processedOptions.mobile && ctx.config.mobile) {
4846
+ processedOptions.mobile = {
4847
+ devices: ctx.config.mobile.devices,
4848
+ fullPage: (_b = ctx.config.mobile.fullPage) != null ? _b : true,
4849
+ orientation: ctx.config.mobile.orientation || constants_default.MOBILE_ORIENTATION_PORTRAIT
4850
+ };
4851
+ }
4666
4852
  if (ctx.config.tunnel) {
4667
4853
  if (ctx.tunnelDetails && ctx.tunnelDetails.tunnelPort != -1 && ctx.tunnelDetails.tunnelHost != "") {
4668
4854
  const tunnelAddress = `http://${ctx.tunnelDetails.tunnelHost}:${ctx.tunnelDetails.tunnelPort}`;
@@ -4734,7 +4920,7 @@ function prepareSnapshot(snapshot, ctx) {
4734
4920
  }
4735
4921
  function processSnapshot(snapshot, ctx) {
4736
4922
  return __async(this, null, function* () {
4737
- var _a, _b;
4923
+ var _a, _b, _c, _d;
4738
4924
  updateLogContext({ task: "discovery" });
4739
4925
  ctx.log.debug(`Processing snapshot ${snapshot.name} ${snapshot.url}`);
4740
4926
  const isHeadless = ((_a = process.env.HEADLESS) == null ? void 0 : _a.toLowerCase()) === "false" ? false : true;
@@ -5023,13 +5209,20 @@ function processSnapshot(snapshot, ctx) {
5023
5209
  }
5024
5210
  if (options.web && Object.keys(options.web).length) {
5025
5211
  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
- );
5212
+ if (options.web.customViewports && Array.isArray(options.web.customViewports) && options.web.customViewports.length > 0) {
5213
+ processedOptions.web.browserViewports = transformCustomViewportsToBrowserViewports(options.web.customViewports);
5214
+ } else {
5215
+ if (options.web.viewports && options.web.viewports.length > 0) {
5216
+ processedOptions.web.viewports = options.web.viewports.filter(
5217
+ (viewport) => Array.isArray(viewport) && viewport.length > 0
5218
+ );
5219
+ }
5220
+ if (options.web.browsers && options.web.browsers.length > 0) {
5221
+ processedOptions.web.browsers = options.web.browsers;
5222
+ }
5030
5223
  }
5031
- if (options.web.browsers && options.web.browsers.length > 0) {
5032
- processedOptions.web.browsers = options.web.browsers;
5224
+ if (Object.keys(processedOptions.web).length === 0) {
5225
+ delete processedOptions.web;
5033
5226
  }
5034
5227
  }
5035
5228
  if (options.mobile && Object.keys(options.mobile).length) {
@@ -5087,6 +5280,16 @@ function processSnapshot(snapshot, ctx) {
5087
5280
  processedOptions.ignoreType = options.ignoreType;
5088
5281
  }
5089
5282
  }
5283
+ if (!processedOptions.web && ((_c = ctx.config.web) == null ? void 0 : _c.browserViewports)) {
5284
+ processedOptions.web = { browserViewports: ctx.config.web.browserViewports };
5285
+ }
5286
+ if (!processedOptions.mobile && ctx.config.mobile) {
5287
+ processedOptions.mobile = {
5288
+ devices: ctx.config.mobile.devices,
5289
+ fullPage: (_d = ctx.config.mobile.fullPage) != null ? _d : true,
5290
+ orientation: ctx.config.mobile.orientation || constants_default.MOBILE_ORIENTATION_PORTRAIT
5291
+ };
5292
+ }
5090
5293
  if (ctx.config.tunnel) {
5091
5294
  if (ctx.tunnelDetails && ctx.tunnelDetails.tunnelPort != -1 && ctx.tunnelDetails.tunnelHost != "") {
5092
5295
  const tunnelAddress = `http://${ctx.tunnelDetails.tunnelHost}:${ctx.tunnelDetails.tunnelPort}`;
@@ -5458,28 +5661,42 @@ var Queue = class {
5458
5661
  }
5459
5662
  }
5460
5663
  processGenerateVariants(snapshot) {
5664
+ var _a, _b;
5665
+ let hasWebOptions = ((_a = snapshot.options) == null ? void 0 : _a.web) && Object.keys(snapshot.options.web).length > 0;
5666
+ let hasMobileOptions = ((_b = snapshot.options) == null ? void 0 : _b.mobile) && Object.keys(snapshot.options.mobile).length > 0;
5461
5667
  if (snapshot.options) {
5462
- if (snapshot.options.web) {
5668
+ if (hasWebOptions) {
5463
5669
  this.generateWebVariants(snapshot, snapshot.options.web);
5464
5670
  }
5465
- if (snapshot.options.mobile) {
5671
+ if (hasMobileOptions) {
5466
5672
  this.generateMobileVariants(snapshot, snapshot.options.mobile);
5467
5673
  }
5468
5674
  }
5469
- if (!snapshot.options || snapshot.options && !snapshot.options.web && !snapshot.options.mobile) {
5675
+ if (!snapshot.options || !hasWebOptions && !hasMobileOptions) {
5470
5676
  this.generateVariants(snapshot, this.ctx.config);
5471
5677
  }
5472
5678
  }
5473
5679
  generateVariants(snapshot, config) {
5474
5680
  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);
5681
+ if (config.web.browserViewports) {
5682
+ for (const [browser, viewports] of Object.entries(config.web.browserViewports)) {
5683
+ for (const viewport of viewports) {
5684
+ const width = viewport.width;
5685
+ const height = viewport.height || 0;
5686
+ const variant = `${snapshot.name}_${browser}_viewport[${width}]_viewport[${height}]`;
5687
+ this.variants.push(variant);
5688
+ }
5689
+ }
5690
+ } else {
5691
+ const browsers = config.web.browsers || [];
5692
+ const viewports = config.web.viewports || [];
5693
+ for (const browser of browsers) {
5694
+ for (const viewport of viewports) {
5695
+ const width = viewport.width;
5696
+ const height = viewport.height || 0;
5697
+ const variant = `${snapshot.name}_${browser}_viewport[${width}]_viewport[${height}]`;
5698
+ this.variants.push(variant);
5699
+ }
5483
5700
  }
5484
5701
  }
5485
5702
  }
@@ -5494,15 +5711,24 @@ var Queue = class {
5494
5711
  }
5495
5712
  generateWebVariants(snapshot, webConfig) {
5496
5713
  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}]`;
5714
+ if (webConfig.customViewports && Array.isArray(webConfig.customViewports) && webConfig.customViewports.length > 0) {
5715
+ for (const entry of webConfig.customViewports) {
5716
+ const width = entry.viewport[0];
5717
+ const height = entry.viewport[1] || 0;
5718
+ const variant = `${snapshot.name}_${entry.browser}_viewport[${width}]_viewport[${height}]`;
5504
5719
  this.variants.push(variant);
5505
5720
  }
5721
+ } else {
5722
+ 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];
5723
+ const viewports = webConfig.viewports || [];
5724
+ for (const browser of browsers) {
5725
+ for (const viewport of viewports) {
5726
+ const width = viewport[0];
5727
+ const height = viewport[1] || 0;
5728
+ const variant = `${snapshot.name}_${browser}_viewport[${width}]_viewport[${height}]`;
5729
+ this.variants.push(variant);
5730
+ }
5731
+ }
5506
5732
  }
5507
5733
  }
5508
5734
  generateMobileVariants(snapshot, mobileConfig) {
@@ -5515,16 +5741,19 @@ var Queue = class {
5515
5741
  }
5516
5742
  }
5517
5743
  filterExistingVariants(snapshot, config) {
5744
+ var _a, _b;
5518
5745
  let drop = true;
5519
- if (snapshot.options && snapshot.options.web) {
5746
+ let hasWebOptions = ((_a = snapshot.options) == null ? void 0 : _a.web) && Object.keys(snapshot.options.web).length > 0;
5747
+ let hasMobileOptions = ((_b = snapshot.options) == null ? void 0 : _b.mobile) && Object.keys(snapshot.options.mobile).length > 0;
5748
+ if (snapshot.options && hasWebOptions) {
5520
5749
  const webDrop = this.filterWebVariants(snapshot, snapshot.options.web);
5521
5750
  if (!webDrop) drop = false;
5522
5751
  }
5523
- if (snapshot.options && snapshot.options.mobile) {
5752
+ if (snapshot.options && hasMobileOptions) {
5524
5753
  const mobileDrop = this.filterMobileVariants(snapshot, snapshot.options.mobile);
5525
5754
  if (!mobileDrop) drop = false;
5526
5755
  }
5527
- if (!snapshot.options || snapshot.options && !snapshot.options.web && !snapshot.options.mobile) {
5756
+ if (!snapshot.options || !hasWebOptions && !hasMobileOptions) {
5528
5757
  const configDrop = this.filterVariants(snapshot, config);
5529
5758
  if (!configDrop) drop = false;
5530
5759
  }
@@ -5534,28 +5763,63 @@ var Queue = class {
5534
5763
  var _a;
5535
5764
  let allVariantsDropped = true;
5536
5765
  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);
5766
+ if (config.web.browserViewports) {
5767
+ const customViewports = [];
5768
+ for (const [browser, viewports] of Object.entries(config.web.browserViewports)) {
5769
+ for (const viewport of viewports) {
5770
+ const width = viewport.width;
5771
+ const height = viewport.height || 0;
5772
+ const variant = `${snapshot.name}_${browser}_viewport[${width}]_viewport[${height}]`;
5773
+ if (!this.variants.includes(variant)) {
5774
+ allVariantsDropped = false;
5775
+ if (height > 0) {
5776
+ customViewports.push({ browser, viewport: [width, height] });
5777
+ } else {
5778
+ customViewports.push({ browser, viewport: [width] });
5779
+ }
5550
5780
  }
5781
+ }
5782
+ }
5783
+ if (customViewports.length > 0) {
5784
+ if (!snapshot.options) snapshot.options = {};
5785
+ snapshot.options.web = { browsers: [], viewports: [], customViewports };
5786
+ for (const entry of customViewports) {
5787
+ if (!snapshot.options.web.browsers.includes(entry.browser)) {
5788
+ snapshot.options.web.browsers.push(entry.browser);
5789
+ }
5790
+ const vp = entry.viewport;
5551
5791
  const viewportExists = snapshot.options.web.viewports.some(
5552
- (existingViewport) => existingViewport[0] === width && (existingViewport.length < 2 || existingViewport[1] === height)
5792
+ (ev) => ev[0] === vp[0] && (ev.length < 2 || ev[1] === (vp[1] || 0))
5553
5793
  );
5554
5794
  if (!viewportExists) {
5555
- if (height > 0) {
5556
- snapshot.options.web.viewports.push([width, height]);
5557
- } else {
5558
- snapshot.options.web.viewports.push([width]);
5795
+ snapshot.options.web.viewports.push(vp);
5796
+ }
5797
+ }
5798
+ }
5799
+ } else {
5800
+ const browsers = config.web.browsers || [];
5801
+ const viewports = config.web.viewports || [];
5802
+ for (const browser of browsers) {
5803
+ for (const viewport of viewports) {
5804
+ const width = viewport.width;
5805
+ const height = viewport.height || 0;
5806
+ const variant = `${snapshot.name}_${browser}_viewport[${width}]_viewport[${height}]`;
5807
+ if (!this.variants.includes(variant)) {
5808
+ allVariantsDropped = false;
5809
+ if (!snapshot.options) snapshot.options = {};
5810
+ if (!snapshot.options.web) snapshot.options.web = { browsers: [], viewports: [] };
5811
+ if (!snapshot.options.web.browsers.includes(browser)) {
5812
+ snapshot.options.web.browsers.push(browser);
5813
+ }
5814
+ const viewportExists = snapshot.options.web.viewports.some(
5815
+ (existingViewport) => existingViewport[0] === width && (existingViewport.length < 2 || existingViewport[1] === height)
5816
+ );
5817
+ if (!viewportExists) {
5818
+ if (height > 0) {
5819
+ snapshot.options.web.viewports.push([width, height]);
5820
+ } else {
5821
+ snapshot.options.web.viewports.push([width]);
5822
+ }
5559
5823
  }
5560
5824
  }
5561
5825
  }
@@ -5583,31 +5847,60 @@ var Queue = class {
5583
5847
  }
5584
5848
  filterWebVariants(snapshot, webConfig) {
5585
5849
  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
5850
  let allVariantsDropped = true;
5589
5851
  if (!snapshot.options) {
5590
5852
  snapshot.options = {};
5591
5853
  }
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}]`;
5854
+ if (webConfig.customViewports && Array.isArray(webConfig.customViewports) && webConfig.customViewports.length > 0) {
5855
+ const filteredCustomViewports = [];
5856
+ const browsers = [];
5857
+ const viewports = [];
5858
+ for (const entry of webConfig.customViewports) {
5859
+ const width = entry.viewport[0];
5860
+ const height = entry.viewport[1] || 0;
5861
+ const variant = `${snapshot.name}_${entry.browser}_viewport[${width}]_viewport[${height}]`;
5598
5862
  if (!this.variants.includes(variant)) {
5599
5863
  allVariantsDropped = false;
5600
- if (!snapshot.options.web.browsers.includes(browser)) {
5601
- snapshot.options.web.browsers.push(browser);
5864
+ filteredCustomViewports.push(entry);
5865
+ if (!browsers.includes(entry.browser)) {
5866
+ browsers.push(entry.browser);
5602
5867
  }
5603
- const viewportExists = snapshot.options.web.viewports.some(
5604
- (existingViewport) => existingViewport[0] === width && (existingViewport.length < 2 || existingViewport[1] === height)
5868
+ const viewportExists = viewports.some(
5869
+ (ev) => ev[0] === width && (ev.length < 2 || ev[1] === height)
5605
5870
  );
5606
5871
  if (!viewportExists) {
5607
5872
  if (height > 0) {
5608
- snapshot.options.web.viewports.push([width, height]);
5873
+ viewports.push([width, height]);
5609
5874
  } else {
5610
- snapshot.options.web.viewports.push([width]);
5875
+ viewports.push([width]);
5876
+ }
5877
+ }
5878
+ }
5879
+ }
5880
+ snapshot.options.web = { browsers, viewports, customViewports: filteredCustomViewports };
5881
+ } else {
5882
+ snapshot.options.web = { browsers: [], viewports: [] };
5883
+ 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];
5884
+ const viewports = webConfig.viewports || [];
5885
+ for (const browser of browsers) {
5886
+ for (const viewport of viewports) {
5887
+ const width = viewport[0];
5888
+ const height = viewport[1] || 0;
5889
+ const variant = `${snapshot.name}_${browser}_viewport[${width}]_viewport[${height}]`;
5890
+ if (!this.variants.includes(variant)) {
5891
+ allVariantsDropped = false;
5892
+ if (!snapshot.options.web.browsers.includes(browser)) {
5893
+ snapshot.options.web.browsers.push(browser);
5894
+ }
5895
+ const viewportExists = snapshot.options.web.viewports.some(
5896
+ (existingViewport) => existingViewport[0] === width && (existingViewport.length < 2 || existingViewport[1] === height)
5897
+ );
5898
+ if (!viewportExists) {
5899
+ if (height > 0) {
5900
+ snapshot.options.web.viewports.push([width, height]);
5901
+ } else {
5902
+ snapshot.options.web.viewports.push([width]);
5903
+ }
5611
5904
  }
5612
5905
  }
5613
5906
  }
@@ -5918,7 +6211,9 @@ command.name("exec").description("Run test commands around SmartUI").argument("<
5918
6211
  console.log(`Error: The '--buildName' option cannot be an empty string.`);
5919
6212
  process.exit(1);
5920
6213
  }
5921
- let ctx = ctx_default(command11.optsWithGlobals());
6214
+ let opts = command11.optsWithGlobals();
6215
+ opts.commandType = constants_default.COMMAND_TYPE_EXEC;
6216
+ let ctx = ctx_default(opts);
5922
6217
  if (!which__default.default.sync(execCommand[0], { nothrow: true })) {
5923
6218
  ctx.log.error(`Error: Command not found "${execCommand[0]}"`);
5924
6219
  return;
@@ -6759,7 +7054,9 @@ command2.name("capture").description("Capture screenshots of static sites").argu
6759
7054
  console.log(`Error: The '--buildName' option cannot be an empty string.`);
6760
7055
  process.exit(1);
6761
7056
  }
6762
- let ctx = ctx_default(command11.optsWithGlobals());
7057
+ let opts = command11.optsWithGlobals();
7058
+ opts.commandType = constants_default.COMMAND_TYPE_CAPTURE;
7059
+ let ctx = ctx_default(opts);
6763
7060
  ctx.isSnapshotCaptured = true;
6764
7061
  if (!fs6__default.default.existsSync(file)) {
6765
7062
  ctx.log.error(`Web Static Config file ${file} not found.`);
@@ -6854,7 +7151,9 @@ command3.name("upload").description("Upload screenshots from given directory").a
6854
7151
  console.log(`Error: The '--buildName' option cannot be an empty string.`);
6855
7152
  process.exit(1);
6856
7153
  }
6857
- let ctx = ctx_default(command11.optsWithGlobals());
7154
+ let opts = command11.optsWithGlobals();
7155
+ opts.commandType = constants_default.COMMAND_TYPE_UPLOAD;
7156
+ let ctx = ctx_default(opts);
6858
7157
  ctx.isSnapshotCaptured = true;
6859
7158
  if (!fs6__default.default.existsSync(directory)) {
6860
7159
  console.log(`Error: The provided directory ${directory} not found.`);
@@ -7137,7 +7436,9 @@ var uploadAppFigmaCommand = new commander.Command();
7137
7436
  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
7437
  return __async(this, null, function* () {
7139
7438
  var _a, _b;
7140
- let ctx = ctx_default(command11.optsWithGlobals());
7439
+ let opts = command11.optsWithGlobals();
7440
+ opts.commandType = constants_default.COMMAND_TYPE_UPLOAD_FIGMA;
7441
+ let ctx = ctx_default(opts);
7141
7442
  ctx.isSnapshotCaptured = true;
7142
7443
  if (!fs6__default.default.existsSync(file)) {
7143
7444
  console.log(`Error: Figma Config file ${file} not found.`);
@@ -7179,7 +7480,9 @@ uploadFigma.name("upload-figma").description("Capture screenshots of static site
7179
7480
  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
7481
  return __async(this, null, function* () {
7181
7482
  var _a;
7182
- let ctx = ctx_default(command11.optsWithGlobals());
7483
+ let opts = command11.optsWithGlobals();
7484
+ opts.commandType = constants_default.COMMAND_TYPE_UPLOAD_FIGMA;
7485
+ let ctx = ctx_default(opts);
7183
7486
  if (!fs6__default.default.existsSync(file)) {
7184
7487
  console.log(`Error: figma-web config file ${file} not found.`);
7185
7488
  return;
@@ -7232,7 +7535,9 @@ uploadWebFigmaCommand.name("upload-figma-web").description("Capture figma screen
7232
7535
  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
7536
  return __async(this, null, function* () {
7234
7537
  var _a;
7235
- let ctx = ctx_default(command11.optsWithGlobals());
7538
+ let opts = command11.optsWithGlobals();
7539
+ opts.commandType = constants_default.COMMAND_TYPE_UPLOAD_FIGMA;
7540
+ let ctx = ctx_default(opts);
7236
7541
  if (!fs6__default.default.existsSync(file)) {
7237
7542
  console.log(`Error: figma-app config file ${file} not found.`);
7238
7543
  return;
@@ -7291,7 +7596,9 @@ command4.name("exec:start").description("Start SmartUI server").option("-P, --po
7291
7596
  console.log(`Error: The '--buildName' option cannot be an empty string.`);
7292
7597
  process.exit(1);
7293
7598
  }
7294
- let ctx = ctx_default(command4.optsWithGlobals());
7599
+ let opts = command4.optsWithGlobals();
7600
+ opts.commandType = constants_default.COMMAND_TYPE_EXEC_START;
7601
+ let ctx = ctx_default(opts);
7295
7602
  ctx.snapshotQueue = new Queue(ctx);
7296
7603
  ctx.totalSnapshots = 0;
7297
7604
  ctx.isStartExec = true;
@@ -7491,7 +7798,9 @@ var command7 = new commander.Command();
7491
7798
  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
7799
  return __async(this, null, function* () {
7493
7800
  const { source, target } = options;
7494
- let ctx = ctx_default(command7.optsWithGlobals());
7801
+ let opts = command7.optsWithGlobals();
7802
+ opts.commandType = constants_default.COMMAND_TYPE_MERGE;
7803
+ let ctx = ctx_default(opts);
7495
7804
  if (!source || source.trim() === "") {
7496
7805
  ctx.log.error("Error: The --source option cannot be empty.");
7497
7806
  process.exit(1);
@@ -7574,7 +7883,9 @@ var command8 = new commander.Command();
7574
7883
  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
7884
  return __async(this, null, function* () {
7576
7885
  const { source, target } = options;
7577
- let ctx = ctx_default(command8.optsWithGlobals());
7886
+ let opts = command8.optsWithGlobals();
7887
+ opts.commandType = constants_default.COMMAND_TYPE_MERGE;
7888
+ let ctx = ctx_default(opts);
7578
7889
  if (!source || source.trim() === "") {
7579
7890
  ctx.log.error("Error: The --source option cannot be empty.");
7580
7891
  process.exit(1);
@@ -7746,7 +8057,9 @@ command10.name("upload-pdf").description("Upload PDFs for visual comparison").ar
7746
8057
  console.log(`Error: The '--buildName' option cannot be an empty string.`);
7747
8058
  process.exit(1);
7748
8059
  }
7749
- let ctx = ctx_default(command11.optsWithGlobals());
8060
+ let opts = command11.optsWithGlobals();
8061
+ opts.commandType = constants_default.COMMAND_TYPE_UPLOAD_PDF;
8062
+ let ctx = ctx_default(opts);
7750
8063
  if (!fs6__default.default.existsSync(directory)) {
7751
8064
  console.log(`Error: The provided directory ${directory} not found.`);
7752
8065
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lambdatest/smartui-cli",
3
- "version": "4.1.56-beta.2",
3
+ "version": "4.1.56",
4
4
  "description": "A command line interface (CLI) to run SmartUI tests on LambdaTest",
5
5
  "files": [
6
6
  "dist/**/*"