@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.
- package/dist/index.cjs +132 -57
- 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
|
|
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
|
|
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 (
|
|
982
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
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 =
|
|
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 =
|
|
1758
|
-
const { size } =
|
|
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(
|
|
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(
|
|
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
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
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 =
|
|
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 (
|
|
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
|
-
|
|
2819
|
-
|
|
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 (
|
|
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
|
-
|
|
2835
|
-
|
|
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 (
|
|
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
|
-
|
|
2851
|
-
|
|
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 (
|
|
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
|
-
|
|
2867
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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(
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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 (!
|
|
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(
|
|
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
|
}
|