@lambdatest/smartui-cli 4.1.0 → 4.1.2-beta.0

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 +132 -57
  2. package/package.json +3 -1
package/dist/index.cjs CHANGED
@@ -7,7 +7,7 @@ var listr2 = require('listr2');
7
7
  var chalk = require('chalk');
8
8
  var path2 = require('path');
9
9
  var fastify = require('fastify');
10
- var fs6 = require('fs');
10
+ var fs5 = require('fs');
11
11
  var Ajv = require('ajv');
12
12
  var addErrors = require('ajv-errors');
13
13
  var test = require('@playwright/test');
@@ -18,6 +18,7 @@ var axios = require('axios');
18
18
  var https = require('https');
19
19
  var child_process = require('child_process');
20
20
  var spawn = require('cross-spawn');
21
+ var NodeCache = require('node-cache');
21
22
  var uuid = require('uuid');
22
23
  var sharp = require('sharp');
23
24
 
@@ -27,13 +28,14 @@ var which__default = /*#__PURE__*/_interopDefault(which);
27
28
  var chalk__default = /*#__PURE__*/_interopDefault(chalk);
28
29
  var path2__default = /*#__PURE__*/_interopDefault(path2);
29
30
  var fastify__default = /*#__PURE__*/_interopDefault(fastify);
30
- var fs6__default = /*#__PURE__*/_interopDefault(fs6);
31
+ var fs5__default = /*#__PURE__*/_interopDefault(fs5);
31
32
  var Ajv__default = /*#__PURE__*/_interopDefault(Ajv);
32
33
  var addErrors__default = /*#__PURE__*/_interopDefault(addErrors);
33
34
  var FormData__default = /*#__PURE__*/_interopDefault(FormData);
34
35
  var axios__default = /*#__PURE__*/_interopDefault(axios);
35
36
  var https__default = /*#__PURE__*/_interopDefault(https);
36
37
  var spawn__default = /*#__PURE__*/_interopDefault(spawn);
38
+ var NodeCache__default = /*#__PURE__*/_interopDefault(NodeCache);
37
39
  var sharp__default = /*#__PURE__*/_interopDefault(sharp);
38
40
 
39
41
  var __defProp = Object.defineProperty;
@@ -561,6 +563,12 @@ var ConfigSchema = {
561
563
  maximum: 3e4,
562
564
  errorMessage: "Invalid config; waitForTimeout must be > 0 and <= 30000"
563
565
  },
