@lambdatest/smartui-cli 4.0.20 → 4.0.21
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 +654 -500
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -4,25 +4,27 @@
|
|
|
4
4
|
var commander = require('commander');
|
|
5
5
|
var which = require('which');
|
|
6
6
|
var listr2 = require('listr2');
|
|
7
|
-
var
|
|
7
|
+
var chalk = require('chalk');
|
|
8
8
|
var path2 = require('path');
|
|
9
9
|
var fastify = require('fastify');
|
|
10
10
|
var fs5 = require('fs');
|
|
11
11
|
var Ajv = require('ajv');
|
|
12
12
|
var addErrors = require('ajv-errors');
|
|
13
|
+
var test = require('@playwright/test');
|
|
14
|
+
var util = require('util');
|
|
13
15
|
var winston = require('winston');
|
|
14
16
|
var FormData = require('form-data');
|
|
15
17
|
var axios = require('axios');
|
|
18
|
+
var https = require('https');
|
|
16
19
|
var child_process = require('child_process');
|
|
17
20
|
var spawn = require('cross-spawn');
|
|
18
|
-
var test = require('@playwright/test');
|
|
19
21
|
var uuid = require('uuid');
|
|
20
22
|
var sharp = require('sharp');
|
|
21
23
|
|
|
22
24
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
23
25
|
|
|
24
26
|
var which__default = /*#__PURE__*/_interopDefault(which);
|
|
25
|
-
var
|
|
27
|
+
var chalk__default = /*#__PURE__*/_interopDefault(chalk);
|
|
26
28
|
var path2__default = /*#__PURE__*/_interopDefault(path2);
|
|
27
29
|
var fastify__default = /*#__PURE__*/_interopDefault(fastify);
|
|
28
30
|
var fs5__default = /*#__PURE__*/_interopDefault(fs5);
|
|
@@ -30,6 +32,7 @@ var Ajv__default = /*#__PURE__*/_interopDefault(Ajv);
|
|
|
30
32
|
var addErrors__default = /*#__PURE__*/_interopDefault(addErrors);
|
|
31
33
|
var FormData__default = /*#__PURE__*/_interopDefault(FormData);
|
|
32
34
|
var axios__default = /*#__PURE__*/_interopDefault(axios);
|
|
35
|
+
var https__default = /*#__PURE__*/_interopDefault(https);
|
|
33
36
|
var spawn__default = /*#__PURE__*/_interopDefault(spawn);
|
|
34
37
|
var sharp__default = /*#__PURE__*/_interopDefault(sharp);
|
|
35
38
|
|
|
@@ -416,7 +419,6 @@ var constants_default = {
|
|
|
416
419
|
"Xperia 10 IV": { os: "android", viewport: { width: 412, height: 832 } },
|
|
417
420
|
"Honeywell CT40": { os: "android", viewport: { width: 360, height: 512 } }
|
|
418
421
|
},
|
|
419
|
-
FIGMA_API: "https://api.figma.com/v1/",
|
|
420
422
|
DEFAULT_FIGMA_CONFIG: {
|
|
421
423
|
"depth": 2,
|
|
422
424
|
"figma_config": [
|
|
@@ -961,9 +963,285 @@ var validateWebStaticConfig = ajv.compile(WebStaticConfigSchema);
|
|
|
961
963
|
var validateSnapshot = ajv.compile(SnapshotSchema);
|
|
962
964
|
var validateFigmaDesignConfig = ajv.compile(FigmaDesignConfigSchema);
|
|
963
965
|
var validateWebFigmaConfig = ajv.compile(FigmaWebConfigSchema);
|
|
966
|
+
util.promisify(setTimeout);
|
|
967
|
+
var isPollingActive = false;
|
|
968
|
+
function delDir(dir) {
|
|
969
|
+
if (fs5__default.default.existsSync(dir)) {
|
|
970
|
+
fs5__default.default.rmSync(dir, { recursive: true });
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
function scrollToBottomAndBackToTop({
|
|
974
|
+
frequency = 100,
|
|
975
|
+
timing = 8,
|
|
976
|
+
remoteWindow = window
|
|
977
|
+
} = {}) {
|
|
978
|
+
return new Promise((resolve) => {
|
|
979
|
+
let scrolls = 1;
|
|
980
|
+
let scrollLength = remoteWindow.document.body.scrollHeight / frequency;
|
|
981
|
+
(function scroll() {
|
|
982
|
+
let scrollBy = scrollLength * scrolls;
|
|
983
|
+
remoteWindow.setTimeout(() => {
|
|
984
|
+
remoteWindow.scrollTo(0, scrollBy);
|
|
985
|
+
if (scrolls < frequency) {
|
|
986
|
+
scrolls += 1;
|
|
987
|
+
scroll();
|
|
988
|
+
}
|
|
989
|
+
if (scrolls === frequency) {
|
|
990
|
+
remoteWindow.setTimeout(() => {
|
|
991
|
+
remoteWindow.scrollTo(0, 0);
|
|
992
|
+
resolve();
|
|
993
|
+
}, timing);
|
|
994
|
+
}
|
|
995
|
+
}, timing);
|
|
996
|
+
})();
|
|
997
|
+
});
|
|
998
|
+
}
|
|
999
|
+
function launchBrowsers(ctx) {
|
|
1000
|
+
return __async(this, null, function* () {
|
|
1001
|
+
var _a;
|
|
1002
|
+
let browsers = {};
|
|
1003
|
+
const isHeadless = ((_a = process.env.HEADLESS) == null ? void 0 : _a.toLowerCase()) === "false" ? false : true;
|
|
1004
|
+
let launchOptions = { headless: isHeadless };
|
|
1005
|
+
if (ctx.config.web) {
|
|
1006
|
+
for (const browser of ctx.config.web.browsers) {
|
|
1007
|
+
switch (browser) {
|
|
1008
|
+
case constants_default.CHROME:
|
|
1009
|
+
browsers[constants_default.CHROME] = yield test.chromium.launch(launchOptions);
|
|
1010
|
+
break;
|
|
1011
|
+
case constants_default.SAFARI:
|
|
1012
|
+
browsers[constants_default.SAFARI] = yield test.webkit.launch(launchOptions);
|
|
1013
|
+
break;
|
|
1014
|
+
case constants_default.FIREFOX:
|
|
1015
|
+
browsers[constants_default.FIREFOX] = yield test.firefox.launch(launchOptions);
|
|
1016
|
+
break;
|
|
1017
|
+
case constants_default.EDGE:
|
|
1018
|
+
launchOptions.args = ["--headless=new"];
|
|
1019
|
+
browsers[constants_default.EDGE] = yield test.chromium.launch(__spreadValues({ channel: constants_default.EDGE_CHANNEL }, launchOptions));
|
|
1020
|
+
break;
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
if (ctx.config.mobile) {
|
|
1025
|
+
for (const device of ctx.config.mobile.devices) {
|
|
1026
|
+
if (constants_default.SUPPORTED_MOBILE_DEVICES[device].os === "android" && !browsers[constants_default.CHROME])
|
|
1027
|
+
browsers[constants_default.CHROME] = yield test.chromium.launch(launchOptions);
|
|
1028
|
+
else if (constants_default.SUPPORTED_MOBILE_DEVICES[device].os === "ios" && !browsers[constants_default.SAFARI])
|
|
1029
|
+
browsers[constants_default.SAFARI] = yield test.webkit.launch(launchOptions);
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
return browsers;
|
|
1033
|
+
});
|
|
1034
|
+
}
|
|
1035
|
+
function closeBrowsers(browsers) {
|
|
1036
|
+
return __async(this, null, function* () {
|
|
1037
|
+
var _a;
|
|
1038
|
+
for (const browserName of Object.keys(browsers))
|
|
1039
|
+
yield (_a = browsers[browserName]) == null ? void 0 : _a.close();
|
|
1040
|
+
});
|
|
1041
|
+
}
|
|
1042
|
+
function getWebRenderViewports(ctx) {
|
|
1043
|
+
let webRenderViewports = [];
|
|
1044
|
+
if (ctx.config.web) {
|
|
1045
|
+
for (const viewport of ctx.config.web.viewports) {
|
|
1046
|
+
webRenderViewports.push({
|
|
1047
|
+
viewport,
|
|
1048
|
+
viewportString: `${viewport.width}${viewport.height ? "x" + viewport.height : ""}`,
|
|
1049
|
+
fullPage: viewport.height ? false : true,
|
|
1050
|
+
device: false
|
|
1051
|
+
});
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
return webRenderViewports;
|
|
1055
|
+
}
|
|
1056
|
+
function getWebRenderViewportsForOptions(options) {
|
|
1057
|
+
let webRenderViewports = [];
|
|
1058
|
+
if (options.web && Array.isArray(options.web.viewports)) {
|
|
1059
|
+
for (const viewport of options.web.viewports) {
|
|
1060
|
+
if (Array.isArray(viewport) && viewport.length > 0) {
|
|
1061
|
+
let viewportObj = {
|
|
1062
|
+
width: viewport[0]
|
|
1063
|
+
};
|
|
1064
|
+
if (viewport.length > 1) {
|
|
1065
|
+
viewportObj.height = viewport[1];
|
|
1066
|
+
}
|
|
1067
|
+
webRenderViewports.push({
|
|
1068
|
+
viewport: viewportObj,
|
|
1069
|
+
viewportString: `${viewport[0]}${viewport[1] ? "x" + viewport[1] : ""}`,
|
|
1070
|
+
fullPage: viewport.length === 1,
|
|
1071
|
+
device: false
|
|
1072
|
+
});
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
return webRenderViewports;
|
|
1077
|
+
}
|
|
1078
|
+
function getMobileRenderViewports(ctx) {
|
|
1079
|
+
var _a;
|
|
1080
|
+
let mobileRenderViewports = {};
|
|
1081
|
+
mobileRenderViewports[constants_default.MOBILE_OS_IOS] = [];
|
|
1082
|
+
mobileRenderViewports[constants_default.MOBILE_OS_ANDROID] = [];
|
|
1083
|
+
if (ctx.config.mobile) {
|
|
1084
|
+
for (const device of ctx.config.mobile.devices) {
|
|
1085
|
+
let os = constants_default.SUPPORTED_MOBILE_DEVICES[device].os;
|
|
1086
|
+
let { width, height } = constants_default.SUPPORTED_MOBILE_DEVICES[device].viewport;
|
|
1087
|
+
let portrait = ctx.config.mobile.orientation === constants_default.MOBILE_ORIENTATION_PORTRAIT ? true : false;
|
|
1088
|
+
(_a = mobileRenderViewports[os]) == null ? void 0 : _a.push({
|
|
1089
|
+
viewport: { width: portrait ? width : height, height: portrait ? height : width },
|
|
1090
|
+
viewportString: `${device} (${ctx.config.mobile.orientation})`,
|
|
1091
|
+
fullPage: ctx.config.mobile.fullPage,
|
|
1092
|
+
device: true,
|
|
1093
|
+
os
|
|
1094
|
+
});
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
return mobileRenderViewports;
|
|
1098
|
+
}
|
|
1099
|
+
function getMobileRenderViewportsForOptions(options) {
|
|
1100
|
+
var _a;
|
|
1101
|
+
let mobileRenderViewports = {};
|
|
1102
|
+
mobileRenderViewports[constants_default.MOBILE_OS_IOS] = [];
|
|
1103
|
+
mobileRenderViewports[constants_default.MOBILE_OS_ANDROID] = [];
|
|
1104
|
+
if (options.mobile) {
|
|
1105
|
+
for (const device of options.mobile.devices) {
|
|
1106
|
+
let os = constants_default.SUPPORTED_MOBILE_DEVICES[device].os;
|
|
1107
|
+
let { width, height } = constants_default.SUPPORTED_MOBILE_DEVICES[device].viewport;
|
|
1108
|
+
let orientation = options.mobile.orientation || constants_default.MOBILE_ORIENTATION_PORTRAIT;
|
|
1109
|
+
let portrait = orientation === constants_default.MOBILE_ORIENTATION_PORTRAIT;
|
|
1110
|
+
let fullPage;
|
|
1111
|
+
if (options.mobile.fullPage === void 0 || options.mobile.fullPage) {
|
|
1112
|
+
fullPage = true;
|
|
1113
|
+
} else {
|
|
1114
|
+
fullPage = false;
|
|
1115
|
+
}
|
|
1116
|
+
(_a = mobileRenderViewports[os]) == null ? void 0 : _a.push({
|
|
1117
|
+
viewport: { width: portrait ? width : height, height: portrait ? height : width },
|
|
1118
|
+
viewportString: `${device} (${orientation})`,
|
|
1119
|
+
fullPage,
|
|
1120
|
+
device: true,
|
|
1121
|
+
os
|
|
1122
|
+
});
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
return mobileRenderViewports;
|
|
1126
|
+
}
|
|
1127
|
+
function getRenderViewports(ctx) {
|
|
1128
|
+
let mobileRenderViewports = getMobileRenderViewports(ctx);
|
|
1129
|
+
let webRenderViewports = getWebRenderViewports(ctx);
|
|
1130
|
+
return [
|
|
1131
|
+
...webRenderViewports,
|
|
1132
|
+
...mobileRenderViewports[constants_default.MOBILE_OS_IOS],
|
|
1133
|
+
...mobileRenderViewports[constants_default.MOBILE_OS_ANDROID]
|
|
1134
|
+
];
|
|
1135
|
+
}
|
|
1136
|
+
function getRenderViewportsForOptions(options) {
|
|
1137
|
+
let mobileRenderViewports = getMobileRenderViewportsForOptions(options);
|
|
1138
|
+
let webRenderViewports = getWebRenderViewportsForOptions(options);
|
|
1139
|
+
return [
|
|
1140
|
+
...webRenderViewports,
|
|
1141
|
+
...mobileRenderViewports[constants_default.MOBILE_OS_IOS],
|
|
1142
|
+
...mobileRenderViewports[constants_default.MOBILE_OS_ANDROID]
|
|
1143
|
+
];
|
|
1144
|
+
}
|
|
1145
|
+
process.on("SIGINT", () => __async(void 0, null, function* () {
|
|
1146
|
+
if (isPollingActive) {
|
|
1147
|
+
console.log("Fetching results interrupted. Exiting...");
|
|
1148
|
+
isPollingActive = false;
|
|
1149
|
+
} else {
|
|
1150
|
+
console.log("\nExiting gracefully...");
|
|
1151
|
+
}
|
|
1152
|
+
process.exit(0);
|
|
1153
|
+
}));
|
|
1154
|
+
function startPolling(ctx) {
|
|
1155
|
+
return __async(this, null, function* () {
|
|
1156
|
+
ctx.log.info("Fetching results in progress....");
|
|
1157
|
+
isPollingActive = true;
|
|
1158
|
+
const intervalId = setInterval(() => __async(this, null, function* () {
|
|
1159
|
+
if (!isPollingActive) {
|
|
1160
|
+
clearInterval(intervalId);
|
|
1161
|
+
return;
|
|
1162
|
+
}
|
|
1163
|
+
try {
|
|
1164
|
+
const resp = yield ctx.client.getScreenshotData(ctx.build.id, ctx.build.baseline, ctx.log);
|
|
1165
|
+
if (!resp.build) {
|
|
1166
|
+
ctx.log.info("Error: Build data is null.");
|
|
1167
|
+
clearInterval(intervalId);
|
|
1168
|
+
isPollingActive = false;
|
|
1169
|
+
}
|
|
1170
|
+
fs5__default.default.writeFileSync(ctx.options.fetchResultsFileName, JSON.stringify(resp, null, 2));
|
|
1171
|
+
ctx.log.debug(`Updated results in ${ctx.options.fetchResultsFileName}`);
|
|
1172
|
+
if (resp.build.build_status_ind === constants_default.BUILD_COMPLETE || resp.build.build_status_ind === constants_default.BUILD_ERROR) {
|
|
1173
|
+
clearInterval(intervalId);
|
|
1174
|
+
ctx.log.info(`Fetching results completed. Final results written to ${ctx.options.fetchResultsFileName}`);
|
|
1175
|
+
isPollingActive = false;
|
|
1176
|
+
let totalScreenshotsWithMismatches = 0;
|
|
1177
|
+
let totalVariantsWithMismatches = 0;
|
|
1178
|
+
const totalScreenshots = Object.keys(resp.screenshots || {}).length;
|
|
1179
|
+
let totalVariants = 0;
|
|
1180
|
+
for (const [screenshot, variants] of Object.entries(resp.screenshots || {})) {
|
|
1181
|
+
let screenshotHasMismatch = false;
|
|
1182
|
+
let variantMismatchCount = 0;
|
|
1183
|
+
totalVariants += variants.length;
|
|
1184
|
+
for (const variant of variants) {
|
|
1185
|
+
if (variant.mismatch_percentage > 0) {
|
|
1186
|
+
screenshotHasMismatch = true;
|
|
1187
|
+
variantMismatchCount++;
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
if (screenshotHasMismatch) {
|
|
1191
|
+
totalScreenshotsWithMismatches++;
|
|
1192
|
+
totalVariantsWithMismatches += variantMismatchCount;
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
ctx.log.info(
|
|
1196
|
+
chalk__default.default.green.bold(
|
|
1197
|
+
`
|
|
1198
|
+
Summary of Mismatches:
|
|
1199
|
+
${chalk__default.default.yellow("Total Variants with Mismatches:")} ${chalk__default.default.white(totalVariantsWithMismatches)} out of ${chalk__default.default.white(totalVariants)}
|
|
1200
|
+
${chalk__default.default.yellow("Total Screenshots with Mismatches:")} ${chalk__default.default.white(totalScreenshotsWithMismatches)} out of ${chalk__default.default.white(totalScreenshots)}
|
|
1201
|
+
${chalk__default.default.yellow("Branch Name:")} ${chalk__default.default.white(resp.build.branch)}
|
|
1202
|
+
${chalk__default.default.yellow("Project Name:")} ${chalk__default.default.white(resp.project.name)}
|
|
1203
|
+
${chalk__default.default.yellow("Build ID:")} ${chalk__default.default.white(resp.build.build_id)}
|
|
1204
|
+
`
|
|
1205
|
+
)
|
|
1206
|
+
);
|
|
1207
|
+
}
|
|
1208
|
+
} catch (error) {
|
|
1209
|
+
if (error.message.includes("ENOTFOUND")) {
|
|
1210
|
+
ctx.log.error("Error: Network error occurred while fetching build results. Please check your connection and try again.");
|
|
1211
|
+
clearInterval(intervalId);
|
|
1212
|
+
} else {
|
|
1213
|
+
ctx.log.error(`Error fetching screenshot data: ${error.message}`);
|
|
1214
|
+
}
|
|
1215
|
+
clearInterval(intervalId);
|
|
1216
|
+
isPollingActive = false;
|
|
1217
|
+
}
|
|
1218
|
+
}), 5e3);
|
|
1219
|
+
});
|
|
1220
|
+
}
|
|
1221
|
+
var pingIntervalId = null;
|
|
1222
|
+
function startPingPolling(ctx) {
|
|
1223
|
+
return __async(this, null, function* () {
|
|
1224
|
+
try {
|
|
1225
|
+
ctx.log.debug("Sending initial ping to server...");
|
|
1226
|
+
yield ctx.client.ping(ctx.build.id, ctx.log);
|
|
1227
|
+
ctx.log.debug("Initial ping sent successfully.");
|
|
1228
|
+
} catch (error) {
|
|
1229
|
+
ctx.log.error(`Error during initial ping: ${error.message}`);
|
|
1230
|
+
}
|
|
1231
|
+
pingIntervalId = setInterval(() => __async(this, null, function* () {
|
|
1232
|
+
try {
|
|
1233
|
+
ctx.log.debug("Sending ping to server...");
|
|
1234
|
+
yield ctx.client.ping(ctx.build.id, ctx.log);
|
|
1235
|
+
ctx.log.debug("Ping sent successfully.");
|
|
1236
|
+
} catch (error) {
|
|
1237
|
+
ctx.log.error(`Error during ping polling: ${error.message}`);
|
|
1238
|
+
}
|
|
1239
|
+
}), 10 * 60 * 1e3);
|
|
1240
|
+
});
|
|
1241
|
+
}
|
|
964
1242
|
|
|
965
1243
|
// src/lib/server.ts
|
|
966
|
-
var server_default = (ctx) => __async(
|
|
1244
|
+
var server_default = (ctx) => __async(void 0, null, function* () {
|
|
967
1245
|
const server = fastify__default.default({
|
|
968
1246
|
logger: {
|
|
969
1247
|
level: "debug",
|
|
@@ -981,7 +1259,7 @@ var server_default = (ctx) => __async(undefined, null, function* () {
|
|
|
981
1259
|
server.get("/domserializer", opts, (request, reply) => {
|
|
982
1260
|
reply.code(200).send({ data: { dom: SMARTUI_DOM } });
|
|
983
1261
|
});
|
|
984
|
-
server.post("/snapshot", opts, (request, reply) => __async(
|
|
1262
|
+
server.post("/snapshot", opts, (request, reply) => __async(void 0, null, function* () {
|
|
985
1263
|
var _a;
|
|
986
1264
|
let replyCode;
|
|
987
1265
|
let replyBody;
|
|
@@ -1000,6 +1278,48 @@ var server_default = (ctx) => __async(undefined, null, function* () {
|
|
|
1000
1278
|
}
|
|
1001
1279
|
return reply.code(replyCode).send(replyBody);
|
|
1002
1280
|
}));
|
|
1281
|
+
server.post("/stop", opts, (_, reply) => __async(void 0, null, function* () {
|
|
1282
|
+
var _a, _b;
|
|
1283
|
+
let replyCode;
|
|
1284
|
+
let replyBody;
|
|
1285
|
+
try {
|
|
1286
|
+
if (ctx.config.delayedUpload) {
|
|
1287
|
+
ctx.log.debug("started after processing because of delayedUpload");
|
|
1288
|
+
(_a = ctx.snapshotQueue) == null ? void 0 : _a.startProcessingfunc();
|
|
1289
|
+
}
|
|
1290
|
+
yield new Promise((resolve) => {
|
|
1291
|
+
const intervalId = setInterval(() => {
|
|
1292
|
+
var _a2, _b2;
|
|
1293
|
+
if (((_a2 = ctx.snapshotQueue) == null ? void 0 : _a2.isEmpty()) && !((_b2 = ctx.snapshotQueue) == null ? void 0 : _b2.isProcessing())) {
|
|
1294
|
+
clearInterval(intervalId);
|
|
1295
|
+
resolve();
|
|
1296
|
+
}
|
|
1297
|
+
}, 1e3);
|
|
1298
|
+
});
|
|
1299
|
+
yield ctx.client.finalizeBuild(ctx.build.id, ctx.totalSnapshots, ctx.log);
|
|
1300
|
+
yield (_b = ctx.browser) == null ? void 0 : _b.close();
|
|
1301
|
+
if (ctx.server) {
|
|
1302
|
+
ctx.server.close();
|
|
1303
|
+
}
|
|
1304
|
+
let resp = yield ctx.client.getS3PreSignedURL(ctx);
|
|
1305
|
+
yield ctx.client.uploadLogs(ctx, resp.data.url);
|
|
1306
|
+
if (pingIntervalId !== null) {
|
|
1307
|
+
clearInterval(pingIntervalId);
|
|
1308
|
+
ctx.log.debug("Ping polling stopped immediately.");
|
|
1309
|
+
}
|
|
1310
|
+
replyCode = 200;
|
|
1311
|
+
replyBody = { data: { message: "success", type: "DELETE" } };
|
|
1312
|
+
} catch (error) {
|
|
1313
|
+
ctx.log.debug(error);
|
|
1314
|
+
ctx.log.debug(`stop endpoint failed; ${error}`);
|
|
1315
|
+
replyCode = 500;
|
|
1316
|
+
replyBody = { error: { message: error.message } };
|
|
1317
|
+
}
|
|
1318
|
+
return reply.code(replyCode).send(replyBody);
|
|
1319
|
+
}));
|
|
1320
|
+
server.get("/ping", opts, (_, reply) => {
|
|
1321
|
+
reply.code(200).send({ status: "Server is running", version: ctx.cliVersion });
|
|
1322
|
+
});
|
|
1003
1323
|
yield server.listen({ port: ctx.options.port });
|
|
1004
1324
|
let { port } = server.addresses()[0];
|
|
1005
1325
|
process.env.SMARTUI_SERVER_ADDRESS = `http://localhost:${port}`;
|
|
@@ -1025,7 +1345,9 @@ var env_default = () => {
|
|
|
1025
1345
|
LT_SDK_DEBUG,
|
|
1026
1346
|
BASELINE_BRANCH,
|
|
1027
1347
|
CURRENT_BRANCH,
|
|
1028
|
-
PROJECT_NAME
|
|
1348
|
+
PROJECT_NAME,
|
|
1349
|
+
SMARTUI_API_PROXY,
|
|
1350
|
+
SMARTUI_API_SKIP_CERTIFICATES
|
|
1029
1351
|
} = process.env;
|
|
1030
1352
|
return {
|
|
1031
1353
|
PROJECT_TOKEN,
|
|
@@ -1043,7 +1365,9 @@ var env_default = () => {
|
|
|
1043
1365
|
CURRENT_BRANCH,
|
|
1044
1366
|
LT_SDK_DEBUG: LT_SDK_DEBUG === "true",
|
|
1045
1367
|
SMARTUI_DO_NOT_USE_CAPTURED_COOKIES: SMARTUI_DO_NOT_USE_CAPTURED_COOKIES === "true",
|
|
1046
|
-
PROJECT_NAME
|
|
1368
|
+
PROJECT_NAME,
|
|
1369
|
+
SMARTUI_API_PROXY,
|
|
1370
|
+
SMARTUI_API_SKIP_CERTIFICATES: SMARTUI_API_SKIP_CERTIFICATES === "true"
|
|
1047
1371
|
};
|
|
1048
1372
|
};
|
|
1049
1373
|
var logContext = {};
|
|
@@ -1062,7 +1386,7 @@ var logger = winston.createLogger({
|
|
|
1062
1386
|
let message = typeof info.message === "object" ? JSON.stringify(info.message).trim() : info.message.trim();
|
|
1063
1387
|
switch (info.level) {
|
|
1064
1388
|
case "warn":
|
|
1065
|
-
message =
|
|
1389
|
+
message = chalk__default.default.yellow(message);
|
|
1066
1390
|
break;
|
|
1067
1391
|
}
|
|
1068
1392
|
return info.level === "info" ? message : `[${contextString}:${info.level}] ` + message;
|
|
@@ -1084,16 +1408,16 @@ var logger_default = logger;
|
|
|
1084
1408
|
var startServer_default = (ctx) => {
|
|
1085
1409
|
return {
|
|
1086
1410
|
title: `Setting up SmartUI server`,
|
|
1087
|
-
task: (ctx2, task) => __async(
|
|
1411
|
+
task: (ctx2, task) => __async(void 0, null, function* () {
|
|
1088
1412
|
var _a;
|
|
1089
1413
|
updateLogContext({ task: "startServer" });
|
|
1090
1414
|
try {
|
|
1091
1415
|
ctx2.server = yield server_default(ctx2);
|
|
1092
|
-
task.output =
|
|
1416
|
+
task.output = chalk__default.default.gray(`listening on port ${(_a = ctx2.server.addresses()[0]) == null ? void 0 : _a.port}`);
|
|
1093
1417
|
task.title = "SmartUI started";
|
|
1094
1418
|
} catch (error) {
|
|
1095
1419
|
ctx2.log.debug(error);
|
|
1096
|
-
task.output =
|
|
1420
|
+
task.output = chalk__default.default.gray(error.message);
|
|
1097
1421
|
throw new Error("SmartUI server setup failed");
|
|
1098
1422
|
}
|
|
1099
1423
|
}),
|
|
@@ -1103,21 +1427,21 @@ var startServer_default = (ctx) => {
|
|
|
1103
1427
|
var auth_default = (ctx) => {
|
|
1104
1428
|
return {
|
|
1105
1429
|
title: `Authenticating with SmartUI`,
|
|
1106
|
-
task: (ctx2, task) => __async(
|
|
1430
|
+
task: (ctx2, task) => __async(void 0, null, function* () {
|
|
1107
1431
|
updateLogContext({ task: "auth" });
|
|
1108
1432
|
try {
|
|
1109
1433
|
const authResult = yield ctx2.client.auth(ctx2.log, ctx2.env);
|
|
1110
1434
|
if (authResult === 2) {
|
|
1111
|
-
task.output =
|
|
1435
|
+
task.output = chalk__default.default.gray(`New project '${ctx2.env.PROJECT_NAME}' created successfully`);
|
|
1112
1436
|
} else if (authResult === 0) {
|
|
1113
|
-
task.output =
|
|
1437
|
+
task.output = chalk__default.default.gray(`Using existing project token '******#${ctx2.env.PROJECT_TOKEN.split("#").pop()}'`);
|
|
1114
1438
|
} else if (authResult === 1) {
|
|
1115
|
-
task.output =
|
|
1439
|
+
task.output = chalk__default.default.gray(`Using existing project '${ctx2.env.PROJECT_NAME}'`);
|
|
1116
1440
|
}
|
|
1117
1441
|
task.title = "Authenticated with SmartUI";
|
|
1118
1442
|
} catch (error) {
|
|
1119
1443
|
ctx2.log.debug(error);
|
|
1120
|
-
task.output =
|
|
1444
|
+
task.output = chalk__default.default.gray(error.message);
|
|
1121
1445
|
throw new Error("Authentication failed");
|
|
1122
1446
|
}
|
|
1123
1447
|
}),
|
|
@@ -1126,66 +1450,36 @@ var auth_default = (ctx) => {
|
|
|
1126
1450
|
};
|
|
1127
1451
|
|
|
1128
1452
|
// package.json
|
|
1129
|
-
var version = "4.0.
|
|
1453
|
+
var version = "4.0.21";
|
|
1130
1454
|
var package_default = {
|
|
1131
1455
|
name: "@lambdatest/smartui-cli",
|
|
1132
|
-
version
|
|
1133
|
-
description: "A command line interface (CLI) to run SmartUI tests on LambdaTest",
|
|
1134
|
-
files: [
|
|
1135
|
-
"dist/**/*"
|
|
1136
|
-
],
|
|
1137
|
-
scripts: {
|
|
1138
|
-
build: "tsup",
|
|
1139
|
-
release: "pnpm run build && pnpm publish --access public --no-git-checks",
|
|
1140
|
-
"local-build": "pnpm run build && pnpm pack"
|
|
1141
|
-
},
|
|
1142
|
-
bin: {
|
|
1143
|
-
smartui: "./dist/index.cjs"
|
|
1144
|
-
},
|
|
1145
|
-
type: "module",
|
|
1146
|
-
keywords: [
|
|
1147
|
-
"lambdatest",
|
|
1148
|
-
"smartui",
|
|
1149
|
-
"cli"
|
|
1150
|
-
],
|
|
1151
|
-
author: "LambdaTest <keys@lambdatest.com>",
|
|
1152
|
-
license: "MIT",
|
|
1153
|
-
dependencies: {
|
|
1154
|
-
"@playwright/browser-chromium": "^1.47.2",
|
|
1155
|
-
"@playwright/browser-firefox": "^1.47.2",
|
|
1156
|
-
"@playwright/browser-webkit": "^1.47.2",
|
|
1157
|
-
"@playwright/test": "^1.47.2",
|
|
1158
|
-
"@types/cross-spawn": "^6.0.4",
|
|
1159
|
-
"@types/node": "^20.8.9",
|
|
1160
|
-
"@types/which": "^3.0.2",
|
|
1161
|
-
ajv: "^8.12.0",
|
|
1162
|
-
"ajv-errors": "^3.0.0",
|
|
1163
|
-
axios: "^1.6.0",
|
|
1164
|
-
chalk: "^4.1.2",
|
|
1165
|
-
commander: "^11.1.0",
|
|
1166
|
-
"cross-spawn": "^7.0.3",
|
|
1167
|
-
fastify: "^4.24.3",
|
|
1168
|
-
"form-data": "^4.0.0",
|
|
1169
|
-
listr2: "^7.0.1",
|
|
1170
|
-
sharp: "^0.33.4",
|
|
1171
|
-
tsup: "^7.2.0",
|
|
1172
|
-
uuid: "^11.0.3",
|
|
1173
|
-
which: "^4.0.0",
|
|
1174
|
-
winston: "^3.10.0"
|
|
1175
|
-
},
|
|
1176
|
-
devDependencies: {
|
|
1177
|
-
typescript: "^5.3.2"
|
|
1178
|
-
}
|
|
1179
|
-
};
|
|
1456
|
+
version};
|
|
1180
1457
|
var httpClient = class {
|
|
1181
|
-
constructor({ SMARTUI_CLIENT_API_URL, PROJECT_TOKEN, PROJECT_NAME, LT_USERNAME, LT_ACCESS_KEY }) {
|
|
1458
|
+
constructor({ SMARTUI_CLIENT_API_URL, PROJECT_TOKEN, PROJECT_NAME, LT_USERNAME, LT_ACCESS_KEY, SMARTUI_API_PROXY, SMARTUI_API_SKIP_CERTIFICATES }) {
|
|
1182
1459
|
this.projectToken = PROJECT_TOKEN || "";
|
|
1183
1460
|
this.projectName = PROJECT_NAME || "";
|
|
1184
1461
|
this.username = LT_USERNAME || "";
|
|
1185
1462
|
this.accessKey = LT_ACCESS_KEY || "";
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1463
|
+
let proxyUrl = null;
|
|
1464
|
+
try {
|
|
1465
|
+
const urlStr = (SMARTUI_API_PROXY == null ? void 0 : SMARTUI_API_PROXY.startsWith("http")) ? SMARTUI_API_PROXY : `http://${SMARTUI_API_PROXY}`;
|
|
1466
|
+
proxyUrl = SMARTUI_API_PROXY ? new URL(urlStr) : null;
|
|
1467
|
+
} catch (error) {
|
|
1468
|
+
console.error("Invalid proxy URL:", error);
|
|
1469
|
+
}
|
|
1470
|
+
const axiosConfig = {
|
|
1471
|
+
baseURL: SMARTUI_CLIENT_API_URL,
|
|
1472
|
+
proxy: proxyUrl ? {
|
|
1473
|
+
host: proxyUrl.hostname,
|
|
1474
|
+
port: proxyUrl.port ? Number(proxyUrl.port) : 80
|
|
1475
|
+
} : false
|
|
1476
|
+
};
|
|
1477
|
+
if (SMARTUI_API_SKIP_CERTIFICATES) {
|
|
1478
|
+
axiosConfig.httpsAgent = new https__default.default.Agent({
|
|
1479
|
+
rejectUnauthorized: false
|
|
1480
|
+
});
|
|
1481
|
+
}
|
|
1482
|
+
this.axiosInstance = axios__default.default.create(axiosConfig);
|
|
1189
1483
|
this.axiosInstance.interceptors.request.use((config) => {
|
|
1190
1484
|
config.headers["projectToken"] = this.projectToken;
|
|
1191
1485
|
config.headers["projectName"] = this.projectName;
|
|
@@ -1215,7 +1509,7 @@ var httpClient = class {
|
|
|
1215
1509
|
headers: error.response.headers,
|
|
1216
1510
|
body: error.response.data
|
|
1217
1511
|
})}`);
|
|
1218
|
-
throw new Error(((_a = error.response.data.error) == null ?
|
|
1512
|
+
throw new Error(((_a = error.response.data.error) == null ? void 0 : _a.message) || error.response.data.message || error.response.data);
|
|
1219
1513
|
}
|
|
1220
1514
|
if (error.request) {
|
|
1221
1515
|
log2.debug(`http request failed: ${error.toJSON()}`);
|
|
@@ -1248,14 +1542,15 @@ var httpClient = class {
|
|
|
1248
1542
|
}
|
|
1249
1543
|
});
|
|
1250
1544
|
}
|
|
1251
|
-
createBuild(git, config, log2, buildName) {
|
|
1545
|
+
createBuild(git, config, log2, buildName, isStartExec) {
|
|
1252
1546
|
return this.request({
|
|
1253
1547
|
url: "/build",
|
|
1254
1548
|
method: "POST",
|
|
1255
1549
|
data: {
|
|
1256
1550
|
git,
|
|
1257
1551
|
config,
|
|
1258
|
-
buildName
|
|
1552
|
+
buildName,
|
|
1553
|
+
isStartExec
|
|
1259
1554
|
}
|
|
1260
1555
|
}, log2);
|
|
1261
1556
|
}
|
|
@@ -1266,6 +1561,15 @@ var httpClient = class {
|
|
|
1266
1561
|
params: { buildId, baseline }
|
|
1267
1562
|
}, log2);
|
|
1268
1563
|
}
|
|
1564
|
+
ping(buildId, log2) {
|
|
1565
|
+
return this.request({
|
|
1566
|
+
url: "/build/ping",
|
|
1567
|
+
method: "POST",
|
|
1568
|
+
data: {
|
|
1569
|
+
buildId
|
|
1570
|
+
}
|
|
1571
|
+
}, log2);
|
|
1572
|
+
}
|
|
1269
1573
|
finalizeBuild(buildId, totalSnapshots, log2) {
|
|
1270
1574
|
let params = { buildId };
|
|
1271
1575
|
if (totalSnapshots > -1)
|
|
@@ -1493,7 +1797,7 @@ var ctx_default = (options) => {
|
|
|
1493
1797
|
}
|
|
1494
1798
|
if (config.web) {
|
|
1495
1799
|
webConfig = { browsers: config.web.browsers, viewports: [] };
|
|
1496
|
-
for (let viewport of (_b = config.web) == null ?
|
|
1800
|
+
for (let viewport of (_b = config.web) == null ? void 0 : _b.viewports)
|
|
1497
1801
|
webConfig.viewports.push({ width: viewport[0], height: viewport[1] || 0 });
|
|
1498
1802
|
}
|
|
1499
1803
|
if (config.mobile) {
|
|
@@ -1547,396 +1851,141 @@ var ctx_default = (options) => {
|
|
|
1547
1851
|
port,
|
|
1548
1852
|
ignoreResolutions: resolutionOff,
|
|
1549
1853
|
fileExtension: extensionFiles,
|
|
1550
|
-
stripExtension: ignoreStripExtension,
|
|
1551
|
-
ignorePattern: ignoreFilePattern,
|
|
1552
|
-
fetchResults: fetchResultObj,
|
|
1553
|
-
fetchResultsFileName: fetchResultsFileObj
|
|
1554
|
-
},
|
|
1555
|
-
cliVersion: version,
|
|
1556
|
-
totalSnapshots: -1
|
|
1557
|
-
|
|
1558
|
-
};
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
}
|
|
1571
|
-
function isGitRepo() {
|
|
1572
|
-
try {
|
|
1573
|
-
executeCommand("git status");
|
|
1574
|
-
return true;
|
|
1575
|
-
} catch (error) {
|
|
1576
|
-
return false;
|
|
1577
|
-
}
|
|
1578
|
-
}
|
|
1579
|
-
var git_default = (ctx) => {
|
|
1580
|
-
if (ctx.env.SMARTUI_GIT_INFO_FILEPATH) {
|
|
1581
|
-
let gitInfo = JSON.parse(fs5__default.default.readFileSync(ctx.env.SMARTUI_GIT_INFO_FILEPATH, "utf-8"));
|
|
1582
|
-
return {
|
|
1583
|
-
branch: ctx.env.CURRENT_BRANCH || gitInfo.branch || "",
|
|
1584
|
-
commitId: gitInfo.commit_id.slice(0, 6) || "",
|
|
1585
|
-
commitMessage: gitInfo.commit_body || "",
|
|
1586
|
-
commitAuthor: gitInfo.commit_author || "",
|
|
1587
|
-
githubURL: ctx.env.GITHUB_ACTIONS ? `${constants_default.GITHUB_API_HOST}/repos/${process.env.GITHUB_REPOSITORY}/statuses/${gitInfo.commit_id}` : "",
|
|
1588
|
-
baselineBranch: ctx.env.BASELINE_BRANCH || ""
|
|
1589
|
-
};
|
|
1590
|
-
} else {
|
|
1591
|
-
const splitCharacter = "<##>";
|
|
1592
|
-
const prettyFormat = ["%h", "%H", "%s", "%f", "%b", "%at", "%ct", "%an", "%ae", "%cn", "%ce", "%N", ""];
|
|
1593
|
-
const command4 = 'git log -1 --pretty=format:"' + prettyFormat.join(splitCharacter) + '" && git rev-parse --abbrev-ref HEAD && git tag --contains HEAD';
|
|
1594
|
-
let res = executeCommand(command4).split(splitCharacter);
|
|
1595
|
-
var branchAndTags = res[res.length - 1].split("\n").filter((n) => n);
|
|
1596
|
-
var branch = ctx.env.CURRENT_BRANCH || branchAndTags[0];
|
|
1597
|
-
branchAndTags.slice(1);
|
|
1598
|
-
return {
|
|
1599
|
-
branch: branch || "",
|
|
1600
|
-
commitId: res[0] || "",
|
|
1601
|
-
commitMessage: res[2] || "",
|
|
1602
|
-
commitAuthor: res[7] || "",
|
|
1603
|
-
githubURL: ctx.env.GITHUB_ACTIONS ? `${constants_default.GITHUB_API_HOST}/repos/${process.env.GITHUB_REPOSITORY}/statuses/${res[1]}` : "",
|
|
1604
|
-
baselineBranch: ctx.env.BASELINE_BRANCH || ""
|
|
1605
|
-
};
|
|
1606
|
-
}
|
|
1607
|
-
};
|
|
1608
|
-
var getGitInfo_default = (ctx) => {
|
|
1609
|
-
return {
|
|
1610
|
-
title: `Fetching git repo details`,
|
|
1611
|
-
skip: (ctx2) => {
|
|
1612
|
-
return !isGitRepo() && !ctx2.env.SMARTUI_GIT_INFO_FILEPATH ? "[SKIPPED] Fetching git repo details; not a git repo" : "";
|
|
1613
|
-
},
|
|
1614
|
-
task: (ctx2, task) => __async(undefined, null, function* () {
|
|
1615
|
-
if (ctx2.env.CURRENT_BRANCH && ctx2.env.CURRENT_BRANCH.trim() === "") {
|
|
1616
|
-
throw new Error("Error: The environment variable CURRENT_BRANCH cannot be empty.");
|
|
1617
|
-
}
|
|
1618
|
-
try {
|
|
1619
|
-
ctx2.git = git_default(ctx2);
|
|
1620
|
-
task.output = chalk6__default.default.gray(`branch: ${ctx2.git.branch}, commit: ${ctx2.git.commitId}, author: ${ctx2.git.commitAuthor}`);
|
|
1621
|
-
task.title = "Fetched git information";
|
|
1622
|
-
} catch (error) {
|
|
1623
|
-
ctx2.log.debug(error);
|
|
1624
|
-
task.output = chalk6__default.default.gray(`${error.message}`);
|
|
1625
|
-
throw new Error("Error fetching git repo details");
|
|
1626
|
-
}
|
|
1627
|
-
}),
|
|
1628
|
-
rendererOptions: { persistentOutput: true }
|
|
1629
|
-
};
|
|
1630
|
-
};
|
|
1631
|
-
var createBuild_default = (ctx) => {
|
|
1632
|
-
return {
|
|
1633
|
-
title: `Creating SmartUI build`,
|
|
1634
|
-
task: (ctx2, task) => __async(undefined, null, function* () {
|
|
1635
|
-
updateLogContext({ task: "createBuild" });
|
|
1636
|
-
try {
|
|
1637
|
-
let resp = yield ctx2.client.createBuild(ctx2.git, ctx2.config, ctx2.log, ctx2.build.name);
|
|
1638
|
-
ctx2.build = {
|
|
1639
|
-
id: resp.data.buildId,
|
|
1640
|
-
name: resp.data.buildName,
|
|
1641
|
-
url: resp.data.buildURL,
|
|
1642
|
-
baseline: resp.data.baseline,
|
|
1643
|
-
useKafkaFlow: resp.data.useKafkaFlow || false
|
|
1644
|
-
};
|
|
1645
|
-
task.output = chalk6__default.default.gray(`build id: ${resp.data.buildId}`);
|
|
1646
|
-
task.title = "SmartUI build created";
|
|
1647
|
-
} catch (error) {
|
|
1648
|
-
ctx2.log.debug(error);
|
|
1649
|
-
task.output = chalk6__default.default.gray(error.message);
|
|
1650
|
-
throw new Error("SmartUI build creation failed");
|
|
1651
|
-
}
|
|
1652
|
-
}),
|
|
1653
|
-
rendererOptions: { persistentOutput: true }
|
|
1654
|
-
};
|
|
1655
|
-
};
|
|
1656
|
-
var isPollingActive = false;
|
|
1657
|
-
function delDir(dir) {
|
|
1658
|
-
if (fs5__default.default.existsSync(dir)) {
|
|
1659
|
-
fs5__default.default.rmSync(dir, { recursive: true });
|
|
1660
|
-
}
|
|
1661
|
-
}
|
|
1662
|
-
function scrollToBottomAndBackToTop({
|
|
1663
|
-
frequency = 100,
|
|
1664
|
-
timing = 8,
|
|
1665
|
-
remoteWindow = window
|
|
1666
|
-
} = {}) {
|
|
1667
|
-
return new Promise((resolve) => {
|
|
1668
|
-
let scrolls = 1;
|
|
1669
|
-
let scrollLength = remoteWindow.document.body.scrollHeight / frequency;
|
|
1670
|
-
(function scroll() {
|
|
1671
|
-
let scrollBy = scrollLength * scrolls;
|
|
1672
|
-
remoteWindow.setTimeout(() => {
|
|
1673
|
-
remoteWindow.scrollTo(0, scrollBy);
|
|
1674
|
-
if (scrolls < frequency) {
|
|
1675
|
-
scrolls += 1;
|
|
1676
|
-
scroll();
|
|
1677
|
-
}
|
|
1678
|
-
if (scrolls === frequency) {
|
|
1679
|
-
remoteWindow.setTimeout(() => {
|
|
1680
|
-
remoteWindow.scrollTo(0, 0);
|
|
1681
|
-
resolve();
|
|
1682
|
-
}, timing);
|
|
1683
|
-
}
|
|
1684
|
-
}, timing);
|
|
1685
|
-
})();
|
|
1686
|
-
});
|
|
1687
|
-
}
|
|
1688
|
-
function launchBrowsers(ctx) {
|
|
1689
|
-
return __async(this, null, function* () {
|
|
1690
|
-
var _a;
|
|
1691
|
-
let browsers = {};
|
|
1692
|
-
const isHeadless = ((_a = process.env.HEADLESS) == null ? undefined : _a.toLowerCase()) === "false" ? false : true;
|
|
1693
|
-
let launchOptions = { headless: isHeadless };
|
|
1694
|
-
if (ctx.config.web) {
|
|
1695
|
-
for (const browser of ctx.config.web.browsers) {
|
|
1696
|
-
switch (browser) {
|
|
1697
|
-
case constants_default.CHROME:
|
|
1698
|
-
browsers[constants_default.CHROME] = yield test.chromium.launch(launchOptions);
|
|
1699
|
-
break;
|
|
1700
|
-
case constants_default.SAFARI:
|
|
1701
|
-
browsers[constants_default.SAFARI] = yield test.webkit.launch(launchOptions);
|
|
1702
|
-
break;
|
|
1703
|
-
case constants_default.FIREFOX:
|
|
1704
|
-
browsers[constants_default.FIREFOX] = yield test.firefox.launch(launchOptions);
|
|
1705
|
-
break;
|
|
1706
|
-
case constants_default.EDGE:
|
|
1707
|
-
launchOptions.args = ["--headless=new"];
|
|
1708
|
-
browsers[constants_default.EDGE] = yield test.chromium.launch(__spreadValues({ channel: constants_default.EDGE_CHANNEL }, launchOptions));
|
|
1709
|
-
break;
|
|
1710
|
-
}
|
|
1711
|
-
}
|
|
1712
|
-
}
|
|
1713
|
-
if (ctx.config.mobile) {
|
|
1714
|
-
for (const device of ctx.config.mobile.devices) {
|
|
1715
|
-
if (constants_default.SUPPORTED_MOBILE_DEVICES[device].os === "android" && !browsers[constants_default.CHROME])
|
|
1716
|
-
browsers[constants_default.CHROME] = yield test.chromium.launch(launchOptions);
|
|
1717
|
-
else if (constants_default.SUPPORTED_MOBILE_DEVICES[device].os === "ios" && !browsers[constants_default.SAFARI])
|
|
1718
|
-
browsers[constants_default.SAFARI] = yield test.webkit.launch(launchOptions);
|
|
1719
|
-
}
|
|
1720
|
-
}
|
|
1721
|
-
return browsers;
|
|
1722
|
-
});
|
|
1723
|
-
}
|
|
1724
|
-
function closeBrowsers(browsers) {
|
|
1725
|
-
return __async(this, null, function* () {
|
|
1726
|
-
var _a;
|
|
1727
|
-
for (const browserName of Object.keys(browsers))
|
|
1728
|
-
yield (_a = browsers[browserName]) == null ? undefined : _a.close();
|
|
1729
|
-
});
|
|
1730
|
-
}
|
|
1731
|
-
function getWebRenderViewports(ctx) {
|
|
1732
|
-
let webRenderViewports = [];
|
|
1733
|
-
if (ctx.config.web) {
|
|
1734
|
-
for (const viewport of ctx.config.web.viewports) {
|
|
1735
|
-
webRenderViewports.push({
|
|
1736
|
-
viewport,
|
|
1737
|
-
viewportString: `${viewport.width}${viewport.height ? "x" + viewport.height : ""}`,
|
|
1738
|
-
fullPage: viewport.height ? false : true,
|
|
1739
|
-
device: false
|
|
1740
|
-
});
|
|
1741
|
-
}
|
|
1742
|
-
}
|
|
1743
|
-
return webRenderViewports;
|
|
1744
|
-
}
|
|
1745
|
-
function getWebRenderViewportsForOptions(options) {
|
|
1746
|
-
let webRenderViewports = [];
|
|
1747
|
-
if (options.web && Array.isArray(options.web.viewports)) {
|
|
1748
|
-
for (const viewport of options.web.viewports) {
|
|
1749
|
-
if (Array.isArray(viewport) && viewport.length > 0) {
|
|
1750
|
-
let viewportObj = {
|
|
1751
|
-
width: viewport[0]
|
|
1752
|
-
};
|
|
1753
|
-
if (viewport.length > 1) {
|
|
1754
|
-
viewportObj.height = viewport[1];
|
|
1755
|
-
}
|
|
1756
|
-
webRenderViewports.push({
|
|
1757
|
-
viewport: viewportObj,
|
|
1758
|
-
viewportString: `${viewport[0]}${viewport[1] ? "x" + viewport[1] : ""}`,
|
|
1759
|
-
fullPage: viewport.length === 1,
|
|
1760
|
-
device: false
|
|
1761
|
-
});
|
|
1762
|
-
}
|
|
1763
|
-
}
|
|
1764
|
-
}
|
|
1765
|
-
return webRenderViewports;
|
|
1766
|
-
}
|
|
1767
|
-
function getMobileRenderViewports(ctx) {
|
|
1768
|
-
var _a;
|
|
1769
|
-
let mobileRenderViewports = {};
|
|
1770
|
-
mobileRenderViewports[constants_default.MOBILE_OS_IOS] = [];
|
|
1771
|
-
mobileRenderViewports[constants_default.MOBILE_OS_ANDROID] = [];
|
|
1772
|
-
if (ctx.config.mobile) {
|
|
1773
|
-
for (const device of ctx.config.mobile.devices) {
|
|
1774
|
-
let os = constants_default.SUPPORTED_MOBILE_DEVICES[device].os;
|
|
1775
|
-
let { width, height } = constants_default.SUPPORTED_MOBILE_DEVICES[device].viewport;
|
|
1776
|
-
let portrait = ctx.config.mobile.orientation === constants_default.MOBILE_ORIENTATION_PORTRAIT ? true : false;
|
|
1777
|
-
(_a = mobileRenderViewports[os]) == null ? undefined : _a.push({
|
|
1778
|
-
viewport: { width: portrait ? width : height, height: portrait ? height : width },
|
|
1779
|
-
viewportString: `${device} (${ctx.config.mobile.orientation})`,
|
|
1780
|
-
fullPage: ctx.config.mobile.fullPage,
|
|
1781
|
-
device: true,
|
|
1782
|
-
os
|
|
1783
|
-
});
|
|
1784
|
-
}
|
|
1854
|
+
stripExtension: ignoreStripExtension,
|
|
1855
|
+
ignorePattern: ignoreFilePattern,
|
|
1856
|
+
fetchResults: fetchResultObj,
|
|
1857
|
+
fetchResultsFileName: fetchResultsFileObj
|
|
1858
|
+
},
|
|
1859
|
+
cliVersion: version,
|
|
1860
|
+
totalSnapshots: -1,
|
|
1861
|
+
isStartExec: false
|
|
1862
|
+
};
|
|
1863
|
+
};
|
|
1864
|
+
function executeCommand(command7) {
|
|
1865
|
+
let dst = process.cwd();
|
|
1866
|
+
try {
|
|
1867
|
+
return child_process.execSync(command7, {
|
|
1868
|
+
cwd: dst,
|
|
1869
|
+
stdio: ["ignore"],
|
|
1870
|
+
encoding: "utf-8"
|
|
1871
|
+
});
|
|
1872
|
+
} catch (error) {
|
|
1873
|
+
throw new Error(error.message);
|
|
1785
1874
|
}
|
|
1786
|
-
return mobileRenderViewports;
|
|
1787
1875
|
}
|
|
1788
|
-
function
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
for (const device of options.mobile.devices) {
|
|
1795
|
-
let os = constants_default.SUPPORTED_MOBILE_DEVICES[device].os;
|
|
1796
|
-
let { width, height } = constants_default.SUPPORTED_MOBILE_DEVICES[device].viewport;
|
|
1797
|
-
let orientation = options.mobile.orientation || constants_default.MOBILE_ORIENTATION_PORTRAIT;
|
|
1798
|
-
let portrait = orientation === constants_default.MOBILE_ORIENTATION_PORTRAIT;
|
|
1799
|
-
let fullPage;
|
|
1800
|
-
if (options.mobile.fullPage === undefined || options.mobile.fullPage) {
|
|
1801
|
-
fullPage = true;
|
|
1802
|
-
} else {
|
|
1803
|
-
fullPage = false;
|
|
1804
|
-
}
|
|
1805
|
-
(_a = mobileRenderViewports[os]) == null ? undefined : _a.push({
|
|
1806
|
-
viewport: { width: portrait ? width : height, height: portrait ? height : width },
|
|
1807
|
-
viewportString: `${device} (${orientation})`,
|
|
1808
|
-
fullPage,
|
|
1809
|
-
device: true,
|
|
1810
|
-
os
|
|
1811
|
-
});
|
|
1812
|
-
}
|
|
1876
|
+
function isGitRepo() {
|
|
1877
|
+
try {
|
|
1878
|
+
executeCommand("git status");
|
|
1879
|
+
return true;
|
|
1880
|
+
} catch (error) {
|
|
1881
|
+
return false;
|
|
1813
1882
|
}
|
|
1814
|
-
return mobileRenderViewports;
|
|
1815
|
-
}
|
|
1816
|
-
function getRenderViewports(ctx) {
|
|
1817
|
-
let mobileRenderViewports = getMobileRenderViewports(ctx);
|
|
1818
|
-
let webRenderViewports = getWebRenderViewports(ctx);
|
|
1819
|
-
return [
|
|
1820
|
-
...webRenderViewports,
|
|
1821
|
-
...mobileRenderViewports[constants_default.MOBILE_OS_IOS],
|
|
1822
|
-
...mobileRenderViewports[constants_default.MOBILE_OS_ANDROID]
|
|
1823
|
-
];
|
|
1824
|
-
}
|
|
1825
|
-
function getRenderViewportsForOptions(options) {
|
|
1826
|
-
let mobileRenderViewports = getMobileRenderViewportsForOptions(options);
|
|
1827
|
-
let webRenderViewports = getWebRenderViewportsForOptions(options);
|
|
1828
|
-
return [
|
|
1829
|
-
...webRenderViewports,
|
|
1830
|
-
...mobileRenderViewports[constants_default.MOBILE_OS_IOS],
|
|
1831
|
-
...mobileRenderViewports[constants_default.MOBILE_OS_ANDROID]
|
|
1832
|
-
];
|
|
1833
1883
|
}
|
|
1834
|
-
|
|
1835
|
-
if (
|
|
1836
|
-
|
|
1837
|
-
|
|
1884
|
+
var git_default = (ctx) => {
|
|
1885
|
+
if (ctx.env.SMARTUI_GIT_INFO_FILEPATH) {
|
|
1886
|
+
let gitInfo = JSON.parse(fs5__default.default.readFileSync(ctx.env.SMARTUI_GIT_INFO_FILEPATH, "utf-8"));
|
|
1887
|
+
return {
|
|
1888
|
+
branch: ctx.env.CURRENT_BRANCH || gitInfo.branch || "",
|
|
1889
|
+
commitId: gitInfo.commit_id.slice(0, 6) || "",
|
|
1890
|
+
commitMessage: gitInfo.commit_body || "",
|
|
1891
|
+
commitAuthor: gitInfo.commit_author || "",
|
|
1892
|
+
githubURL: ctx.env.GITHUB_ACTIONS ? `${constants_default.GITHUB_API_HOST}/repos/${process.env.GITHUB_REPOSITORY}/statuses/${gitInfo.commit_id}` : "",
|
|
1893
|
+
baselineBranch: ctx.env.BASELINE_BRANCH || ""
|
|
1894
|
+
};
|
|
1838
1895
|
} else {
|
|
1839
|
-
|
|
1896
|
+
const splitCharacter = "<##>";
|
|
1897
|
+
const prettyFormat = ["%h", "%H", "%s", "%f", "%b", "%at", "%ct", "%an", "%ae", "%cn", "%ce", "%N", ""];
|
|
1898
|
+
const command7 = 'git log -1 --pretty=format:"' + prettyFormat.join(splitCharacter) + '" && git rev-parse --abbrev-ref HEAD && git tag --contains HEAD';
|
|
1899
|
+
let res = executeCommand(command7).split(splitCharacter);
|
|
1900
|
+
var branchAndTags = res[res.length - 1].split("\n").filter((n) => n);
|
|
1901
|
+
var branch = ctx.env.CURRENT_BRANCH || branchAndTags[0];
|
|
1902
|
+
branchAndTags.slice(1);
|
|
1903
|
+
return {
|
|
1904
|
+
branch: branch || "",
|
|
1905
|
+
commitId: res[0] || "",
|
|
1906
|
+
commitMessage: res[2] || "",
|
|
1907
|
+
commitAuthor: res[7] || "",
|
|
1908
|
+
githubURL: ctx.env.GITHUB_ACTIONS ? `${constants_default.GITHUB_API_HOST}/repos/${process.env.GITHUB_REPOSITORY}/statuses/${res[1]}` : "",
|
|
1909
|
+
baselineBranch: ctx.env.BASELINE_BRANCH || ""
|
|
1910
|
+
};
|
|
1840
1911
|
}
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1912
|
+
};
|
|
1913
|
+
var getGitInfo_default = (ctx) => {
|
|
1914
|
+
return {
|
|
1915
|
+
title: `Fetching git repo details`,
|
|
1916
|
+
skip: (ctx2) => {
|
|
1917
|
+
return !isGitRepo() && !ctx2.env.SMARTUI_GIT_INFO_FILEPATH ? "[SKIPPED] Fetching git repo details; not a git repo" : "";
|
|
1918
|
+
},
|
|
1919
|
+
task: (ctx2, task) => __async(void 0, null, function* () {
|
|
1920
|
+
if (ctx2.env.CURRENT_BRANCH && ctx2.env.CURRENT_BRANCH.trim() === "") {
|
|
1921
|
+
throw new Error("Error: The environment variable CURRENT_BRANCH cannot be empty.");
|
|
1851
1922
|
}
|
|
1852
1923
|
try {
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
clearInterval(intervalId);
|
|
1857
|
-
isPollingActive = false;
|
|
1858
|
-
}
|
|
1859
|
-
fs5__default.default.writeFileSync(ctx.options.fetchResultsFileName, JSON.stringify(resp, null, 2));
|
|
1860
|
-
ctx.log.debug(`Updated results in ${ctx.options.fetchResultsFileName}`);
|
|
1861
|
-
if (resp.build.build_status_ind === constants_default.BUILD_COMPLETE || resp.build.build_status_ind === constants_default.BUILD_ERROR) {
|
|
1862
|
-
clearInterval(intervalId);
|
|
1863
|
-
ctx.log.info(`Fetching results completed. Final results written to ${ctx.options.fetchResultsFileName}`);
|
|
1864
|
-
isPollingActive = false;
|
|
1865
|
-
let totalScreenshotsWithMismatches = 0;
|
|
1866
|
-
let totalVariantsWithMismatches = 0;
|
|
1867
|
-
const totalScreenshots = Object.keys(resp.screenshots || {}).length;
|
|
1868
|
-
let totalVariants = 0;
|
|
1869
|
-
for (const [screenshot, variants] of Object.entries(resp.screenshots || {})) {
|
|
1870
|
-
let screenshotHasMismatch = false;
|
|
1871
|
-
let variantMismatchCount = 0;
|
|
1872
|
-
totalVariants += variants.length;
|
|
1873
|
-
for (const variant of variants) {
|
|
1874
|
-
if (variant.mismatch_percentage > 0) {
|
|
1875
|
-
screenshotHasMismatch = true;
|
|
1876
|
-
variantMismatchCount++;
|
|
1877
|
-
}
|
|
1878
|
-
}
|
|
1879
|
-
if (screenshotHasMismatch) {
|
|
1880
|
-
totalScreenshotsWithMismatches++;
|
|
1881
|
-
totalVariantsWithMismatches += variantMismatchCount;
|
|
1882
|
-
}
|
|
1883
|
-
}
|
|
1884
|
-
ctx.log.info(
|
|
1885
|
-
chalk6__default.default.green.bold(
|
|
1886
|
-
`
|
|
1887
|
-
Summary of Mismatches:
|
|
1888
|
-
${chalk6__default.default.yellow("Total Variants with Mismatches:")} ${chalk6__default.default.white(totalVariantsWithMismatches)} out of ${chalk6__default.default.white(totalVariants)}
|
|
1889
|
-
${chalk6__default.default.yellow("Total Screenshots with Mismatches:")} ${chalk6__default.default.white(totalScreenshotsWithMismatches)} out of ${chalk6__default.default.white(totalScreenshots)}
|
|
1890
|
-
${chalk6__default.default.yellow("Branch Name:")} ${chalk6__default.default.white(resp.build.branch)}
|
|
1891
|
-
${chalk6__default.default.yellow("Project Name:")} ${chalk6__default.default.white(resp.project.name)}
|
|
1892
|
-
${chalk6__default.default.yellow("Build ID:")} ${chalk6__default.default.white(resp.build.build_id)}
|
|
1893
|
-
`
|
|
1894
|
-
)
|
|
1895
|
-
);
|
|
1896
|
-
}
|
|
1924
|
+
ctx2.git = git_default(ctx2);
|
|
1925
|
+
task.output = chalk__default.default.gray(`branch: ${ctx2.git.branch}, commit: ${ctx2.git.commitId}, author: ${ctx2.git.commitAuthor}`);
|
|
1926
|
+
task.title = "Fetched git information";
|
|
1897
1927
|
} catch (error) {
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
} else {
|
|
1902
|
-
ctx.log.error(`Error fetching screenshot data: ${error.message}`);
|
|
1903
|
-
}
|
|
1904
|
-
clearInterval(intervalId);
|
|
1905
|
-
isPollingActive = false;
|
|
1928
|
+
ctx2.log.debug(error);
|
|
1929
|
+
task.output = chalk__default.default.gray(`${error.message}`);
|
|
1930
|
+
throw new Error("Error fetching git repo details");
|
|
1906
1931
|
}
|
|
1907
|
-
}),
|
|
1908
|
-
|
|
1909
|
-
}
|
|
1910
|
-
|
|
1911
|
-
|
|
1932
|
+
}),
|
|
1933
|
+
rendererOptions: { persistentOutput: true }
|
|
1934
|
+
};
|
|
1935
|
+
};
|
|
1936
|
+
var createBuild_default = (ctx) => {
|
|
1937
|
+
return {
|
|
1938
|
+
title: `Creating SmartUI build`,
|
|
1939
|
+
task: (ctx2, task) => __async(void 0, null, function* () {
|
|
1940
|
+
updateLogContext({ task: "createBuild" });
|
|
1941
|
+
try {
|
|
1942
|
+
let resp = yield ctx2.client.createBuild(ctx2.git, ctx2.config, ctx2.log, ctx2.build.name, ctx2.isStartExec);
|
|
1943
|
+
ctx2.build = {
|
|
1944
|
+
id: resp.data.buildId,
|
|
1945
|
+
name: resp.data.buildName,
|
|
1946
|
+
url: resp.data.buildURL,
|
|
1947
|
+
baseline: resp.data.baseline,
|
|
1948
|
+
useKafkaFlow: resp.data.useKafkaFlow || false
|
|
1949
|
+
};
|
|
1950
|
+
task.output = chalk__default.default.gray(`build id: ${resp.data.buildId}`);
|
|
1951
|
+
task.title = "SmartUI build created";
|
|
1952
|
+
} catch (error) {
|
|
1953
|
+
ctx2.log.debug(error);
|
|
1954
|
+
task.output = chalk__default.default.gray(error.message);
|
|
1955
|
+
throw new Error("SmartUI build creation failed");
|
|
1956
|
+
}
|
|
1957
|
+
}),
|
|
1958
|
+
rendererOptions: { persistentOutput: true }
|
|
1959
|
+
};
|
|
1960
|
+
};
|
|
1912
1961
|
var exec_default = (ctx) => {
|
|
1913
1962
|
var _a;
|
|
1914
1963
|
return {
|
|
1915
|
-
title: `Executing '${(_a = ctx.args.execCommand) == null ?
|
|
1916
|
-
task: (ctx2, task) => __async(
|
|
1964
|
+
title: `Executing '${(_a = ctx.args.execCommand) == null ? void 0 : _a.join(" ")}'`,
|
|
1965
|
+
task: (ctx2, task) => __async(void 0, null, function* () {
|
|
1917
1966
|
if (ctx2.options.fetchResults) {
|
|
1918
1967
|
startPolling(ctx2);
|
|
1919
1968
|
}
|
|
1920
1969
|
updateLogContext({ task: "exec" });
|
|
1921
1970
|
return new Promise((resolve, reject) => {
|
|
1922
1971
|
var _a2, _b, _c;
|
|
1923
|
-
const childProcess = spawn__default.default(ctx2.args.execCommand[0], (_a2 = ctx2.args.execCommand) == null ?
|
|
1972
|
+
const childProcess = spawn__default.default(ctx2.args.execCommand[0], (_a2 = ctx2.args.execCommand) == null ? void 0 : _a2.slice(1));
|
|
1924
1973
|
let totalOutput = "";
|
|
1925
1974
|
const output = listr2.createWritable((chunk) => {
|
|
1926
1975
|
totalOutput += chunk;
|
|
1927
|
-
task.output =
|
|
1976
|
+
task.output = chalk__default.default.gray(totalOutput);
|
|
1928
1977
|
});
|
|
1929
|
-
(_b = childProcess.stdout) == null ?
|
|
1930
|
-
(_c = childProcess.stderr) == null ?
|
|
1978
|
+
(_b = childProcess.stdout) == null ? void 0 : _b.pipe(output);
|
|
1979
|
+
(_c = childProcess.stderr) == null ? void 0 : _c.pipe(output);
|
|
1931
1980
|
childProcess.on("error", (error) => {
|
|
1932
1981
|
var _a3;
|
|
1933
|
-
task.output =
|
|
1934
|
-
throw new Error(`Execution of '${(_a3 = ctx2.args.execCommand) == null ?
|
|
1982
|
+
task.output = chalk__default.default.gray(`error: ${error.message}`);
|
|
1983
|
+
throw new Error(`Execution of '${(_a3 = ctx2.args.execCommand) == null ? void 0 : _a3.join(" ")}' failed`);
|
|
1935
1984
|
});
|
|
1936
|
-
childProcess.on("close", (code, signal) => __async(
|
|
1985
|
+
childProcess.on("close", (code, signal) => __async(void 0, null, function* () {
|
|
1937
1986
|
var _a3;
|
|
1938
1987
|
if (code !== null) {
|
|
1939
|
-
task.title = `Execution of '${(_a3 = ctx2.args.execCommand) == null ?
|
|
1988
|
+
task.title = `Execution of '${(_a3 = ctx2.args.execCommand) == null ? void 0 : _a3.join(" ")}' completed; exited with code ${code}`;
|
|
1940
1989
|
} else if (signal !== null) {
|
|
1941
1990
|
throw new Error(`Child process killed with signal ${signal}`);
|
|
1942
1991
|
}
|
|
@@ -1951,7 +2000,7 @@ var exec_default = (ctx) => {
|
|
|
1951
2000
|
var processSnapshot_default = (ctx) => {
|
|
1952
2001
|
return {
|
|
1953
2002
|
title: `Processing snapshots`,
|
|
1954
|
-
task: (ctx2, task) => __async(
|
|
2003
|
+
task: (ctx2, task) => __async(void 0, null, function* () {
|
|
1955
2004
|
var _a, _b;
|
|
1956
2005
|
try {
|
|
1957
2006
|
if (ctx2.config.delayedUpload) {
|
|
@@ -1973,19 +2022,19 @@ var processSnapshot_default = (ctx) => {
|
|
|
1973
2022
|
let output = "";
|
|
1974
2023
|
for (let snapshot of (_b = ctx2.snapshotQueue) == null ? void 0 : _b.getProcessedSnapshots()) {
|
|
1975
2024
|
if (snapshot.error)
|
|
1976
|
-
output += `${
|
|
2025
|
+
output += `${chalk__default.default.red("\u2717")} ${chalk__default.default.gray(`${snapshot.name}
|
|
1977
2026
|
[error] ${snapshot.error}`)}
|
|
1978
2027
|
`;
|
|
1979
2028
|
else
|
|
1980
|
-
output += `${
|
|
1981
|
-
${snapshot.warnings.length ?
|
|
2029
|
+
output += `${chalk__default.default.green("\u2713")} ${chalk__default.default.gray(snapshot.name)}
|
|
2030
|
+
${snapshot.warnings.length ? chalk__default.default.gray(`[warning] ${snapshot.warnings.join("\n[warning] ")}
|
|
1982
2031
|
`) : ""}`;
|
|
1983
2032
|
}
|
|
1984
2033
|
task.output = output;
|
|
1985
2034
|
task.title = "Processed snapshots";
|
|
1986
2035
|
} catch (error) {
|
|
1987
2036
|
ctx2.log.debug(error);
|
|
1988
|
-
task.output =
|
|
2037
|
+
task.output = chalk__default.default.gray(error.message);
|
|
1989
2038
|
throw new Error("Processing of snapshots failed");
|
|
1990
2039
|
}
|
|
1991
2040
|
}),
|
|
@@ -1995,16 +2044,16 @@ ${snapshot.warnings.length ? chalk6__default.default.gray(`[warning] ${snapshot.
|
|
|
1995
2044
|
var finalizeBuild_default = (ctx) => {
|
|
1996
2045
|
return {
|
|
1997
2046
|
title: `Finalizing build`,
|
|
1998
|
-
task: (ctx2, task) => __async(
|
|
2047
|
+
task: (ctx2, task) => __async(void 0, null, function* () {
|
|
1999
2048
|
var _a, _b;
|
|
2000
2049
|
updateLogContext({ task: "finalizeBuild" });
|
|
2001
2050
|
try {
|
|
2002
2051
|
yield ctx2.client.finalizeBuild(ctx2.build.id, ctx2.totalSnapshots, ctx2.log);
|
|
2003
|
-
task.output =
|
|
2052
|
+
task.output = chalk__default.default.gray(`build url: ${ctx2.build.url}`);
|
|
2004
2053
|
task.title = "Finalized build";
|
|
2005
2054
|
} catch (error) {
|
|
2006
2055
|
ctx2.log.debug(error);
|
|
2007
|
-
task.output =
|
|
2056
|
+
task.output = chalk__default.default.gray(error.message);
|
|
2008
2057
|
throw new Error("Finalize build failed");
|
|
2009
2058
|
}
|
|
2010
2059
|
try {
|
|
@@ -2031,7 +2080,7 @@ function processSnapshot(snapshot, ctx) {
|
|
|
2031
2080
|
var _a, _b;
|
|
2032
2081
|
updateLogContext({ task: "discovery" });
|
|
2033
2082
|
ctx.log.debug(`Processing snapshot ${snapshot.name} ${snapshot.url}`);
|
|
2034
|
-
const isHeadless = ((_a = process.env.HEADLESS) == null ?
|
|
2083
|
+
const isHeadless = ((_a = process.env.HEADLESS) == null ? void 0 : _a.toLowerCase()) === "false" ? false : true;
|
|
2035
2084
|
let launchOptions = {
|
|
2036
2085
|
headless: isHeadless,
|
|
2037
2086
|
args: constants_default.LAUNCH_ARGS
|
|
@@ -2040,7 +2089,7 @@ function processSnapshot(snapshot, ctx) {
|
|
|
2040
2089
|
javaScriptEnabled: ctx.config.cliEnableJavaScript,
|
|
2041
2090
|
userAgent: constants_default.CHROME_USER_AGENT
|
|
2042
2091
|
};
|
|
2043
|
-
if (!((_b = ctx.browser) == null ?
|
|
2092
|
+
if (!((_b = ctx.browser) == null ? void 0 : _b.isConnected())) {
|
|
2044
2093
|
if (ctx.env.HTTP_PROXY || ctx.env.HTTPS_PROXY)
|
|
2045
2094
|
launchOptions.proxy = { server: ctx.env.HTTP_PROXY || ctx.env.HTTPS_PROXY };
|
|
2046
2095
|
if (ctx.env.SMARTUI_HTTP_PROXY || ctx.env.SMARTUI_HTTPS_PROXY)
|
|
@@ -2173,7 +2222,7 @@ function processSnapshot(snapshot, ctx) {
|
|
|
2173
2222
|
const isNotAllEmpty = (obj) => {
|
|
2174
2223
|
var _a2;
|
|
2175
2224
|
for (let key in obj)
|
|
2176
|
-
if ((_a2 = obj[key]) == null ?
|
|
2225
|
+
if ((_a2 = obj[key]) == null ? void 0 : _a2.length)
|
|
2177
2226
|
return true;
|
|
2178
2227
|
return false;
|
|
2179
2228
|
};
|
|
@@ -2301,11 +2350,11 @@ function processSnapshot(snapshot, ctx) {
|
|
|
2301
2350
|
return DEFAULT_HEIGHT;
|
|
2302
2351
|
}
|
|
2303
2352
|
const measurements = [
|
|
2304
|
-
(body == null ?
|
|
2305
|
-
(body == null ?
|
|
2306
|
-
(html == null ?
|
|
2307
|
-
(html == null ?
|
|
2308
|
-
(html == null ?
|
|
2353
|
+
(body == null ? void 0 : body.scrollHeight) || 0,
|
|
2354
|
+
(body == null ? void 0 : body.offsetHeight) || 0,
|
|
2355
|
+
(html == null ? void 0 : html.clientHeight) || 0,
|
|
2356
|
+
(html == null ? void 0 : html.scrollHeight) || 0,
|
|
2357
|
+
(html == null ? void 0 : html.offsetHeight) || 0
|
|
2309
2358
|
];
|
|
2310
2359
|
const allMeasurementsInvalid = measurements.every((measurement) => !measurement);
|
|
2311
2360
|
if (allMeasurementsInvalid) {
|
|
@@ -2420,7 +2469,7 @@ var Queue = class {
|
|
|
2420
2469
|
}
|
|
2421
2470
|
generateWebVariants(snapshot, webConfig) {
|
|
2422
2471
|
var _a, _b, _c;
|
|
2423
|
-
const browsers = (_c = (_b = webConfig.browsers) != null ? _b : (_a = this.ctx.config.web) == null ?
|
|
2472
|
+
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];
|
|
2424
2473
|
const viewports = webConfig.viewports || [];
|
|
2425
2474
|
for (const browser of browsers) {
|
|
2426
2475
|
for (const viewport of viewports) {
|
|
@@ -2434,7 +2483,7 @@ var Queue = class {
|
|
|
2434
2483
|
generateMobileVariants(snapshot, mobileConfig) {
|
|
2435
2484
|
var _a, _b, _c;
|
|
2436
2485
|
const devices = mobileConfig.devices || [];
|
|
2437
|
-
const orientation = (_c = (_b = mobileConfig.orientation) != null ? _b : (_a = this.ctx.config.mobile) == null ?
|
|
2486
|
+
const orientation = (_c = (_b = mobileConfig.orientation) != null ? _b : (_a = this.ctx.config.mobile) == null ? void 0 : _a.orientation) != null ? _c : constants_default.MOBILE_ORIENTATION_PORTRAIT;
|
|
2438
2487
|
for (const device of devices) {
|
|
2439
2488
|
const variant = `${snapshot.name}_${device}_${orientation}`;
|
|
2440
2489
|
this.variants.push(variant);
|
|
@@ -2516,7 +2565,7 @@ var Queue = class {
|
|
|
2516
2565
|
}
|
|
2517
2566
|
filterWebVariants(snapshot, webConfig) {
|
|
2518
2567
|
var _a, _b, _c;
|
|
2519
|
-
const browsers = (_c = (_b = webConfig.browsers) != null ? _b : (_a = this.ctx.config.web) == null ?
|
|
2568
|
+
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];
|
|
2520
2569
|
const viewports = webConfig.viewports || [];
|
|
2521
2570
|
let allVariantsDropped = true;
|
|
2522
2571
|
if (!snapshot.options) {
|
|
@@ -2554,8 +2603,8 @@ var Queue = class {
|
|
|
2554
2603
|
snapshot.options = {};
|
|
2555
2604
|
}
|
|
2556
2605
|
const devices = mobileConfig.devices || [];
|
|
2557
|
-
const orientation = (_c = (_b = mobileConfig.orientation) != null ? _b : (_a = this.ctx.config.mobile) == null ?
|
|
2558
|
-
const fullPage = (_f = (_e = mobileConfig.fullPage) != null ? _e : (_d = this.ctx.config.mobile) == null ?
|
|
2606
|
+
const orientation = (_c = (_b = mobileConfig.orientation) != null ? _b : (_a = this.ctx.config.mobile) == null ? void 0 : _a.orientation) != null ? _c : constants_default.MOBILE_ORIENTATION_PORTRAIT;
|
|
2607
|
+
const fullPage = (_f = (_e = mobileConfig.fullPage) != null ? _e : (_d = this.ctx.config.mobile) == null ? void 0 : _d.fullPage) != null ? _f : true;
|
|
2559
2608
|
let allVariantsDropped = true;
|
|
2560
2609
|
snapshot.options.mobile = { devices: [], orientation: constants_default.MOBILE_ORIENTATION_PORTRAIT, fullPage };
|
|
2561
2610
|
for (const device of devices) {
|
|
@@ -2580,6 +2629,9 @@ var Queue = class {
|
|
|
2580
2629
|
try {
|
|
2581
2630
|
this.processingSnapshot = snapshot == null ? void 0 : snapshot.name;
|
|
2582
2631
|
let drop = false;
|
|
2632
|
+
if (this.ctx.isStartExec) {
|
|
2633
|
+
this.ctx.log.info(`Processing Snapshot: ${snapshot == null ? void 0 : snapshot.name}`);
|
|
2634
|
+
}
|
|
2583
2635
|
if (!this.ctx.config.delayedUpload && snapshot && snapshot.name && this.snapshotNames.includes(snapshot.name)) {
|
|
2584
2636
|
drop = true;
|
|
2585
2637
|
this.ctx.log.info(`Skipping duplicate SmartUI snapshot '${snapshot.name}'. To capture duplicate screenshots, please set the 'delayedUpload' configuration as true in your config file.`);
|
|
@@ -2643,14 +2695,14 @@ var Queue = class {
|
|
|
2643
2695
|
|
|
2644
2696
|
// src/commander/exec.ts
|
|
2645
2697
|
var command = new commander.Command();
|
|
2646
|
-
command.name("exec").description("Run test commands around SmartUI").argument("<command...>", "Command supplied for running tests").option("-P, --port <number>", "Port number for the server").option("--fetch-results [filename]", "Fetch results and optionally specify an output file, e.g., <filename>.json").option("--buildName <string>", "Specify the build name").action(function(execCommand, _,
|
|
2698
|
+
command.name("exec").description("Run test commands around SmartUI").argument("<command...>", "Command supplied for running tests").option("-P, --port <number>", "Port number for the server").option("--fetch-results [filename]", "Fetch results and optionally specify an output file, e.g., <filename>.json").option("--buildName <string>", "Specify the build name").action(function(execCommand, _, command7) {
|
|
2647
2699
|
return __async(this, null, function* () {
|
|
2648
|
-
const options =
|
|
2700
|
+
const options = command7.optsWithGlobals();
|
|
2649
2701
|
if (options.buildName === "") {
|
|
2650
2702
|
console.log(`Error: The '--buildName' option cannot be an empty string.`);
|
|
2651
2703
|
process.exit(1);
|
|
2652
2704
|
}
|
|
2653
|
-
let ctx = ctx_default(
|
|
2705
|
+
let ctx = ctx_default(command7.optsWithGlobals());
|
|
2654
2706
|
if (!which__default.default.sync(execCommand[0], { nothrow: true })) {
|
|
2655
2707
|
ctx.log.error(`Error: Command not found "${execCommand[0]}"`);
|
|
2656
2708
|
return;
|
|
@@ -2762,9 +2814,9 @@ function verifyFigmaWebConfig(ctx) {
|
|
|
2762
2814
|
if (ctx.env.LT_ACCESS_KEY == "") {
|
|
2763
2815
|
throw new Error("Missing LT_ACCESS_KEY in Environment Variables");
|
|
2764
2816
|
}
|
|
2765
|
-
let figma = ctx.config && ((_a = ctx.config) == null ?
|
|
2817
|
+
let figma = ctx.config && ((_a = ctx.config) == null ? void 0 : _a.figma) || {};
|
|
2766
2818
|
const screenshots = [];
|
|
2767
|
-
for (let c of figma == null ?
|
|
2819
|
+
for (let c of figma == null ? void 0 : figma.configs) {
|
|
2768
2820
|
if (c.screenshot_names && c.screenshot_names.length > 0 && c.figma_ids && c.figma_ids.length != c.screenshot_names.length) {
|
|
2769
2821
|
throw new Error("Mismatch in Figma Ids and Screenshot Names in figma config");
|
|
2770
2822
|
}
|
|
@@ -2840,8 +2892,8 @@ function captureScreenshotsForConfig(_0, _1, _2, _3, _4) {
|
|
|
2840
2892
|
} catch (error) {
|
|
2841
2893
|
throw new Error(`captureScreenshotsForConfig failed for browser ${browserName}; error: ${error}`);
|
|
2842
2894
|
} finally {
|
|
2843
|
-
yield page == null ?
|
|
2844
|
-
yield context == null ?
|
|
2895
|
+
yield page == null ? void 0 : page.close();
|
|
2896
|
+
yield context == null ? void 0 : context.close();
|
|
2845
2897
|
}
|
|
2846
2898
|
});
|
|
2847
2899
|
}
|
|
@@ -2905,13 +2957,13 @@ function captureScreenshots(ctx) {
|
|
|
2905
2957
|
else
|
|
2906
2958
|
yield captureScreenshotsSync(ctx, staticConfig, browsers);
|
|
2907
2959
|
delDir(`screenshots/${staticConfig.name.toLowerCase().replace(/\s/g, "_")}`);
|
|
2908
|
-
output += `${
|
|
2960
|
+
output += `${chalk__default.default.gray(staticConfig.name)} ${chalk__default.default.green("\u2713")}
|
|
2909
2961
|
`;
|
|
2910
2962
|
ctx.task.output = output;
|
|
2911
2963
|
capturedScreenshots++;
|
|
2912
2964
|
} catch (error) {
|
|
2913
2965
|
ctx.log.debug(`screenshot capture failed for ${JSON.stringify(staticConfig)}; error: ${error}`);
|
|
2914
|
-
output += `${
|
|
2966
|
+
output += `${chalk__default.default.gray(staticConfig.name)} ${chalk__default.default.red("\u2717")}
|
|
2915
2967
|
`;
|
|
2916
2968
|
ctx.task.output = output;
|
|
2917
2969
|
}
|
|
@@ -3088,14 +3140,14 @@ function processChunk(ctx, urlConfig) {
|
|
|
3088
3140
|
try {
|
|
3089
3141
|
yield captureScreenshotsAsync(ctx, staticConfig, browsers);
|
|
3090
3142
|
delDir(`screenshots/${staticConfig.name.toLowerCase().replace(/\s/g, "_")}`);
|
|
3091
|
-
let output = `${
|
|
3143
|
+
let output = `${chalk__default.default.gray(staticConfig.name)} ${chalk__default.default.green("\u2713")}
|
|
3092
3144
|
`;
|
|
3093
3145
|
ctx.task.output = ctx.task.output ? ctx.task.output + output : output;
|
|
3094
3146
|
finalOutput += output;
|
|
3095
3147
|
capturedScreenshots++;
|
|
3096
3148
|
} catch (error) {
|
|
3097
3149
|
ctx.log.debug(`screenshot capture failed for ${JSON.stringify(staticConfig)}; error: ${error}`);
|
|
3098
|
-
let output = `${
|
|
3150
|
+
let output = `${chalk__default.default.gray(staticConfig.name)} ${chalk__default.default.red("\u2717")}
|
|
3099
3151
|
`;
|
|
3100
3152
|
ctx.task.output += output;
|
|
3101
3153
|
finalOutput += output;
|
|
@@ -3108,7 +3160,7 @@ function processChunk(ctx, urlConfig) {
|
|
|
3108
3160
|
var captureScreenshots_default = (ctx) => {
|
|
3109
3161
|
return {
|
|
3110
3162
|
title: "Capturing screenshots",
|
|
3111
|
-
task: (ctx2, task) => __async(
|
|
3163
|
+
task: (ctx2, task) => __async(void 0, null, function* () {
|
|
3112
3164
|
try {
|
|
3113
3165
|
ctx2.task = task;
|
|
3114
3166
|
if (ctx2.options.fetchResults) {
|
|
@@ -3129,7 +3181,7 @@ var captureScreenshots_default = (ctx) => {
|
|
|
3129
3181
|
task.title = "Screenshots captured successfully";
|
|
3130
3182
|
} catch (error) {
|
|
3131
3183
|
ctx2.log.debug(error);
|
|
3132
|
-
task.output =
|
|
3184
|
+
task.output = chalk__default.default.gray(`${error.message}`);
|
|
3133
3185
|
throw new Error("Capturing screenshots failed");
|
|
3134
3186
|
}
|
|
3135
3187
|
}),
|
|
@@ -3140,14 +3192,14 @@ var captureScreenshots_default = (ctx) => {
|
|
|
3140
3192
|
|
|
3141
3193
|
// src/commander/capture.ts
|
|
3142
3194
|
var command2 = new commander.Command();
|
|
3143
|
-
command2.name("capture").description("Capture screenshots of static sites").argument("<file>", "Web static config file").option("-C, --parallel [number]", "Specify the number of instances per browser", parseInt).option("-F, --force", "forcefully apply the specified parallel instances per browser").option("--fetch-results [filename]", "Fetch results and optionally specify an output file, e.g., <filename>.json").option("--buildName <string>", "Specify the build name").action(function(file, _,
|
|
3195
|
+
command2.name("capture").description("Capture screenshots of static sites").argument("<file>", "Web static config file").option("-C, --parallel [number]", "Specify the number of instances per browser", parseInt).option("-F, --force", "forcefully apply the specified parallel instances per browser").option("--fetch-results [filename]", "Fetch results and optionally specify an output file, e.g., <filename>.json").option("--buildName <string>", "Specify the build name").action(function(file, _, command7) {
|
|
3144
3196
|
return __async(this, null, function* () {
|
|
3145
|
-
const options =
|
|
3197
|
+
const options = command7.optsWithGlobals();
|
|
3146
3198
|
if (options.buildName === "") {
|
|
3147
3199
|
console.log(`Error: The '--buildName' option cannot be an empty string.`);
|
|
3148
3200
|
process.exit(1);
|
|
3149
3201
|
}
|
|
3150
|
-
let ctx = ctx_default(
|
|
3202
|
+
let ctx = ctx_default(command7.optsWithGlobals());
|
|
3151
3203
|
if (!fs5__default.default.existsSync(file)) {
|
|
3152
3204
|
ctx.log.error(`Web Static Config file ${file} not found.`);
|
|
3153
3205
|
return;
|
|
@@ -3195,7 +3247,7 @@ var capture_default = command2;
|
|
|
3195
3247
|
var uploadScreenshots_default = (ctx) => {
|
|
3196
3248
|
return {
|
|
3197
3249
|
title: "Uploading screenshots",
|
|
3198
|
-
task: (ctx2, task) => __async(
|
|
3250
|
+
task: (ctx2, task) => __async(void 0, null, function* () {
|
|
3199
3251
|
try {
|
|
3200
3252
|
ctx2.task = task;
|
|
3201
3253
|
if (ctx2.options.fetchResults) {
|
|
@@ -3206,7 +3258,7 @@ var uploadScreenshots_default = (ctx) => {
|
|
|
3206
3258
|
task.title = "Screenshots uploaded successfully";
|
|
3207
3259
|
} catch (error) {
|
|
3208
3260
|
ctx2.log.debug(error);
|
|
3209
|
-
task.output =
|
|
3261
|
+
task.output = chalk__default.default.gray(`${error.message}`);
|
|
3210
3262
|
throw new Error("Uploading screenshots failed");
|
|
3211
3263
|
}
|
|
3212
3264
|
}),
|
|
@@ -3221,14 +3273,14 @@ command3.name("upload").description("Upload screenshots from given directory").a
|
|
|
3221
3273
|
return val.split(",").map((ext) => ext.trim().toLowerCase());
|
|
3222
3274
|
}).option("-E, --removeExtensions", "Strips file extensions from snapshot names").option("-i, --ignoreDir <patterns>", "Comma-separated list of directories to ignore", (val) => {
|
|
3223
3275
|
return val.split(",").map((pattern) => pattern.trim());
|
|
3224
|
-
}).option("--fetch-results [filename]", "Fetch results and optionally specify an output file, e.g., <filename>.json").option("--buildName <string>", "Specify the build name").action(function(directory, _,
|
|
3276
|
+
}).option("--fetch-results [filename]", "Fetch results and optionally specify an output file, e.g., <filename>.json").option("--buildName <string>", "Specify the build name").action(function(directory, _, command7) {
|
|
3225
3277
|
return __async(this, null, function* () {
|
|
3226
|
-
const options =
|
|
3278
|
+
const options = command7.optsWithGlobals();
|
|
3227
3279
|
if (options.buildName === "") {
|
|
3228
3280
|
console.log(`Error: The '--buildName' option cannot be an empty string.`);
|
|
3229
3281
|
process.exit(1);
|
|
3230
3282
|
}
|
|
3231
|
-
let ctx = ctx_default(
|
|
3283
|
+
let ctx = ctx_default(command7.optsWithGlobals());
|
|
3232
3284
|
if (!fs5__default.default.existsSync(directory)) {
|
|
3233
3285
|
console.log(`Error: The provided directory ${directory} not found.`);
|
|
3234
3286
|
return;
|
|
@@ -3267,7 +3319,7 @@ command3.name("upload").description("Upload screenshots from given directory").a
|
|
|
3267
3319
|
var upload_default = command3;
|
|
3268
3320
|
|
|
3269
3321
|
// src/lib/uploadFigmaDesigns.ts
|
|
3270
|
-
var uploadFigmaDesigns_default = (ctx) => __async(
|
|
3322
|
+
var uploadFigmaDesigns_default = (ctx) => __async(void 0, null, function* () {
|
|
3271
3323
|
const depth = ctx.figmaDesignConfig.depth;
|
|
3272
3324
|
const figmaConfigs = ctx.figmaDesignConfig.figma_config;
|
|
3273
3325
|
let results = "";
|
|
@@ -3294,7 +3346,7 @@ var uploadFigmaDesigns_default = (ctx) => __async(undefined, null, function* ()
|
|
|
3294
3346
|
var uploadFigmaDesigns_default2 = (ctx) => {
|
|
3295
3347
|
return {
|
|
3296
3348
|
title: "Uploading Figma Designs",
|
|
3297
|
-
task: (ctx2, task) => __async(
|
|
3349
|
+
task: (ctx2, task) => __async(void 0, null, function* () {
|
|
3298
3350
|
try {
|
|
3299
3351
|
ctx2.task = task;
|
|
3300
3352
|
updateLogContext({ task: "upload-figma" });
|
|
@@ -3306,7 +3358,7 @@ var uploadFigmaDesigns_default2 = (ctx) => {
|
|
|
3306
3358
|
ctx2.log.debug(`Figma designs processed: ${results}`);
|
|
3307
3359
|
} catch (error) {
|
|
3308
3360
|
ctx2.log.debug(error);
|
|
3309
|
-
task.output =
|
|
3361
|
+
task.output = chalk__default.default.gray(`${error.message}`);
|
|
3310
3362
|
throw new Error("Uploading Figma designs failed");
|
|
3311
3363
|
}
|
|
3312
3364
|
}),
|
|
@@ -3316,13 +3368,13 @@ var uploadFigmaDesigns_default2 = (ctx) => {
|
|
|
3316
3368
|
};
|
|
3317
3369
|
|
|
3318
3370
|
// src/lib/uploadWebFigma.ts
|
|
3319
|
-
var uploadWebFigma_default = (ctx) => __async(
|
|
3371
|
+
var uploadWebFigma_default = (ctx) => __async(void 0, null, function* () {
|
|
3320
3372
|
var _a, _b;
|
|
3321
|
-
const figmaConfig = ctx.config && ((_a = ctx.config) == null ?
|
|
3322
|
-
const webConfig = ctx.config && ((_b = ctx.config) == null ?
|
|
3373
|
+
const figmaConfig = ctx.config && ((_a = ctx.config) == null ? void 0 : _a.figma) || {};
|
|
3374
|
+
const webConfig = ctx.config && ((_b = ctx.config) == null ? void 0 : _b.web) || {};
|
|
3323
3375
|
let results = "";
|
|
3324
3376
|
const buildName = ctx.options.buildName;
|
|
3325
|
-
if (figmaConfig.configs && figmaConfig.configs.length > 0) {
|
|
3377
|
+
if (figmaConfig && figmaConfig.configs && figmaConfig.configs.length > 0) {
|
|
3326
3378
|
const authToken = `Basic ${Buffer.from(`${ctx.env.LT_USERNAME}:${ctx.env.LT_ACCESS_KEY}`).toString("base64")}`;
|
|
3327
3379
|
const requestBody = {
|
|
3328
3380
|
figma_token: ctx.env.FIGMA_TOKEN,
|
|
@@ -3349,7 +3401,7 @@ var uploadWebFigma_default = (ctx) => __async(undefined, null, function* () {
|
|
|
3349
3401
|
});
|
|
3350
3402
|
|
|
3351
3403
|
// src/lib/fetchFigma.ts
|
|
3352
|
-
var fetchFigma_default = (ctx) => __async(
|
|
3404
|
+
var fetchFigma_default = (ctx) => __async(void 0, null, function* () {
|
|
3353
3405
|
const buildId = ctx.build.id;
|
|
3354
3406
|
ctx.log.debug(`Fetching figma results for buildId ${buildId}`);
|
|
3355
3407
|
const startTime = Date.now();
|
|
@@ -3394,7 +3446,7 @@ function callFetchWebFigmaRecursive(startTime, buildId, ctx) {
|
|
|
3394
3446
|
var uploadWebFigma_default2 = (ctx) => {
|
|
3395
3447
|
return {
|
|
3396
3448
|
title: "Processing Web Figma",
|
|
3397
|
-
task: (ctx2, task) => __async(
|
|
3449
|
+
task: (ctx2, task) => __async(void 0, null, function* () {
|
|
3398
3450
|
try {
|
|
3399
3451
|
ctx2.task = task;
|
|
3400
3452
|
updateLogContext({ task: "upload-figma-web" });
|
|
@@ -3403,17 +3455,17 @@ var uploadWebFigma_default2 = (ctx) => {
|
|
|
3403
3455
|
throw new Error("Uploading Web Figma Screenshot failed");
|
|
3404
3456
|
}
|
|
3405
3457
|
if (ctx2.build.id) {
|
|
3406
|
-
task.output =
|
|
3458
|
+
task.output = chalk__default.default.gray(`Build Id: ${ctx2.build.id}`);
|
|
3407
3459
|
let figmaOutput = yield fetchFigma_default(ctx2);
|
|
3408
3460
|
const jsonObject = JSON.parse(figmaOutput);
|
|
3409
3461
|
let output = JSON.stringify(jsonObject, null, 2);
|
|
3410
|
-
task.output = task.output + "\n" +
|
|
3462
|
+
task.output = task.output + "\n" + chalk__default.default.green(`${output}`);
|
|
3411
3463
|
}
|
|
3412
3464
|
task.title = "Web Figma images uploaded successfully to SmartUI";
|
|
3413
3465
|
ctx2.log.debug(`Web Figma processed: ${results}`);
|
|
3414
3466
|
} catch (error) {
|
|
3415
3467
|
ctx2.log.debug(error);
|
|
3416
|
-
task.output =
|
|
3468
|
+
task.output = chalk__default.default.gray(`${error.message}`);
|
|
3417
3469
|
throw new Error("Uploading Web Figma Screenshots failed");
|
|
3418
3470
|
}
|
|
3419
3471
|
}),
|
|
@@ -3423,10 +3475,10 @@ var uploadWebFigma_default2 = (ctx) => {
|
|
|
3423
3475
|
};
|
|
3424
3476
|
var uploadFigma = new commander.Command();
|
|
3425
3477
|
var uploadWebFigmaCommand = new commander.Command();
|
|
3426
|
-
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, _,
|
|
3478
|
+
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, _, command7) {
|
|
3427
3479
|
return __async(this, null, function* () {
|
|
3428
3480
|
var _a, _b;
|
|
3429
|
-
let ctx = ctx_default(
|
|
3481
|
+
let ctx = ctx_default(command7.optsWithGlobals());
|
|
3430
3482
|
if (!fs5__default.default.existsSync(file)) {
|
|
3431
3483
|
console.log(`Error: Figma Config file ${file} not found.`);
|
|
3432
3484
|
return;
|
|
@@ -3464,10 +3516,10 @@ uploadFigma.name("upload-figma").description("Capture screenshots of static site
|
|
|
3464
3516
|
}
|
|
3465
3517
|
});
|
|
3466
3518
|
});
|
|
3467
|
-
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, _,
|
|
3519
|
+
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) {
|
|
3468
3520
|
return __async(this, null, function* () {
|
|
3469
3521
|
var _a;
|
|
3470
|
-
let ctx = ctx_default(
|
|
3522
|
+
let ctx = ctx_default(command7.optsWithGlobals());
|
|
3471
3523
|
if (!fs5__default.default.existsSync(file)) {
|
|
3472
3524
|
console.log(`Error: figma-web config file ${file} not found.`);
|
|
3473
3525
|
return;
|
|
@@ -3488,7 +3540,7 @@ uploadWebFigmaCommand.name("upload-figma-web").description("Capture screenshots
|
|
|
3488
3540
|
}
|
|
3489
3541
|
verifyFigmaWebConfig(ctx);
|
|
3490
3542
|
} catch (error) {
|
|
3491
|
-
ctx.log.error(
|
|
3543
|
+
ctx.log.error(chalk__default.default.red(`Invalid figma-web config; ${error.message}`));
|
|
3492
3544
|
return;
|
|
3493
3545
|
}
|
|
3494
3546
|
let tasks = new listr2.Listr(
|
|
@@ -3516,10 +3568,112 @@ uploadWebFigmaCommand.name("upload-figma-web").description("Capture screenshots
|
|
|
3516
3568
|
}
|
|
3517
3569
|
});
|
|
3518
3570
|
});
|
|
3571
|
+
var command4 = new commander.Command();
|
|
3572
|
+
command4.name("exec:start").description("Start SmartUI server").option("-P, --port <number>", "Port number for the server").option("--fetch-results [filename]", "Fetch results and optionally specify an output file, e.g., <filename>.json").option("--buildName <string>", "Specify the build name").action(function() {
|
|
3573
|
+
return __async(this, null, function* () {
|
|
3574
|
+
const options = command4.optsWithGlobals();
|
|
3575
|
+
if (options.buildName === "") {
|
|
3576
|
+
console.log(`Error: The '--buildName' option cannot be an empty string.`);
|
|
3577
|
+
process.exit(1);
|
|
3578
|
+
}
|
|
3579
|
+
let ctx = ctx_default(command4.optsWithGlobals());
|
|
3580
|
+
ctx.snapshotQueue = new Queue(ctx);
|
|
3581
|
+
ctx.totalSnapshots = 0;
|
|
3582
|
+
ctx.isStartExec = true;
|
|
3583
|
+
let tasks = new listr2.Listr(
|
|
3584
|
+
[
|
|
3585
|
+
auth_default(),
|
|
3586
|
+
startServer_default(),
|
|
3587
|
+
getGitInfo_default(),
|
|
3588
|
+
createBuild_default()
|
|
3589
|
+
],
|
|
3590
|
+
{
|
|
3591
|
+
rendererOptions: {
|
|
3592
|
+
icon: {
|
|
3593
|
+
[listr2.ListrDefaultRendererLogLevels.OUTPUT]: `\u2192`
|
|
3594
|
+
},
|
|
3595
|
+
color: {
|
|
3596
|
+
[listr2.ListrDefaultRendererLogLevels.OUTPUT]: listr2.color.gray
|
|
3597
|
+
}
|
|
3598
|
+
}
|
|
3599
|
+
}
|
|
3600
|
+
);
|
|
3601
|
+
try {
|
|
3602
|
+
yield tasks.run(ctx);
|
|
3603
|
+
startPingPolling(ctx);
|
|
3604
|
+
if (ctx.options.fetchResults) {
|
|
3605
|
+
startPolling(ctx);
|
|
3606
|
+
}
|
|
3607
|
+
} catch (error) {
|
|
3608
|
+
console.error("Error during server execution:", error);
|
|
3609
|
+
}
|
|
3610
|
+
});
|
|
3611
|
+
});
|
|
3612
|
+
var server_default2 = command4;
|
|
3613
|
+
var command5 = new commander.Command();
|
|
3614
|
+
function getSmartUIServerAddress() {
|
|
3615
|
+
const serverAddress = process.env.SMARTUI_SERVER_ADDRESS || "http://localhost:49152";
|
|
3616
|
+
return serverAddress;
|
|
3617
|
+
}
|
|
3618
|
+
command5.name("exec:stop").description("Stop the SmartUI server").action(function() {
|
|
3619
|
+
return __async(this, null, function* () {
|
|
3620
|
+
try {
|
|
3621
|
+
const serverAddress = getSmartUIServerAddress();
|
|
3622
|
+
console.log(chalk__default.default.yellow(`Stopping server at ${serverAddress} from terminal...`));
|
|
3623
|
+
const response = yield axios__default.default.post(`${serverAddress}/stop`, { timeout: 15e3 }, {
|
|
3624
|
+
headers: {
|
|
3625
|
+
"Content-Type": "application/json"
|
|
3626
|
+
// Ensure the correct Content-Type header
|
|
3627
|
+
}
|
|
3628
|
+
});
|
|
3629
|
+
if (response.status === 200) {
|
|
3630
|
+
console.log(chalk__default.default.green("Server stopped successfully"));
|
|
3631
|
+
console.log(chalk__default.default.green(`Response: ${JSON.stringify(response.data)}`));
|
|
3632
|
+
} else {
|
|
3633
|
+
console.log(chalk__default.default.red("Failed to stop server"));
|
|
3634
|
+
}
|
|
3635
|
+
} catch (error) {
|
|
3636
|
+
if (error.code === "ECONNABORTED") {
|
|
3637
|
+
console.error(chalk__default.default.red("Error: SmartUI server did not respond in 15 seconds"));
|
|
3638
|
+
} else {
|
|
3639
|
+
console.error(chalk__default.default.red("Error while stopping server"));
|
|
3640
|
+
}
|
|
3641
|
+
}
|
|
3642
|
+
});
|
|
3643
|
+
});
|
|
3644
|
+
var stopServer_default = command5;
|
|
3645
|
+
function getSmartUIServerAddress2() {
|
|
3646
|
+
const serverAddress = process.env.SMARTUI_SERVER_ADDRESS || "http://localhost:49152";
|
|
3647
|
+
return serverAddress;
|
|
3648
|
+
}
|
|
3649
|
+
var command6 = new commander.Command();
|
|
3650
|
+
command6.name("exec:ping").description("Ping the SmartUI server to check if it is running").action(function() {
|
|
3651
|
+
return __async(this, null, function* () {
|
|
3652
|
+
try {
|
|
3653
|
+
console.log(chalk__default.default.yellow("Pinging server..."));
|
|
3654
|
+
const serverAddress = getSmartUIServerAddress2();
|
|
3655
|
+
console.log(chalk__default.default.yellow(`Pinging server at ${serverAddress} from terminal...`));
|
|
3656
|
+
const response = yield axios__default.default.get(`${serverAddress}/ping`, { timeout: 15e3 });
|
|
3657
|
+
if (response.status === 200) {
|
|
3658
|
+
console.log(chalk__default.default.green("SmartUI Server is running"));
|
|
3659
|
+
console.log(chalk__default.default.green(`Response: ${JSON.stringify(response.data)}`));
|
|
3660
|
+
} else {
|
|
3661
|
+
console.log(chalk__default.default.red("Failed to reach the server"));
|
|
3662
|
+
}
|
|
3663
|
+
} catch (error) {
|
|
3664
|
+
if (error.code === "ECONNABORTED") {
|
|
3665
|
+
console.error(chalk__default.default.red("Error: SmartUI server did not respond in 15 seconds"));
|
|
3666
|
+
} else {
|
|
3667
|
+
console.error(chalk__default.default.red("SmartUI server is not running"));
|
|
3668
|
+
}
|
|
3669
|
+
}
|
|
3670
|
+
});
|
|
3671
|
+
});
|
|
3672
|
+
var ping_default = command6;
|
|
3519
3673
|
|
|
3520
3674
|
// src/commander/commander.ts
|
|
3521
3675
|
var program = new commander.Command();
|
|
3522
|
-
program.name("smartui").description("CLI to help you run your SmartUI tests on LambdaTest platform").version(`v${version}`).option("-c --config <filepath>", "Config file path").addCommand(exec_default2).addCommand(capture_default).addCommand(configWeb).addCommand(configStatic).addCommand(upload_default).addCommand(configFigma).addCommand(uploadFigma).addCommand(configWebFigma).addCommand(uploadWebFigmaCommand);
|
|
3676
|
+
program.name("smartui").description("CLI to help you run your SmartUI tests on LambdaTest platform").version(`v${version}`).option("-c --config <filepath>", "Config file path").addCommand(exec_default2).addCommand(capture_default).addCommand(configWeb).addCommand(configStatic).addCommand(upload_default).addCommand(server_default2).addCommand(stopServer_default).addCommand(ping_default).addCommand(configFigma).addCommand(uploadFigma).addCommand(configWebFigma).addCommand(uploadWebFigmaCommand);
|
|
3523
3677
|
var commander_default = program;
|
|
3524
3678
|
(function() {
|
|
3525
3679
|
return __async(this, null, function* () {
|
|
@@ -3529,16 +3683,16 @@ var commander_default = program;
|
|
|
3529
3683
|
let { data: { latestVersion, deprecated, additionalDescription } } = yield client.checkUpdate(log2);
|
|
3530
3684
|
log2.info(`
|
|
3531
3685
|
LambdaTest SmartUI CLI v${package_default.version}`);
|
|
3532
|
-
log2.info(
|
|
3686
|
+
log2.info(chalk__default.default.yellow(`${additionalDescription}`));
|
|
3533
3687
|
if (deprecated) {
|
|
3534
3688
|
log2.warn(`This version is deprecated. A new version ${latestVersion} is available!`);
|
|
3535
3689
|
} else if (package_default.version !== latestVersion) {
|
|
3536
|
-
log2.info(
|
|
3690
|
+
log2.info(chalk__default.default.green(`A new version ${latestVersion} is available!`));
|
|
3537
3691
|
} else
|
|
3538
|
-
log2.info(
|
|
3692
|
+
log2.info(chalk__default.default.gray("https://www.npmjs.com/package/@lambdatest/smartui-cli\n"));
|
|
3539
3693
|
} catch (error) {
|
|
3540
3694
|
log2.debug(error);
|
|
3541
|
-
log2.info(
|
|
3695
|
+
log2.info(chalk__default.default.gray("https://www.npmjs.com/package/@lambdatest/smartui-cli\n"));
|
|
3542
3696
|
}
|
|
3543
3697
|
commander_default.parse();
|
|
3544
3698
|
});
|