@lambdatest/smartui-cli 4.1.28 → 4.1.29
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 +372 -42
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1716,6 +1716,130 @@ function calculateVariantCountFromSnapshot(snapshot, globalConfig) {
|
|
|
1716
1716
|
}
|
|
1717
1717
|
return variantCount;
|
|
1718
1718
|
}
|
|
1719
|
+
function startPdfPolling(ctx) {
|
|
1720
|
+
console.log(chalk__default.default.yellow("\nFetching PDF test results..."));
|
|
1721
|
+
ctx.log.debug(`Starting fetching results for build: ${ctx.build.id || ctx.build.name}`);
|
|
1722
|
+
if (!ctx.build.id && !ctx.build.name) {
|
|
1723
|
+
ctx.log.error(chalk__default.default.red("Error: Build information not found for fetching results"));
|
|
1724
|
+
return;
|
|
1725
|
+
}
|
|
1726
|
+
if (!ctx.env.LT_USERNAME || !ctx.env.LT_ACCESS_KEY) {
|
|
1727
|
+
console.log(chalk__default.default.red("Error: LT_USERNAME and LT_ACCESS_KEY environment variables are required for fetching results"));
|
|
1728
|
+
return;
|
|
1729
|
+
}
|
|
1730
|
+
let attempts = 0;
|
|
1731
|
+
const maxAttempts = 60;
|
|
1732
|
+
console.log(chalk__default.default.yellow("Waiting for results..."));
|
|
1733
|
+
const interval = setInterval(() => __async(this, null, function* () {
|
|
1734
|
+
attempts++;
|
|
1735
|
+
try {
|
|
1736
|
+
const response = yield ctx.client.fetchPdfResults(ctx);
|
|
1737
|
+
if (response.screenshots) {
|
|
1738
|
+
clearInterval(interval);
|
|
1739
|
+
const pdfGroups = groupScreenshotsByPdf(response.screenshots);
|
|
1740
|
+
const pdfsWithMismatches = countPdfsWithMismatches(pdfGroups);
|
|
1741
|
+
const pagesWithMismatches = countPagesWithMismatches(response.screenshots);
|
|
1742
|
+
console.log(chalk__default.default.green("\n\u2713 PDF Test Results:"));
|
|
1743
|
+
console.log(chalk__default.default.green(`Build Name: ${response.build.name}`));
|
|
1744
|
+
console.log(chalk__default.default.green(`Project Name: ${response.project.name}`));
|
|
1745
|
+
console.log(chalk__default.default.green(`Total PDFs: ${Object.keys(pdfGroups).length}`));
|
|
1746
|
+
console.log(chalk__default.default.green(`Total Pages: ${response.screenshots.length}`));
|
|
1747
|
+
if (pdfsWithMismatches > 0 || pagesWithMismatches > 0) {
|
|
1748
|
+
console.log(chalk__default.default.yellow(`${pdfsWithMismatches} PDFs and ${pagesWithMismatches} Pages in build ${response.build.name} have changes present.`));
|
|
1749
|
+
} else {
|
|
1750
|
+
console.log(chalk__default.default.green("All PDFs match the baseline."));
|
|
1751
|
+
}
|
|
1752
|
+
Object.entries(pdfGroups).forEach(([pdfName, pages]) => {
|
|
1753
|
+
const hasMismatch = pages.some((page) => page.mismatch_percentage > 0);
|
|
1754
|
+
const statusColor = hasMismatch ? chalk__default.default.yellow : chalk__default.default.green;
|
|
1755
|
+
console.log(statusColor(`
|
|
1756
|
+
\u{1F4C4} ${pdfName} (${pages.length} pages)`));
|
|
1757
|
+
pages.forEach((page) => {
|
|
1758
|
+
const pageStatusColor = page.mismatch_percentage > 0 ? chalk__default.default.yellow : chalk__default.default.green;
|
|
1759
|
+
console.log(pageStatusColor(` - Page ${getPageNumber(page.screenshot_name)}: ${page.status} (Mismatch: ${page.mismatch_percentage}%)`));
|
|
1760
|
+
});
|
|
1761
|
+
});
|
|
1762
|
+
const formattedResults = {
|
|
1763
|
+
status: "success",
|
|
1764
|
+
data: {
|
|
1765
|
+
buildId: response.build.id,
|
|
1766
|
+
buildName: response.build.name,
|
|
1767
|
+
projectName: response.project.name,
|
|
1768
|
+
buildStatus: response.build.build_satus,
|
|
1769
|
+
pdfs: formatPdfsForOutput(pdfGroups)
|
|
1770
|
+
}
|
|
1771
|
+
};
|
|
1772
|
+
if (ctx.options.fetchResults && ctx.options.fetchResultsFileName) {
|
|
1773
|
+
const filename = ctx.options.fetchResultsFileName !== "" ? ctx.options.fetchResultsFileName : "pdf-results.json";
|
|
1774
|
+
fs5__default.default.writeFileSync(filename, JSON.stringify(formattedResults, null, 2));
|
|
1775
|
+
console.log(chalk__default.default.green(`
|
|
1776
|
+
Results saved to ${filename}`));
|
|
1777
|
+
}
|
|
1778
|
+
return;
|
|
1779
|
+
}
|
|
1780
|
+
if (attempts >= maxAttempts) {
|
|
1781
|
+
clearInterval(interval);
|
|
1782
|
+
console.log(chalk__default.default.red("\nTimeout: Could not fetch PDF results after 5 minutes"));
|
|
1783
|
+
return;
|
|
1784
|
+
}
|
|
1785
|
+
} catch (error) {
|
|
1786
|
+
ctx.log.debug(`Error during polling: ${error.message}`);
|
|
1787
|
+
if (attempts >= maxAttempts) {
|
|
1788
|
+
clearInterval(interval);
|
|
1789
|
+
console.log(chalk__default.default.red("\nTimeout: Could not fetch PDF results after 5 minutes"));
|
|
1790
|
+
if (error.response && error.response.data) {
|
|
1791
|
+
console.log(chalk__default.default.red(`Error details: ${JSON.stringify(error.response.data)}`));
|
|
1792
|
+
} else {
|
|
1793
|
+
console.log(chalk__default.default.red(`Error details: ${error.message}`));
|
|
1794
|
+
}
|
|
1795
|
+
return;
|
|
1796
|
+
}
|
|
1797
|
+
process.stdout.write(chalk__default.default.yellow("."));
|
|
1798
|
+
}
|
|
1799
|
+
}), 1e4);
|
|
1800
|
+
}
|
|
1801
|
+
function groupScreenshotsByPdf(screenshots) {
|
|
1802
|
+
const pdfGroups = {};
|
|
1803
|
+
screenshots.forEach((screenshot) => {
|
|
1804
|
+
const pdfName = screenshot.screenshot_name.split("#")[0];
|
|
1805
|
+
if (!pdfGroups[pdfName]) {
|
|
1806
|
+
pdfGroups[pdfName] = [];
|
|
1807
|
+
}
|
|
1808
|
+
pdfGroups[pdfName].push(screenshot);
|
|
1809
|
+
});
|
|
1810
|
+
return pdfGroups;
|
|
1811
|
+
}
|
|
1812
|
+
function countPdfsWithMismatches(pdfGroups) {
|
|
1813
|
+
let count = 0;
|
|
1814
|
+
Object.values(pdfGroups).forEach((pages) => {
|
|
1815
|
+
if (pages.some((page) => page.mismatch_percentage > 0)) {
|
|
1816
|
+
count++;
|
|
1817
|
+
}
|
|
1818
|
+
});
|
|
1819
|
+
return count;
|
|
1820
|
+
}
|
|
1821
|
+
function countPagesWithMismatches(screenshots) {
|
|
1822
|
+
return screenshots.filter((screenshot) => screenshot.mismatch_percentage > 0).length;
|
|
1823
|
+
}
|
|
1824
|
+
function formatPdfsForOutput(pdfGroups) {
|
|
1825
|
+
return Object.entries(pdfGroups).map(([pdfName, pages]) => {
|
|
1826
|
+
return {
|
|
1827
|
+
pdfName,
|
|
1828
|
+
pageCount: pages.length,
|
|
1829
|
+
pages: pages.map((page) => ({
|
|
1830
|
+
pageNumber: getPageNumber(page.screenshot_name),
|
|
1831
|
+
screenshotId: page.captured_image_id,
|
|
1832
|
+
mismatchPercentage: page.mismatch_percentage,
|
|
1833
|
+
status: page.status,
|
|
1834
|
+
screenshotUrl: page.shareable_link
|
|
1835
|
+
}))
|
|
1836
|
+
};
|
|
1837
|
+
});
|
|
1838
|
+
}
|
|
1839
|
+
function getPageNumber(screenshotName) {
|
|
1840
|
+
const parts = screenshotName.split("#");
|
|
1841
|
+
return parts.length > 1 ? parts[1] : "1";
|
|
1842
|
+
}
|
|
1719
1843
|
|
|
1720
1844
|
// src/lib/server.ts
|
|
1721
1845
|
var uploadDomToS3ViaEnv = process.env.USE_LAMBDA_INTERNAL || false;
|
|
@@ -1764,7 +1888,6 @@ var server_default = (ctx) => __async(void 0, null, function* () {
|
|
|
1764
1888
|
}
|
|
1765
1889
|
} catch (error) {
|
|
1766
1890
|
ctx.log.debug(`Failed to fetch capabilities for sessionId ${sessionId}: ${error.message}`);
|
|
1767
|
-
console.log(`Failed to fetch capabilities for sessionId ${sessionId}: ${error.message}`);
|
|
1768
1891
|
}
|
|
1769
1892
|
}
|
|
1770
1893
|
if (capsBuildId && capsBuildId !== "") {
|
|
@@ -1813,19 +1936,39 @@ var server_default = (ctx) => __async(void 0, null, function* () {
|
|
|
1813
1936
|
}
|
|
1814
1937
|
}, 1e3);
|
|
1815
1938
|
});
|
|
1816
|
-
|
|
1817
|
-
|
|
1939
|
+
for (const [sessionId, capabilities] of ctx.sessionCapabilitiesMap.entries()) {
|
|
1940
|
+
try {
|
|
1941
|
+
const buildId = (capabilities == null ? void 0 : capabilities.buildId) || "";
|
|
1942
|
+
const projectToken = (capabilities == null ? void 0 : capabilities.projectToken) || "";
|
|
1943
|
+
const totalSnapshots = (capabilities == null ? void 0 : capabilities.snapshotCount) || 0;
|
|
1944
|
+
const sessionBuildUrl = (capabilities == null ? void 0 : capabilities.buildURL) || "";
|
|
1945
|
+
const testId = (capabilities == null ? void 0 : capabilities.id) || "";
|
|
1946
|
+
if (buildId && projectToken) {
|
|
1947
|
+
yield ctx.client.finalizeBuildForCapsWithToken(buildId, totalSnapshots, projectToken, ctx.log);
|
|
1948
|
+
}
|
|
1949
|
+
if (testId && buildId) {
|
|
1950
|
+
buildUrls += `TestId ${testId}: ${sessionBuildUrl}
|
|
1951
|
+
`;
|
|
1952
|
+
}
|
|
1953
|
+
} catch (error) {
|
|
1954
|
+
ctx.log.debug(`Error finalizing build for session ${sessionId}: ${error.message}`);
|
|
1955
|
+
}
|
|
1956
|
+
}
|
|
1957
|
+
if (ctx.build && ctx.build.id) {
|
|
1958
|
+
yield ctx.client.finalizeBuild(ctx.build.id, ctx.totalSnapshots, ctx.log);
|
|
1959
|
+
let uploadCLILogsToS3 = ((_b = ctx == null ? void 0 : ctx.config) == null ? void 0 : _b.useLambdaInternal) || uploadDomToS3ViaEnv;
|
|
1960
|
+
if (!uploadCLILogsToS3) {
|
|
1961
|
+
ctx.log.debug(`Log file to be uploaded`);
|
|
1962
|
+
let resp = yield ctx.client.getS3PreSignedURL(ctx);
|
|
1963
|
+
yield ctx.client.uploadLogs(ctx, resp.data.url);
|
|
1964
|
+
} else {
|
|
1965
|
+
ctx.log.debug(`Skipping upload of CLI logs as useLambdaInternal is set`);
|
|
1966
|
+
}
|
|
1967
|
+
}
|
|
1968
|
+
yield (_c = ctx.browser) == null ? void 0 : _c.close();
|
|
1818
1969
|
if (ctx.server) {
|
|
1819
1970
|
ctx.server.close();
|
|
1820
1971
|
}
|
|
1821
|
-
let uploadCLILogsToS3 = ((_c = ctx == null ? void 0 : ctx.config) == null ? void 0 : _c.useLambdaInternal) || uploadDomToS3ViaEnv;
|
|
1822
|
-
if (!uploadCLILogsToS3) {
|
|
1823
|
-
ctx.log.debug(`Log file to be uploaded`);
|
|
1824
|
-
let resp = yield ctx.client.getS3PreSignedURL(ctx);
|
|
1825
|
-
yield ctx.client.uploadLogs(ctx, resp.data.url);
|
|
1826
|
-
} else {
|
|
1827
|
-
ctx.log.debug(`Skipping upload of CLI logs as useLambdaInternal is set`);
|
|
1828
|
-
}
|
|
1829
1972
|
if (pingIntervalId !== null) {
|
|
1830
1973
|
clearInterval(pingIntervalId);
|
|
1831
1974
|
ctx.log.debug("Ping polling stopped immediately.");
|
|
@@ -1942,6 +2085,7 @@ var env_default = () => {
|
|
|
1942
2085
|
const {
|
|
1943
2086
|
PROJECT_TOKEN = "",
|
|
1944
2087
|
SMARTUI_CLIENT_API_URL = "https://api.lambdatest.com/visualui/1.0",
|
|
2088
|
+
SMARTUI_UPLOAD_URL = "https://api.lambdatest.com",
|
|
1945
2089
|
SMARTUI_GIT_INFO_FILEPATH,
|
|
1946
2090
|
SMARTUI_DO_NOT_USE_CAPTURED_COOKIES,
|
|
1947
2091
|
HTTP_PROXY,
|
|
@@ -1964,6 +2108,7 @@ var env_default = () => {
|
|
|
1964
2108
|
return {
|
|
1965
2109
|
PROJECT_TOKEN,
|
|
1966
2110
|
SMARTUI_CLIENT_API_URL,
|
|
2111
|
+
SMARTUI_UPLOAD_URL,
|
|
1967
2112
|
SMARTUI_GIT_INFO_FILEPATH,
|
|
1968
2113
|
HTTP_PROXY,
|
|
1969
2114
|
HTTPS_PROXY,
|
|
@@ -2076,7 +2221,7 @@ var authExec_default = (ctx) => {
|
|
|
2076
2221
|
};
|
|
2077
2222
|
|
|
2078
2223
|
// package.json
|
|
2079
|
-
var version = "4.1.
|
|
2224
|
+
var version = "4.1.29";
|
|
2080
2225
|
var package_default = {
|
|
2081
2226
|
name: "@lambdatest/smartui-cli",
|
|
2082
2227
|
version,
|
|
@@ -2133,6 +2278,18 @@ var package_default = {
|
|
|
2133
2278
|
}
|
|
2134
2279
|
};
|
|
2135
2280
|
var httpClient = class {
|
|
2281
|
+
handleHttpError(error, log2) {
|
|
2282
|
+
var _a;
|
|
2283
|
+
if (error && error.response) {
|
|
2284
|
+
log2.debug(`http response error: ${JSON.stringify({
|
|
2285
|
+
status: error.response.status,
|
|
2286
|
+
body: error.response.data
|
|
2287
|
+
})}`);
|
|
2288
|
+
throw new Error(((_a = error.response.data) == null ? void 0 : _a.message) || error.response.data || `HTTP ${error.response.status} error`);
|
|
2289
|
+
}
|
|
2290
|
+
log2.debug(`http request failed: ${error.message}`);
|
|
2291
|
+
throw new Error(error.message);
|
|
2292
|
+
}
|
|
2136
2293
|
constructor({ SMARTUI_CLIENT_API_URL, PROJECT_TOKEN, PROJECT_NAME, LT_USERNAME, LT_ACCESS_KEY, SMARTUI_API_PROXY, SMARTUI_API_SKIP_CERTIFICATES }) {
|
|
2137
2294
|
this.projectToken = PROJECT_TOKEN || "";
|
|
2138
2295
|
this.projectName = PROJECT_NAME || "";
|
|
@@ -2189,6 +2346,8 @@ var httpClient = class {
|
|
|
2189
2346
|
return this.axiosInstance(config);
|
|
2190
2347
|
}
|
|
2191
2348
|
return Promise.reject(error);
|
|
2349
|
+
} else {
|
|
2350
|
+
return Promise.reject(error);
|
|
2192
2351
|
}
|
|
2193
2352
|
})
|
|
2194
2353
|
);
|
|
@@ -2715,6 +2874,61 @@ var httpClient = class {
|
|
|
2715
2874
|
}
|
|
2716
2875
|
}, ctx.log);
|
|
2717
2876
|
}
|
|
2877
|
+
uploadPdf(ctx, form, buildName) {
|
|
2878
|
+
return __async(this, null, function* () {
|
|
2879
|
+
form.append("projectToken", this.projectToken);
|
|
2880
|
+
if (ctx.build.name !== void 0 && ctx.build.name !== "") {
|
|
2881
|
+
form.append("buildName", buildName);
|
|
2882
|
+
}
|
|
2883
|
+
try {
|
|
2884
|
+
const response = yield this.axiosInstance.request({
|
|
2885
|
+
url: ctx.env.SMARTUI_UPLOAD_URL + "/pdf/upload",
|
|
2886
|
+
method: "POST",
|
|
2887
|
+
headers: form.getHeaders(),
|
|
2888
|
+
data: form
|
|
2889
|
+
});
|
|
2890
|
+
ctx.log.debug(`http response: ${JSON.stringify({
|
|
2891
|
+
status: response.status,
|
|
2892
|
+
headers: response.headers,
|
|
2893
|
+
body: response.data
|
|
2894
|
+
})}`);
|
|
2895
|
+
return response.data;
|
|
2896
|
+
} catch (error) {
|
|
2897
|
+
this.handleHttpError(error, ctx.log);
|
|
2898
|
+
}
|
|
2899
|
+
});
|
|
2900
|
+
}
|
|
2901
|
+
fetchPdfResults(ctx) {
|
|
2902
|
+
return __async(this, null, function* () {
|
|
2903
|
+
const params = {};
|
|
2904
|
+
if (ctx.build.projectId) {
|
|
2905
|
+
params.project_id = ctx.build.projectId;
|
|
2906
|
+
} else {
|
|
2907
|
+
throw new Error("Project ID not found to fetch PDF results");
|
|
2908
|
+
}
|
|
2909
|
+
params.build_id = ctx.build.id;
|
|
2910
|
+
const auth = Buffer.from(`${this.username}:${this.accessKey}`).toString("base64");
|
|
2911
|
+
try {
|
|
2912
|
+
const response = yield axios__default.default.request({
|
|
2913
|
+
url: ctx.env.SMARTUI_UPLOAD_URL + "/smartui/2.0/build/screenshots",
|
|
2914
|
+
method: "GET",
|
|
2915
|
+
params,
|
|
2916
|
+
headers: {
|
|
2917
|
+
"accept": "application/json",
|
|
2918
|
+
"Authorization": `Basic ${auth}`
|
|
2919
|
+
}
|
|
2920
|
+
});
|
|
2921
|
+
ctx.log.debug(`http response: ${JSON.stringify({
|
|
2922
|
+
status: response.status,
|
|
2923
|
+
headers: response.headers,
|
|
2924
|
+
body: response.data
|
|
2925
|
+
})}`);
|
|
2926
|
+
return response.data;
|
|
2927
|
+
} catch (error) {
|
|
2928
|
+
this.handleHttpError(error, ctx.log);
|
|
2929
|
+
}
|
|
2930
|
+
});
|
|
2931
|
+
}
|
|
2718
2932
|
};
|
|
2719
2933
|
var ctx_default = (options) => {
|
|
2720
2934
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
@@ -2889,10 +3103,10 @@ var ctx_default = (options) => {
|
|
|
2889
3103
|
mergeByBuild: false
|
|
2890
3104
|
};
|
|
2891
3105
|
};
|
|
2892
|
-
function executeCommand(
|
|
3106
|
+
function executeCommand(command11) {
|
|
2893
3107
|
let dst = process.cwd();
|
|
2894
3108
|
try {
|
|
2895
|
-
return child_process.execSync(
|
|
3109
|
+
return child_process.execSync(command11, {
|
|
2896
3110
|
cwd: dst,
|
|
2897
3111
|
stdio: ["ignore"],
|
|
2898
3112
|
encoding: "utf-8"
|
|
@@ -2901,11 +3115,12 @@ function executeCommand(command10) {
|
|
|
2901
3115
|
throw new Error(error.message);
|
|
2902
3116
|
}
|
|
2903
3117
|
}
|
|
2904
|
-
function isGitRepo() {
|
|
3118
|
+
function isGitRepo(ctx) {
|
|
2905
3119
|
try {
|
|
2906
3120
|
executeCommand("git status");
|
|
2907
3121
|
return true;
|
|
2908
3122
|
} catch (error) {
|
|
3123
|
+
setNonGitInfo(ctx);
|
|
2909
3124
|
return false;
|
|
2910
3125
|
}
|
|
2911
3126
|
}
|
|
@@ -2937,8 +3152,8 @@ var git_default = (ctx) => {
|
|
|
2937
3152
|
} else {
|
|
2938
3153
|
const splitCharacter = "<##>";
|
|
2939
3154
|
const prettyFormat = ["%h", "%H", "%s", "%f", "%b", "%at", "%ct", "%an", "%ae", "%cn", "%ce", "%N", ""];
|
|
2940
|
-
const
|
|
2941
|
-
let res = executeCommand(
|
|
3155
|
+
const command11 = 'git log -1 --pretty=format:"' + prettyFormat.join(splitCharacter) + '" && git rev-parse --abbrev-ref HEAD && git tag --contains HEAD';
|
|
3156
|
+
let res = executeCommand(command11).split(splitCharacter);
|
|
2942
3157
|
var branchAndTags = res[res.length - 1].split("\n").filter((n) => n);
|
|
2943
3158
|
var branch = ctx.env.CURRENT_BRANCH || branchAndTags[0];
|
|
2944
3159
|
branchAndTags.slice(1);
|
|
@@ -2956,11 +3171,30 @@ var git_default = (ctx) => {
|
|
|
2956
3171
|
};
|
|
2957
3172
|
}
|
|
2958
3173
|
};
|
|
3174
|
+
function setNonGitInfo(ctx) {
|
|
3175
|
+
let branch = ctx.env.CURRENT_BRANCH || "unknown-branch";
|
|
3176
|
+
if (ctx.options.markBaseline) {
|
|
3177
|
+
ctx.env.BASELINE_BRANCH = branch;
|
|
3178
|
+
ctx.env.SMART_GIT = false;
|
|
3179
|
+
}
|
|
3180
|
+
let githubURL;
|
|
3181
|
+
if (ctx.options.githubURL && ctx.options.githubURL.startsWith("https://")) {
|
|
3182
|
+
githubURL = ctx.options.githubURL;
|
|
3183
|
+
}
|
|
3184
|
+
ctx.git = {
|
|
3185
|
+
branch,
|
|
3186
|
+
commitId: "-",
|
|
3187
|
+
commitAuthor: "-",
|
|
3188
|
+
commitMessage: "-",
|
|
3189
|
+
githubURL: githubURL ? githubURL : "",
|
|
3190
|
+
baselineBranch: ctx.options.baselineBranch || ctx.env.BASELINE_BRANCH || ""
|
|
3191
|
+
};
|
|
3192
|
+
}
|
|
2959
3193
|
var getGitInfo_default = (ctx) => {
|
|
2960
3194
|
return {
|
|
2961
3195
|
title: `Fetching git repo details`,
|
|
2962
3196
|
skip: (ctx2) => {
|
|
2963
|
-
return !isGitRepo() && !ctx2.env.SMARTUI_GIT_INFO_FILEPATH ? "[SKIPPED] Fetching git repo details; not a git repo" : "";
|
|
3197
|
+
return !isGitRepo(ctx2) && !ctx2.env.SMARTUI_GIT_INFO_FILEPATH ? "[SKIPPED] Fetching git repo details; not a git repo" : "";
|
|
2964
3198
|
},
|
|
2965
3199
|
task: (ctx2, task) => __async(void 0, null, function* () {
|
|
2966
3200
|
if (ctx2.env.CURRENT_BRANCH && ctx2.env.CURRENT_BRANCH.trim() === "") {
|
|
@@ -3168,7 +3402,7 @@ var finalizeBuild_default = (ctx) => {
|
|
|
3168
3402
|
task.output = chalk__default.default.gray(error.message);
|
|
3169
3403
|
throw new Error("Finalize build failed");
|
|
3170
3404
|
}
|
|
3171
|
-
let
|
|
3405
|
+
let buildUrls2 = `build url: ${ctx2.build.url}
|
|
3172
3406
|
`;
|
|
3173
3407
|
if (pingIntervalId !== null) {
|
|
3174
3408
|
clearInterval(pingIntervalId);
|
|
@@ -3198,14 +3432,14 @@ var finalizeBuild_default = (ctx) => {
|
|
|
3198
3432
|
yield ctx2.client.finalizeBuildForCapsWithToken(buildId, totalSnapshots, projectToken, ctx2.log);
|
|
3199
3433
|
}
|
|
3200
3434
|
if (testId && buildId) {
|
|
3201
|
-
|
|
3435
|
+
buildUrls2 += `TestId ${testId}: ${sessionBuildUrl}
|
|
3202
3436
|
`;
|
|
3203
3437
|
}
|
|
3204
3438
|
} catch (error) {
|
|
3205
3439
|
ctx2.log.debug(`Error finalizing build for session ${sessionId}: ${error.message}`);
|
|
3206
3440
|
}
|
|
3207
3441
|
}
|
|
3208
|
-
task.output = chalk__default.default.gray(
|
|
3442
|
+
task.output = chalk__default.default.gray(buildUrls2);
|
|
3209
3443
|
task.title = "Finalized build";
|
|
3210
3444
|
try {
|
|
3211
3445
|
yield (_a = ctx2.browser) == null ? void 0 : _a.close();
|
|
@@ -4124,7 +4358,7 @@ var Queue = class {
|
|
|
4124
4358
|
try {
|
|
4125
4359
|
this.processingSnapshot = snapshot == null ? void 0 : snapshot.name;
|
|
4126
4360
|
let drop = false;
|
|
4127
|
-
if (this.ctx.isStartExec
|
|
4361
|
+
if (this.ctx.isStartExec) {
|
|
4128
4362
|
this.ctx.log.info(`Processing Snapshot: ${snapshot == null ? void 0 : snapshot.name}`);
|
|
4129
4363
|
}
|
|
4130
4364
|
if (!this.ctx.config.delayedUpload && snapshot && snapshot.name && this.snapshotNames.includes(snapshot.name) && !this.ctx.config.allowDuplicateSnapshotNames) {
|
|
@@ -4319,15 +4553,15 @@ var startTunnel_default = (ctx) => {
|
|
|
4319
4553
|
|
|
4320
4554
|
// src/commander/exec.ts
|
|
4321
4555
|
var command = new commander.Command();
|
|
4322
|
-
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").option("--scheduled <string>", "Specify the schedule ID").option("--userName <string>", "Specify the LT username").option("--accessKey <string>", "Specify the LT accesskey").action(function(execCommand, _,
|
|
4556
|
+
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").option("--scheduled <string>", "Specify the schedule ID").option("--userName <string>", "Specify the LT username").option("--accessKey <string>", "Specify the LT accesskey").action(function(execCommand, _, command11) {
|
|
4323
4557
|
return __async(this, null, function* () {
|
|
4324
4558
|
var _a;
|
|
4325
|
-
const options =
|
|
4559
|
+
const options = command11.optsWithGlobals();
|
|
4326
4560
|
if (options.buildName === "") {
|
|
4327
4561
|
console.log(`Error: The '--buildName' option cannot be an empty string.`);
|
|
4328
4562
|
process.exit(1);
|
|
4329
4563
|
}
|
|
4330
|
-
let ctx = ctx_default(
|
|
4564
|
+
let ctx = ctx_default(command11.optsWithGlobals());
|
|
4331
4565
|
if (!which__default.default.sync(execCommand[0], { nothrow: true })) {
|
|
4332
4566
|
ctx.log.error(`Error: Command not found "${execCommand[0]}"`);
|
|
4333
4567
|
return;
|
|
@@ -4943,15 +5177,15 @@ var captureScreenshots_default = (ctx) => {
|
|
|
4943
5177
|
|
|
4944
5178
|
// src/commander/capture.ts
|
|
4945
5179
|
var command2 = new commander.Command();
|
|
4946
|
-
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").option("--scheduled <string>", "Specify the schedule ID").option("--userName <string>", "Specify the LT username").option("--accessKey <string>", "Specify the LT accesskey").action(function(file, _,
|
|
5180
|
+
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").option("--scheduled <string>", "Specify the schedule ID").option("--userName <string>", "Specify the LT username").option("--accessKey <string>", "Specify the LT accesskey").action(function(file, _, command11) {
|
|
4947
5181
|
return __async(this, null, function* () {
|
|
4948
5182
|
var _a, _b;
|
|
4949
|
-
const options =
|
|
5183
|
+
const options = command11.optsWithGlobals();
|
|
4950
5184
|
if (options.buildName === "") {
|
|
4951
5185
|
console.log(`Error: The '--buildName' option cannot be an empty string.`);
|
|
4952
5186
|
process.exit(1);
|
|
4953
5187
|
}
|
|
4954
|
-
let ctx = ctx_default(
|
|
5188
|
+
let ctx = ctx_default(command11.optsWithGlobals());
|
|
4955
5189
|
ctx.isSnapshotCaptured = true;
|
|
4956
5190
|
if (!fs5__default.default.existsSync(file)) {
|
|
4957
5191
|
ctx.log.error(`Web Static Config file ${file} not found.`);
|
|
@@ -5039,14 +5273,14 @@ command3.name("upload").description("Upload screenshots from given directory").a
|
|
|
5039
5273
|
return val.split(",").map((ext) => ext.trim().toLowerCase());
|
|
5040
5274
|
}).option("-E, --removeExtensions", "Strips file extensions from snapshot names").option("-i, --ignoreDir <patterns>", "Comma-separated list of directories to ignore", (val) => {
|
|
5041
5275
|
return val.split(",").map((pattern) => pattern.trim());
|
|
5042
|
-
}).option("--fetch-results [filename]", "Fetch results and optionally specify an output file, e.g., <filename>.json").option("--buildName <string>", "Specify the build name").option("--userName <string>", "Specify the LT username").option("--accessKey <string>", "Specify the LT accesskey").action(function(directory, _,
|
|
5276
|
+
}).option("--fetch-results [filename]", "Fetch results and optionally specify an output file, e.g., <filename>.json").option("--buildName <string>", "Specify the build name").option("--userName <string>", "Specify the LT username").option("--accessKey <string>", "Specify the LT accesskey").action(function(directory, _, command11) {
|
|
5043
5277
|
return __async(this, null, function* () {
|
|
5044
|
-
const options =
|
|
5278
|
+
const options = command11.optsWithGlobals();
|
|
5045
5279
|
if (options.buildName === "") {
|
|
5046
5280
|
console.log(`Error: The '--buildName' option cannot be an empty string.`);
|
|
5047
5281
|
process.exit(1);
|
|
5048
5282
|
}
|
|
5049
|
-
let ctx = ctx_default(
|
|
5283
|
+
let ctx = ctx_default(command11.optsWithGlobals());
|
|
5050
5284
|
ctx.isSnapshotCaptured = true;
|
|
5051
5285
|
if (!fs5__default.default.existsSync(directory)) {
|
|
5052
5286
|
console.log(`Error: The provided directory ${directory} not found.`);
|
|
@@ -5324,10 +5558,10 @@ var uploadAppFigma_default2 = (ctx) => {
|
|
|
5324
5558
|
var uploadFigma = new commander.Command();
|
|
5325
5559
|
var uploadWebFigmaCommand = new commander.Command();
|
|
5326
5560
|
var uploadAppFigmaCommand = new commander.Command();
|
|
5327
|
-
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, _,
|
|
5561
|
+
uploadFigma.name("upload-figma").description("Capture screenshots of static sites").argument("<file>", "figma design config file").option("--markBaseline", "Mark the uploaded images as baseline").option("--buildName <buildName>", "Name of the build").action(function(file, _, command11) {
|
|
5328
5562
|
return __async(this, null, function* () {
|
|
5329
5563
|
var _a, _b;
|
|
5330
|
-
let ctx = ctx_default(
|
|
5564
|
+
let ctx = ctx_default(command11.optsWithGlobals());
|
|
5331
5565
|
ctx.isSnapshotCaptured = true;
|
|
5332
5566
|
if (!fs5__default.default.existsSync(file)) {
|
|
5333
5567
|
console.log(`Error: Figma Config file ${file} not found.`);
|
|
@@ -5366,10 +5600,10 @@ uploadFigma.name("upload-figma").description("Capture screenshots of static site
|
|
|
5366
5600
|
}
|
|
5367
5601
|
});
|
|
5368
5602
|
});
|
|
5369
|
-
uploadWebFigmaCommand.name("upload-figma-web").description("Capture figma screenshots into CLI build").argument("<file>", "figma config config file").option("--markBaseline", "Mark the uploaded images as baseline").option("--buildName <buildName>", "Name of the build").option("--fetch-results [filename]", "Fetch results and optionally specify an output file, e.g., <filename>.json").action(function(file, _,
|
|
5603
|
+
uploadWebFigmaCommand.name("upload-figma-web").description("Capture figma screenshots into CLI build").argument("<file>", "figma config config file").option("--markBaseline", "Mark the uploaded images as baseline").option("--buildName <buildName>", "Name of the build").option("--fetch-results [filename]", "Fetch results and optionally specify an output file, e.g., <filename>.json").action(function(file, _, command11) {
|
|
5370
5604
|
return __async(this, null, function* () {
|
|
5371
5605
|
var _a;
|
|
5372
|
-
let ctx = ctx_default(
|
|
5606
|
+
let ctx = ctx_default(command11.optsWithGlobals());
|
|
5373
5607
|
if (!fs5__default.default.existsSync(file)) {
|
|
5374
5608
|
console.log(`Error: figma-web config file ${file} not found.`);
|
|
5375
5609
|
return;
|
|
@@ -5419,10 +5653,10 @@ uploadWebFigmaCommand.name("upload-figma-web").description("Capture figma screen
|
|
|
5419
5653
|
}
|
|
5420
5654
|
});
|
|
5421
5655
|
});
|
|
5422
|
-
uploadAppFigmaCommand.name("upload-figma-app").description("Capture figma screenshots into App Build").argument("<file>", "figma config config file").option("--markBaseline", "Mark the uploaded images as baseline").option("--buildName <buildName>", "Name of the build").option("--fetch-results [filename]", "Fetch results and optionally specify an output file, e.g., <filename>.json").action(function(file, _,
|
|
5656
|
+
uploadAppFigmaCommand.name("upload-figma-app").description("Capture figma screenshots into App Build").argument("<file>", "figma config config file").option("--markBaseline", "Mark the uploaded images as baseline").option("--buildName <buildName>", "Name of the build").option("--fetch-results [filename]", "Fetch results and optionally specify an output file, e.g., <filename>.json").action(function(file, _, command11) {
|
|
5423
5657
|
return __async(this, null, function* () {
|
|
5424
5658
|
var _a;
|
|
5425
|
-
let ctx = ctx_default(
|
|
5659
|
+
let ctx = ctx_default(command11.optsWithGlobals());
|
|
5426
5660
|
if (!fs5__default.default.existsSync(file)) {
|
|
5427
5661
|
console.log(`Error: figma-app config file ${file} not found.`);
|
|
5428
5662
|
return;
|
|
@@ -5486,10 +5720,10 @@ command4.name("exec:start").description("Start SmartUI server").option("-P, --po
|
|
|
5486
5720
|
ctx.isStartExec = true;
|
|
5487
5721
|
let tasks = new listr2.Listr(
|
|
5488
5722
|
[
|
|
5489
|
-
|
|
5723
|
+
authExec_default(),
|
|
5490
5724
|
startServer_default(),
|
|
5491
5725
|
getGitInfo_default(),
|
|
5492
|
-
|
|
5726
|
+
createBuildExec_default()
|
|
5493
5727
|
],
|
|
5494
5728
|
{
|
|
5495
5729
|
rendererOptions: {
|
|
@@ -5504,8 +5738,10 @@ command4.name("exec:start").description("Start SmartUI server").option("-P, --po
|
|
|
5504
5738
|
);
|
|
5505
5739
|
try {
|
|
5506
5740
|
yield tasks.run(ctx);
|
|
5507
|
-
|
|
5508
|
-
|
|
5741
|
+
if (ctx.build && ctx.build.id) {
|
|
5742
|
+
startPingPolling(ctx);
|
|
5743
|
+
}
|
|
5744
|
+
if (ctx.options.fetchResults && ctx.build && ctx.build.id) {
|
|
5509
5745
|
startPolling(ctx, "", false, "");
|
|
5510
5746
|
}
|
|
5511
5747
|
} catch (error) {
|
|
@@ -5866,10 +6102,104 @@ command9.name("exec:pingTest").description("Ping the SmartUI server to check if
|
|
|
5866
6102
|
});
|
|
5867
6103
|
});
|
|
5868
6104
|
var pingTest_default = command9;
|
|
6105
|
+
var uploadPdfs_default = (ctx) => {
|
|
6106
|
+
return {
|
|
6107
|
+
title: "Uploading PDFs",
|
|
6108
|
+
task: (ctx2, task) => __async(void 0, null, function* () {
|
|
6109
|
+
try {
|
|
6110
|
+
ctx2.task = task;
|
|
6111
|
+
updateLogContext({ task: "upload-pdf" });
|
|
6112
|
+
yield uploadPdfs(ctx2, ctx2.uploadFilePath);
|
|
6113
|
+
task.title = "PDFs uploaded successfully";
|
|
6114
|
+
} catch (error) {
|
|
6115
|
+
ctx2.log.debug(error);
|
|
6116
|
+
task.output = chalk__default.default.red(`${error.message}`);
|
|
6117
|
+
throw new Error("PDF upload failed");
|
|
6118
|
+
}
|
|
6119
|
+
}),
|
|
6120
|
+
rendererOptions: { persistentOutput: true },
|
|
6121
|
+
exitOnError: false
|
|
6122
|
+
};
|
|
6123
|
+
};
|
|
6124
|
+
function uploadPdfs(ctx, pdfPath) {
|
|
6125
|
+
return __async(this, null, function* () {
|
|
6126
|
+
const formData = new FormData__default.default();
|
|
6127
|
+
if (pdfPath.endsWith(".pdf")) {
|
|
6128
|
+
formData.append("pathToFiles", fs5__default.default.createReadStream(pdfPath));
|
|
6129
|
+
} else {
|
|
6130
|
+
const files = fs5__default.default.readdirSync(pdfPath);
|
|
6131
|
+
const pdfFiles = files.filter((file) => file.endsWith(".pdf"));
|
|
6132
|
+
pdfFiles.forEach((pdf) => {
|
|
6133
|
+
const filePath = path2__default.default.join(pdfPath, pdf);
|
|
6134
|
+
formData.append("pathToFiles", fs5__default.default.createReadStream(filePath));
|
|
6135
|
+
});
|
|
6136
|
+
}
|
|
6137
|
+
const buildName = ctx.options.buildName;
|
|
6138
|
+
if (buildName) {
|
|
6139
|
+
ctx.build.name = buildName;
|
|
6140
|
+
}
|
|
6141
|
+
try {
|
|
6142
|
+
const response = yield ctx.client.uploadPdf(ctx, formData, buildName);
|
|
6143
|
+
if (response && response.buildId) {
|
|
6144
|
+
ctx.build.id = response.buildId;
|
|
6145
|
+
ctx.log.debug(`PDF upload successful. Build ID: ${ctx.build.id}`);
|
|
6146
|
+
}
|
|
6147
|
+
if (response && response.projectId) {
|
|
6148
|
+
ctx.build.projectId = response.projectId;
|
|
6149
|
+
}
|
|
6150
|
+
} catch (error) {
|
|
6151
|
+
throw new Error(error.message);
|
|
6152
|
+
}
|
|
6153
|
+
});
|
|
6154
|
+
}
|
|
6155
|
+
|
|
6156
|
+
// src/commander/uploadPdf.ts
|
|
6157
|
+
var command10 = new commander.Command();
|
|
6158
|
+
command10.name("upload-pdf").description("Upload PDFs for visual comparison").argument("<directory>", "Path of the directory containing PDFs").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, _, command11) {
|
|
6159
|
+
return __async(this, null, function* () {
|
|
6160
|
+
const options = command11.optsWithGlobals();
|
|
6161
|
+
if (options.buildName === "") {
|
|
6162
|
+
console.log(`Error: The '--buildName' option cannot be an empty string.`);
|
|
6163
|
+
process.exit(1);
|
|
6164
|
+
}
|
|
6165
|
+
let ctx = ctx_default(command11.optsWithGlobals());
|
|
6166
|
+
if (!fs5__default.default.existsSync(directory)) {
|
|
6167
|
+
console.log(`Error: The provided directory ${directory} not found.`);
|
|
6168
|
+
process.exit(1);
|
|
6169
|
+
}
|
|
6170
|
+
ctx.uploadFilePath = directory;
|
|
6171
|
+
let tasks = new listr2.Listr(
|
|
6172
|
+
[
|
|
6173
|
+
auth_default(),
|
|
6174
|
+
uploadPdfs_default()
|
|
6175
|
+
],
|
|
6176
|
+
{
|
|
6177
|
+
rendererOptions: {
|
|
6178
|
+
icon: {
|
|
6179
|
+
[listr2.ListrDefaultRendererLogLevels.OUTPUT]: `\u2192`
|
|
6180
|
+
},
|
|
6181
|
+
color: {
|
|
6182
|
+
[listr2.ListrDefaultRendererLogLevels.OUTPUT]: listr2.color.gray
|
|
6183
|
+
}
|
|
6184
|
+
}
|
|
6185
|
+
}
|
|
6186
|
+
);
|
|
6187
|
+
try {
|
|
6188
|
+
yield tasks.run(ctx);
|
|
6189
|
+
if (ctx.options.fetchResults) {
|
|
6190
|
+
startPdfPolling(ctx);
|
|
6191
|
+
}
|
|
6192
|
+
} catch (error) {
|
|
6193
|
+
console.log("\nRefer docs: https://www.lambdatest.com/support/docs/smart-visual-regression-testing/");
|
|
6194
|
+
process.exit(1);
|
|
6195
|
+
}
|
|
6196
|
+
});
|
|
6197
|
+
});
|
|
6198
|
+
var uploadPdf_default = command10;
|
|
5869
6199
|
|
|
5870
6200
|
// src/commander/commander.ts
|
|
5871
6201
|
var program2 = new commander.Command();
|
|
5872
|
-
program2.name("smartui").description("CLI to help you run your SmartUI tests on LambdaTest platform").version(`v${version}`).option("-c --config <filepath>", "Config file path").option("--markBaseline", "Mark this build baseline").option("--baselineBranch <string>", "Mark this build baseline").option("--baselineBuild <string>", "Mark this build baseline").option("--githubURL <string>", "GitHub URL including commitId").addCommand(exec_default2).addCommand(capture_default).addCommand(configWeb).addCommand(configStatic).addCommand(upload_default).addCommand(server_default2).addCommand(stopServer_default).addCommand(merge_default).addCommand(ping_default).addCommand(configFigma).addCommand(uploadFigma).addCommand(configWebFigma).addCommand(configAppFigma).addCommand(uploadWebFigmaCommand).addCommand(uploadAppFigmaCommand).addCommand(pingTest_default);
|
|
6202
|
+
program2.name("smartui").description("CLI to help you run your SmartUI tests on LambdaTest platform").version(`v${version}`).option("-c --config <filepath>", "Config file path").option("--markBaseline", "Mark this build baseline").option("--baselineBranch <string>", "Mark this build baseline").option("--baselineBuild <string>", "Mark this build baseline").option("--githubURL <string>", "GitHub URL including commitId").addCommand(exec_default2).addCommand(capture_default).addCommand(configWeb).addCommand(configStatic).addCommand(upload_default).addCommand(server_default2).addCommand(stopServer_default).addCommand(merge_default).addCommand(ping_default).addCommand(configFigma).addCommand(uploadFigma).addCommand(configWebFigma).addCommand(configAppFigma).addCommand(uploadWebFigmaCommand).addCommand(uploadAppFigmaCommand).addCommand(pingTest_default).addCommand(uploadPdf_default);
|
|
5873
6203
|
var commander_default = program2;
|
|
5874
6204
|
(function() {
|
|
5875
6205
|
return __async(this, null, function* () {
|