566
+ waitForDiscovery: {
567
+ type: "number",
568
+ minimum: 0,
569
+ maximum: 18e5,
570
+ errorMessage: "Invalid config; waitForDiscovery must be > 0 and <= 1800000"
571
+ },
564
572
  enableJavaScript: {
565
573
  type: "boolean",
566
574
  errorMessage: "Invalid config; enableJavaScript must be true/false"
@@ -573,6 +581,10 @@ var ConfigSchema = {
573
581
  type: "boolean",
574
582
  errorMessage: "Invalid config; smartIgnore must be true/false"
575
583
  },
584
+ ignoreHTTPSErrors: {
585
+ type: "boolean",
586
+ errorMessage: "Invalid config; ignoreHttpsError must be true/false"
587
+ },
576
588
  scrollTime: {
577
589
  type: "number",
578
590
  minimum: 1,
@@ -609,6 +621,10 @@ var ConfigSchema = {
609
621
  delayedUpload: {
610
622
  type: "boolean",
611
623
  errorMessage: "Invalid config; delayedUpload must be true/false"
624
+ },
625
+ useGlobalCache: {
626
+ type: "boolean",
627
+ errorMessage: "Invalid config; useGlobalCache must be true/false"
612
628
  }
613
629
  },
614
630
  anyOf: [
@@ -978,8 +994,8 @@ var validateWebFigmaConfig = ajv.compile(FigmaWebConfigSchema);
978
994
  util.promisify(setTimeout);
979
995
  var isPollingActive = false;
980
996
  function delDir(dir) {
981
- if (fs6__default.default.existsSync(dir)) {
982
- fs6__default.default.rmSync(dir, { recursive: true });
997
+ if (fs5__default.default.existsSync(dir)) {
998
+ fs5__default.default.rmSync(dir, { recursive: true });
983
999
  }
984
1000
  }
985
1001
  function scrollToBottomAndBackToTop({
@@ -1166,6 +1182,7 @@ process.on("SIGINT", () => __async(void 0, null, function* () {
1166
1182
  function startPolling(ctx) {
1167
1183
  return __async(this, null, function* () {
1168
1184
  ctx.log.info("Fetching results in progress....");
1185
+ ctx.log.debug(ctx.build);
1169
1186
  isPollingActive = true;
1170
1187
  const intervalId = setInterval(() => __async(this, null, function* () {
1171
1188
  if (!isPollingActive) {
@@ -1173,13 +1190,13 @@ function startPolling(ctx) {
1173
1190
  return;
1174
1191
  }
1175
1192
  try {
1176
- const resp = yield ctx.client.getScreenshotData(ctx.build.id, ctx.build.baseline, ctx.log);
1193
+ const resp = yield ctx.client.getScreenshotData(ctx.build.id, ctx.build.baseline || false, ctx.log);
1177
1194
  if (!resp.build) {
1178
1195
  ctx.log.info("Error: Build data is null.");
1179
1196
  clearInterval(intervalId);
1180
1197
  isPollingActive = false;
1181
1198
  }
1182
- fs6__default.default.writeFileSync(ctx.options.fetchResultsFileName, JSON.stringify(resp, null, 2));
1199
+ fs5__default.default.writeFileSync(ctx.options.fetchResultsFileName, JSON.stringify(resp, null, 2));
1183
1200
  ctx.log.debug(`Updated results in ${ctx.options.fetchResultsFileName}`);
1184
1201
  if (resp.build.build_status_ind === constants_default.BUILD_COMPLETE || resp.build.build_status_ind === constants_default.BUILD_ERROR) {
1185
1202
  clearInterval(intervalId);
@@ -1264,7 +1281,7 @@ var server_default = (ctx) => __async(void 0, null, function* () {
1264
1281
  bodyLimit: 3e7
1265
1282
  });
1266
1283
  const opts = {};
1267
- const SMARTUI_DOM = fs6.readFileSync(path2__default.default.resolve(__dirname, "dom-serializer.js"), "utf-8");
1284
+ const SMARTUI_DOM = fs5.readFileSync(path2__default.default.resolve(__dirname, "dom-serializer.js"), "utf-8");
1268
1285
  server.get("/healthcheck", opts, (_, reply) => {
1269
1286
  reply.code(200).send({ cliVersion: ctx.cliVersion });
1270
1287
  });
@@ -1281,6 +1298,7 @@ var server_default = (ctx) => __async(void 0, null, function* () {
1281
1298
  throw new Error(validateSnapshot.errors[0].message);
1282
1299
  ctx.testType = testType;
1283
1300
  (_a = ctx.snapshotQueue) == null ? void 0 : _a.enqueue(snapshot);
1301
+ ctx.isSnapshotCaptured = true;
1284
1302
  replyCode = 200;
1285
1303
  replyBody = { data: { message: "success", warnings: [] } };
1286
1304
  } catch (error) {
@@ -1465,7 +1483,7 @@ var auth_default = (ctx) => {
1465
1483
  };
1466
1484
 
1467
1485
  // package.json
1468
- var version = "4.1.0";
1486
+ var version = "4.1.2-beta.0";
1469
1487
  var package_default = {
1470
1488
  name: "@lambdatest/smartui-cli",
1471
1489
  version,
@@ -1476,6 +1494,7 @@ var package_default = {
1476
1494
  scripts: {
1477
1495
  build: "tsup",
1478
1496
  release: "pnpm run build && pnpm publish --access public --no-git-checks",
1497
+ "release:beta": "pnpm run build && pnpm publish --tag beta --access public --no-git-checks",
1479
1498
  "local-build": "pnpm run build && pnpm pack"
1480
1499
  },
1481
1500
  bin: {
@@ -1506,6 +1525,7 @@ var package_default = {
1506
1525
  fastify: "^4.24.3",
1507
1526
  "form-data": "^4.0.0",
1508
1527
  listr2: "^7.0.1",
1528
+ "node-cache": "^5.1.2",
1509
1529
  sharp: "^0.33.4",
1510
1530
  tsup: "^7.2.0",
1511
1531
  uuid: "^11.0.3",
@@ -1549,6 +1569,26 @@ var httpClient = class {
1549
1569
  config.headers["accessKey"] = this.accessKey;
1550
1570
  return config;
1551
1571
  });
1572
+ this.axiosInstance.interceptors.response.use(
1573
+ (response) => response,
1574
+ (error) => __async(this, null, function* () {
1575
+ const { config } = error;
1576
+ if (config && config.url === "/screenshot" && config.method === "post") {
1577
+ if (!config.retryCount) {
1578
+ config.retryCount = 0;
1579
+ config.retry = 2;
1580
+ config.retryDelay = 5e3;
1581
+ }
1582
+ if (config.retryCount < config.retry) {
1583
+ config.retryCount += 1;
1584
+ yield new Promise((resolve) => setTimeout(resolve, config.retryDelay));
1585
+ config.timeout = 3e4;
1586
+ return this.axiosInstance(config);
1587
+ }
1588
+ return Promise.reject(error);
1589
+ }
1590
+ })
1591
+ );
1552
1592
  }
1553
1593
  request(config, log2) {
1554
1594
  return __async(this, null, function* () {
@@ -1557,12 +1597,17 @@ var httpClient = class {
1557
1597
  log2.debug(config.data);
1558
1598
  }
1559
1599
  return this.axiosInstance.request(config).then((resp) => {
1560
- log2.debug(`http response: ${JSON.stringify({
1561
- status: resp.status,
1562
- headers: resp.headers,
1563
- body: resp.data
1564
- })}`);
1565
- return resp.data;
1600
+ if (resp) {
1601
+ log2.debug(`http response: ${JSON.stringify({
1602
+ status: resp.status,
1603
+ headers: resp.headers,
1604
+ body: resp.data
1605
+ })}`);
1606
+ return resp.data;
1607
+ } else {
1608
+ log2.debug(`empty response: ${JSON.stringify(resp)}`);
1609
+ return {};
1610
+ }
1566
1611
  }).catch((error) => {
1567
1612
  var _a;
1568
1613
  if (error.response) {
@@ -1675,7 +1720,7 @@ var httpClient = class {
1675
1720
  }
1676
1721
  uploadScreenshot({ id: buildId, name: buildName, baseline }, ssPath, ssName, browserName, viewport, log2) {
1677
1722
  browserName = browserName === constants_default.SAFARI ? constants_default.WEBKIT : browserName;
1678
- const file = fs6__default.default.readFileSync(ssPath);
1723
+ const file = fs5__default.default.readFileSync(ssPath);
1679
1724
  const form = new FormData__default.default();
1680
1725
  form.append("screenshot", file, { filename: `${ssName}.png`, contentType: "image/png" });
1681
1726
  form.append("browser", browserName);
@@ -1688,7 +1733,8 @@ var httpClient = class {
1688
1733
  url: `/screenshot`,
1689
1734
  method: "POST",
1690
1735
  headers: form.getHeaders(),
1691
- data: form
1736
+ data: form,
1737
+ timeout: 3e4
1692
1738
  }).then(() => {
1693
1739
  log2.debug(`${ssName} for ${browserName} ${viewport} uploaded successfully`);
1694
1740
  }).catch((error) => {
@@ -1754,8 +1800,8 @@ var httpClient = class {
1754
1800
  }, ctx.log);
1755
1801
  }
1756
1802
  uploadLogs(ctx, uploadURL) {
1757
- const fileStream = fs6__default.default.createReadStream(constants_default.LOG_FILE_PATH);
1758
- const { size } = fs6__default.default.statSync(constants_default.LOG_FILE_PATH);
1803
+ const fileStream = fs5__default.default.createReadStream(constants_default.LOG_FILE_PATH);
1804
+ const { size } = fs5__default.default.statSync(constants_default.LOG_FILE_PATH);
1759
1805
  return this.request({
1760
1806
  url: uploadURL,
1761
1807
  method: "PUT",
@@ -1806,7 +1852,7 @@ var httpClient = class {
1806
1852
  }
1807
1853
  };
1808
1854
  var ctx_default = (options) => {
1809
- var _a, _b, _c, _d, _e, _f, _g;
1855
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
1810
1856
  let env = env_default();
1811
1857
  let webConfig;
1812
1858
  let mobileConfig;
@@ -1823,7 +1869,7 @@ var ctx_default = (options) => {
1823
1869
  let buildNameObj;
1824
1870
  try {
1825
1871
  if (options.config) {
1826
- config = JSON.parse(fs6__default.default.readFileSync(options.config, "utf-8"));
1872
+ config = JSON.parse(fs5__default.default.readFileSync(options.config, "utf-8"));
1827
1873
  if ((_a = config.web) == null ? void 0 : _a.resolutions) {
1828
1874
  config.web.viewports = config.web.resolutions;
1829
1875
  delete config.web.resolutions;
@@ -1881,13 +1927,16 @@ var ctx_default = (options) => {
1881
1927
  mobile: mobileConfig,
1882
1928
  waitForPageRender: config.waitForPageRender || 0,
1883
1929
  waitForTimeout: config.waitForTimeout || 0,
1930
+ waitForDiscovery: config.waitForDiscovery || 3e4,
1884
1931
  enableJavaScript: (_d = config.enableJavaScript) != null ? _d : false,
1885
1932
  cliEnableJavaScript: (_e = config.cliEnableJavaScript) != null ? _e : true,
1886
1933
  scrollTime: config.scrollTime || constants_default.DEFAULT_SCROLL_TIME,
1887
1934
  allowedHostnames: config.allowedHostnames || [],
1888
1935
  basicAuthorization: basicAuthObj,
1889
1936
  smartIgnore: (_f = config.smartIgnore) != null ? _f : false,
1890
- delayedUpload: (_g = config.delayedUpload) != null ? _g : false
1937
+ delayedUpload: (_g = config.delayedUpload) != null ? _g : false,
1938
+ useGlobalCache: (_h = config.useGlobalCache) != null ? _h : false,
1939
+ ignoreHTTPSErrors: (_i = config.ignoreHTTPSErrors) != null ? _i : false
1891
1940
  },
1892
1941
  uploadFilePath: "",
1893
1942
  webStaticConfig: [],
@@ -1920,7 +1969,8 @@ var ctx_default = (options) => {
1920
1969
  },
1921
1970
  cliVersion: version,
1922
1971
  totalSnapshots: -1,
1923
- isStartExec: false
1972
+ isStartExec: false,
1973
+ isSnapshotCaptured: false
1924
1974
  };
1925
1975
  };
1926
1976
  function executeCommand(command7) {
@@ -1945,7 +1995,7 @@ function isGitRepo() {
1945
1995
  }
1946
1996
  var git_default = (ctx) => {
1947
1997
  if (ctx.env.SMARTUI_GIT_INFO_FILEPATH) {
1948
- let gitInfo = JSON.parse(fs6__default.default.readFileSync(ctx.env.SMARTUI_GIT_INFO_FILEPATH, "utf-8"));
1998
+ let gitInfo = JSON.parse(fs5__default.default.readFileSync(ctx.env.SMARTUI_GIT_INFO_FILEPATH, "utf-8"));
1949
1999
  return {
1950
2000
  branch: ctx.env.CURRENT_BRANCH || gitInfo.branch || "",
1951
2001
  commitId: gitInfo.commit_id.slice(0, 6) || "",
@@ -2123,10 +2173,11 @@ var finalizeBuild_default = (ctx) => {
2123
2173
  ctx2.log.debug(`Closed browser`);
2124
2174
  yield (_b = ctx2.server) == null ? void 0 : _b.close();
2125
2175
  ctx2.log.debug(`Closed server`);
2126
- let resp = yield ctx2.client.getS3PreSignedURL(ctx2);
2127
- yield ctx2.client.uploadLogs(ctx2, resp.data.url);
2128
- fs6__default.default.unlinkSync(constants_default.LOG_FILE_PATH);
2129
- ctx2.log.debug(`Log file deleted: ${constants_default.LOG_FILE_PATH}`);
2176
+ if (ctx2.isSnapshotCaptured) {
2177
+ ctx2.log.debug(`Log file to be uploaded`);
2178
+ let resp = yield ctx2.client.getS3PreSignedURL(ctx2);
2179
+ yield ctx2.client.uploadLogs(ctx2, resp.data.url);
2180
+ }
2130
2181
  } catch (error) {
2131
2182
  ctx2.log.debug(error);
2132
2183
  }
@@ -2134,10 +2185,11 @@ var finalizeBuild_default = (ctx) => {
2134
2185
  rendererOptions: { persistentOutput: true }
2135
2186
  };
2136
2187
  };
2188
+ var globalCache = new NodeCache__default.default({ stdTTL: 3600, checkperiod: 600 });
2137
2189
  var MAX_RESOURCE_SIZE = 15 * 1024 ** 2;
2138
2190
  var ALLOWED_RESOURCES = ["document", "stylesheet", "image", "media", "font", "other"];
2139
2191
  var ALLOWED_STATUSES = [200, 201];
2140
- var REQUEST_TIMEOUT = 1e4;
2192
+ var REQUEST_TIMEOUT = 18e5;
2141
2193
  var MIN_VIEWPORT_HEIGHT = 1080;
2142
2194
  function processSnapshot(snapshot, ctx) {
2143
2195
  return __async(this, null, function* () {
@@ -2151,7 +2203,8 @@ function processSnapshot(snapshot, ctx) {
2151
2203
  };
2152
2204
  let contextOptions = {
2153
2205
  javaScriptEnabled: ctx.config.cliEnableJavaScript,
2154
- userAgent: constants_default.CHROME_USER_AGENT
2206
+ userAgent: constants_default.CHROME_USER_AGENT,
2207
+ ignoreHTTPSErrors: ctx.config.ignoreHTTPSErrors
2155
2208
  };
2156
2209
  if (!((_b = ctx.browser) == null ? void 0 : _b.isConnected())) {
2157
2210
  if (ctx.env.HTTP_PROXY || ctx.env.HTTPS_PROXY)
@@ -2228,7 +2281,15 @@ function processSnapshot(snapshot, ctx) {
2228
2281
  headers: () => ({ "content-type": cache[requestUrl].mimetype })
2229
2282
  };
2230
2283
  body = cache[requestUrl].body;
2284
+ } else if (ctx.config.useGlobalCache && globalCache.has(requestUrl)) {
2285
+ ctx.log.debug(`Found resource ${requestUrl} in global cache`);
2286
+ response = {
2287
+ status: () => 200,
2288
+ headers: () => ({ "content-type": globalCache.get(requestUrl).type })
2289
+ };
2290
+ body = globalCache.get(requestUrl).body;
2231
2291
  } else {
2292
+ ctx.log.debug(`Resource not found in cache or global cache ${requestUrl} fetching from server`);
2232
2293
  response = yield page.request.fetch(request, requestOptions);
2233
2294
  body = yield response.body();
2234
2295
  }
@@ -2259,6 +2320,12 @@ function processSnapshot(snapshot, ctx) {
2259
2320
  } else {
2260
2321
  ctx.log.debug(`Handling request ${requestUrl}
2261
2322
  - content-type ${response.headers()["content-type"]}`);
2323
+ if (ctx.config.useGlobalCache) {
2324
+ globalCache.set(requestUrl, {
2325
+ body: body.toString("base64"),
2326
+ type: response.headers()["content-type"]
2327
+ });
2328
+ }
2262
2329
  cache[requestUrl] = {
2263
2330
  body: body.toString("base64"),
2264
2331
  type: response.headers()["content-type"]
@@ -2377,7 +2444,7 @@ function processSnapshot(snapshot, ctx) {
2377
2444
  ctx.log.debug(`Page resized to ${viewport.width}x${viewport.height || MIN_VIEWPORT_HEIGHT}`);
2378
2445
  if (!navigated) {
2379
2446
  try {
2380
- yield page.goto(snapshot.url, { waitUntil: "domcontentloaded" });
2447
+ yield page.goto(snapshot.url, { waitUntil: "domcontentloaded", timeout: ctx.config.waitForDiscovery });
2381
2448
  yield new Promise((r) => setTimeout(r, 1250));
2382
2449
  if (ctx.config.waitForTimeout)
2383
2450
  yield page.waitForTimeout(ctx.config.waitForTimeout);
@@ -2810,13 +2877,13 @@ function createConfig(filepath) {
2810
2877
  console.log("Error: Config file must have .json extension");
2811
2878
  return;
2812
2879
  }
2813
- if (fs6__default.default.existsSync(filepath)) {
2880
+ if (fs5__default.default.existsSync(filepath)) {
2814
2881
  console.log(`Error: SmartUI Config already exists: ${filepath}`);
2815
2882
  console.log(`To create a new file, please specify the file name like: 'smartui config:create .smartui-config.json'`);
2816
2883
  return;
2817
2884
  }
2818
- fs6__default.default.mkdirSync(path2__default.default.dirname(filepath), { recursive: true });
2819
- fs6__default.default.writeFileSync(filepath, JSON.stringify(constants_default.DEFAULT_CONFIG, null, 2) + "\n");
2885
+ fs5__default.default.mkdirSync(path2__default.default.dirname(filepath), { recursive: true });
2886
+ fs5__default.default.writeFileSync(filepath, JSON.stringify(constants_default.DEFAULT_CONFIG, null, 2) + "\n");
2820
2887
  console.log(`Created SmartUI Config: ${filepath}`);
2821
2888
  }
2822
2889
  function createWebStaticConfig(filepath) {
@@ -2826,13 +2893,13 @@ function createWebStaticConfig(filepath) {
2826
2893
  console.log("Error: Config file must have .json extension");
2827
2894
  return;
2828
2895
  }
2829
- if (fs6__default.default.existsSync(filepath)) {
2896
+ if (fs5__default.default.existsSync(filepath)) {
2830
2897
  console.log(`Error: web-static config already exists: ${filepath}`);
2831
2898
  console.log(`To create a new file, please specify the file name like: 'smartui config:create-web-static links.json'`);
2832
2899
  return;
2833
2900
  }
2834
- fs6__default.default.mkdirSync(path2__default.default.dirname(filepath), { recursive: true });
2835
- fs6__default.default.writeFileSync(filepath, JSON.stringify(constants_default.DEFAULT_WEB_STATIC_CONFIG, null, 2) + "\n");
2901
+ fs5__default.default.mkdirSync(path2__default.default.dirname(filepath), { recursive: true });
2902
+ fs5__default.default.writeFileSync(filepath, JSON.stringify(constants_default.DEFAULT_WEB_STATIC_CONFIG, null, 2) + "\n");
2836
2903
  console.log(`Created web-static config: ${filepath}`);
2837
2904
  }
2838
2905
  function createFigmaConfig(filepath) {
@@ -2842,13 +2909,13 @@ function createFigmaConfig(filepath) {
2842
2909
  console.log("Error: designs config file must have .json extension");
2843
2910
  return;
2844
2911
  }
2845
- if (fs6__default.default.existsSync(filepath)) {
2912
+ if (fs5__default.default.existsSync(filepath)) {
2846
2913
  console.log(`Error: designs config already exists: ${filepath}`);
2847
2914
  console.log(`To create a new file, please specify the file name like: 'smartui config:figma-config designs.json'`);
2848
2915
  return;
2849
2916
  }
2850
- fs6__default.default.mkdirSync(path2__default.default.dirname(filepath), { recursive: true });
2851
- fs6__default.default.writeFileSync(filepath, JSON.stringify(constants_default.DEFAULT_FIGMA_CONFIG, null, 2) + "\n");
2917
+ fs5__default.default.mkdirSync(path2__default.default.dirname(filepath), { recursive: true });
2918
+ fs5__default.default.writeFileSync(filepath, JSON.stringify(constants_default.DEFAULT_FIGMA_CONFIG, null, 2) + "\n");
2852
2919
  console.log(`Created designs config: ${filepath}`);
2853
2920
  }
2854
2921
  function createWebFigmaConfig(filepath) {
@@ -2858,13 +2925,13 @@ function createWebFigmaConfig(filepath) {
2858
2925
  console.log("Error: figma config file must have .json extension");
2859
2926
  return;
2860
2927
  }
2861
- if (fs6__default.default.existsSync(filepath)) {
2928
+ if (fs5__default.default.existsSync(filepath)) {
2862
2929
  console.log(`Error: figma config already exists: ${filepath}`);
2863
2930
  console.log(`To create a new file, please specify the file name like: 'smartui config:create-figma-web <fileName>.json'`);
2864
2931
  return;
2865
2932
  }
2866
- fs6__default.default.mkdirSync(path2__default.default.dirname(filepath), { recursive: true });
2867
- fs6__default.default.writeFileSync(filepath, JSON.stringify(constants_default.WEB_FIGMA_CONFIG, null, 2) + "\n");
2933
+ fs5__default.default.mkdirSync(path2__default.default.dirname(filepath), { recursive: true });
2934
+ fs5__default.default.writeFileSync(filepath, JSON.stringify(constants_default.WEB_FIGMA_CONFIG, null, 2) + "\n");
2868
2935
  console.log(`Created figma web config: ${filepath}`);
2869
2936
  }
2870
2937
  function verifyFigmaWebConfig(ctx) {
@@ -3044,7 +3111,7 @@ function captureScreenshots(ctx) {
3044
3111
  });
3045
3112
  }
3046
3113
  function getImageDimensions(filePath) {
3047
- const buffer = fs6__default.default.readFileSync(filePath);
3114
+ const buffer = fs5__default.default.readFileSync(filePath);
3048
3115
  let width, height;
3049
3116
  if (buffer.toString("hex", 0, 2) === "ffd8") {
3050
3117
  let offset = 2;
@@ -3069,7 +3136,7 @@ function getImageDimensions(filePath) {
3069
3136
  function isAllowedImage(filePath) {
3070
3137
  return __async(this, null, function* () {
3071
3138
  try {
3072
- const fileBuffer = fs6__default.default.readFileSync(filePath);
3139
+ const fileBuffer = fs5__default.default.readFileSync(filePath);
3073
3140
  const isMagicValid = constants_default.MAGIC_NUMBERS.some((magic) => fileBuffer.slice(0, magic.magic.length).equals(magic.magic));
3074
3141
  const metadata = yield sharp__default.default(filePath).metadata();
3075
3142
  if (metadata.format === constants_default.FILE_EXTENSION_GIFS) {
@@ -3093,10 +3160,10 @@ function uploadScreenshots(ctx) {
3093
3160
  let noOfScreenshots = 0;
3094
3161
  function processDirectory(directory, relativePath = "") {
3095
3162
  return __async(this, null, function* () {
3096
- const files = fs6__default.default.readdirSync(directory);
3163
+ const files = fs5__default.default.readdirSync(directory);
3097
3164
  for (let file of files) {
3098
3165
  const filePath = path2__default.default.join(directory, file);
3099
- const stat = fs6__default.default.statSync(filePath);
3166
+ const stat = fs5__default.default.statSync(filePath);
3100
3167
  const relativeFilePath = path2__default.default.join(relativePath, file);
3101
3168
  if (stat.isDirectory() && ctx.options.ignorePattern.includes(relativeFilePath)) {
3102
3169
  ctx.log.info(`Ignoring Directory ${relativeFilePath}`);
@@ -3251,7 +3318,7 @@ var captureScreenshots_default = (ctx) => {
3251
3318
  try {
3252
3319
  ctx2.task = task;
3253
3320
  if (ctx2.options.fetchResults) {
3254
- startPolling(ctx2, task);
3321
+ startPolling(ctx2);
3255
3322
  }
3256
3323
  updateLogContext({ task: "capture" });
3257
3324
  if (ctx2.options.parallel) {
@@ -3288,12 +3355,13 @@ command2.name("capture").description("Capture screenshots of static sites").argu
3288
3355
  process.exit(1);
3289
3356
  }
3290
3357
  let ctx = ctx_default(command7.optsWithGlobals());
3291
- if (!fs6__default.default.existsSync(file)) {
3358
+ ctx.isSnapshotCaptured = true;
3359
+ if (!fs5__default.default.existsSync(file)) {
3292
3360
  ctx.log.error(`Web Static Config file ${file} not found.`);
3293
3361
  return;
3294
3362
  }
3295
3363
  try {
3296
- ctx.webStaticConfig = JSON.parse(fs6__default.default.readFileSync(file, "utf8"));
3364
+ ctx.webStaticConfig = JSON.parse(fs5__default.default.readFileSync(file, "utf8"));
3297
3365
  if (!validateWebStaticConfig(ctx.webStaticConfig)) {
3298
3366
  ctx.log.debug(JSON.stringify(validateWebStaticConfig.errors, null, 2));
3299
3367
  (_a = validateWebStaticConfig.errors) == null ? void 0 : _a.forEach((error) => {
@@ -3349,7 +3417,7 @@ var uploadScreenshots_default = (ctx) => {
3349
3417
  try {
3350
3418
  ctx2.task = task;
3351
3419
  if (ctx2.options.fetchResults) {
3352
- startPolling(ctx2, task);
3420
+ startPolling(ctx2);
3353
3421
  }
3354
3422
  updateLogContext({ task: "upload" });
3355
3423
  yield uploadScreenshots(ctx2);
@@ -3379,7 +3447,8 @@ command3.name("upload").description("Upload screenshots from given directory").a
3379
3447
  process.exit(1);
3380
3448
  }
3381
3449
  let ctx = ctx_default(command7.optsWithGlobals());
3382
- if (!fs6__default.default.existsSync(directory)) {
3450
+ ctx.isSnapshotCaptured = true;
3451
+ if (!fs5__default.default.existsSync(directory)) {
3383
3452
  console.log(`Error: The provided directory ${directory} not found.`);
3384
3453
  return;
3385
3454
  }
@@ -3489,7 +3558,8 @@ var uploadWebFigma_default = (ctx) => __async(void 0, null, function* () {
3489
3558
  results = responseData.data.message;
3490
3559
  ctx.build = {
3491
3560
  id: responseData.data.buildId,
3492
- url: responseData.data.buildURL || "https://smartui.lambdatestinternal.com"
3561
+ url: responseData.data.buildURL || "https://smartui.lambdatestinternal.com",
3562
+ baseline: responseData.data.baseline ? responseData.data.baseline : false
3493
3563
  };
3494
3564
  }
3495
3565
  } else {
@@ -3559,6 +3629,9 @@ var uploadWebFigma_default2 = (ctx) => {
3559
3629
  let output = JSON.stringify(jsonObject, null, 2);
3560
3630
  task.output = task.output + "\n" + chalk__default.default.green(`${output}`);
3561
3631
  }
3632
+ if (ctx2.options.fetchResults) {
3633
+ startPolling(ctx2);
3634
+ }
3562
3635
  task.title = "Web Figma images uploaded successfully to SmartUI";
3563
3636
  ctx2.log.debug(`Web Figma processed: ${results}`);
3564
3637
  } catch (error) {
@@ -3577,12 +3650,13 @@ uploadFigma.name("upload-figma").description("Capture screenshots of static site
3577
3650
  return __async(this, null, function* () {
3578
3651
  var _a, _b;
3579
3652
  let ctx = ctx_default(command7.optsWithGlobals());
3580
- if (!fs6__default.default.existsSync(file)) {
3653
+ ctx.isSnapshotCaptured = true;
3654
+ if (!fs5__default.default.existsSync(file)) {
3581
3655
  console.log(`Error: Figma Config file ${file} not found.`);
3582
3656
  return;
3583
3657
  }
3584
3658
  try {
3585
- ctx.figmaDesignConfig = JSON.parse(fs6__default.default.readFileSync(file, "utf8"));
3659
+ ctx.figmaDesignConfig = JSON.parse(fs5__default.default.readFileSync(file, "utf8"));
3586
3660
  if (!validateFigmaDesignConfig(ctx.figmaDesignConfig)) {
3587
3661
  const validationError = (_b = (_a = validateFigmaDesignConfig.errors) == null ? void 0 : _a[0]) == null ? void 0 : _b.message;
3588
3662
  throw new Error(validationError || "Invalid figma design Config");
@@ -3614,16 +3688,16 @@ uploadFigma.name("upload-figma").description("Capture screenshots of static site
3614
3688
  }
3615
3689
  });
3616
3690
  });
3617
- 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, _, command7) {
3691
+ 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").option("--fetch-results [filename]", "Fetch results and optionally specify an output file, e.g., <filename>.json").action(function(file, _, command7) {
3618
3692
  return __async(this, null, function* () {
3619
3693
  var _a;
3620
3694
  let ctx = ctx_default(command7.optsWithGlobals());
3621
- if (!fs6__default.default.existsSync(file)) {
3695
+ if (!fs5__default.default.existsSync(file)) {
3622
3696
  console.log(`Error: figma-web config file ${file} not found.`);
3623
3697
  return;
3624
3698
  }
3625
3699
  try {
3626
- ctx.config = JSON.parse(fs6__default.default.readFileSync(file, "utf8"));
3700
+ ctx.config = JSON.parse(fs5__default.default.readFileSync(file, "utf8"));
3627
3701
  ctx.log.info(JSON.stringify(ctx.config));
3628
3702
  if (!validateWebFigmaConfig(ctx.config)) {
3629
3703
  ctx.log.debug(JSON.stringify(validateWebFigmaConfig.errors, null, 2));
@@ -3778,6 +3852,7 @@ var commander_default = program;
3778
3852
  let client = new httpClient(env_default());
3779
3853
  let log2 = logger_default;
3780
3854
  try {
3855
+ fs5__default.default.unlinkSync(constants_default.LOG_FILE_PATH);
3781
3856
  let { data: { latestVersion, deprecated, additionalDescription } } = yield client.checkUpdate(log2);
3782
3857
  log2.info(`
3783
3858
  LambdaTest SmartUI CLI v${package_default.version}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lambdatest/smartui-cli",
3
- "version": "4.1.0",
3
+ "version": "4.1.2-beta.0",
4
4
  "description": "A command line interface (CLI) to run SmartUI tests on LambdaTest",
5
5
  "files": [
6
6
  "dist/**/*"
@@ -33,6 +33,7 @@
33
33
  "fastify": "^4.24.3",
34
34
  "form-data": "^4.0.0",
35
35
  "listr2": "^7.0.1",
36
+ "node-cache": "^5.1.2",
36
37
  "sharp": "^0.33.4",
37
38
  "tsup": "^7.2.0",
38
39
  "uuid": "^11.0.3",
@@ -45,6 +46,7 @@
45
46
  "scripts": {
46
47
  "build": "tsup",
47
48
  "release": "pnpm run build && pnpm publish --access public --no-git-checks",
49
+ "release:beta": "pnpm run build && pnpm publish --tag beta --access public --no-git-checks",
48
50
  "local-build": "pnpm run build && pnpm pack"
49
51
  }
50
52
  }