From 6b3a73f3614d6ba179c4b9dd231fe8fedf444d38 Mon Sep 17 00:00:00 2001 From: Shrinish Vhanbatte Date: Sat, 18 Apr 2026 00:37:39 +0530 Subject: [PATCH 1/2] fix PDF fetch-results --- package.json | 2 +- src/lib/utils.ts | 66 +++++++++++++++++++++++++++++++----------------- 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/package.json b/package.json index deaee65..a63be3e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lambdatest/smartui-cli", - "version": "4.1.63", + "version": "4.1.64-up-1", "description": "A command line interface (CLI) to run SmartUI tests on LambdaTest", "files": [ "dist/**/*" diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 75ca63d..51962d7 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -628,60 +628,74 @@ export function startPdfPolling(ctx: Context) { return } - if (!ctx.env.LT_USERNAME || !ctx.env.LT_ACCESS_KEY) { - console.log(chalk.red('Error: LT_USERNAME and LT_ACCESS_KEY environment variables are required for fetching results')); - return; - } - let attempts = 0; - const maxAttempts = 60; // 5 minutes (10 seconds * 30) + const maxAttempts = 60; // 10 minutes (10 seconds * 60) console.log(chalk.yellow('Waiting for results...')); + const projectToken = ctx.env.PROJECT_TOKEN || ''; + const interval = setInterval(async () => { attempts++; try { - const response = await ctx.client.fetchPdfResults(ctx); + const response = await ctx.client.getScreenshotData(ctx.build.id, false, ctx.log, projectToken, ''); + + if (!response || !response.build) { + if (attempts >= maxAttempts) { + clearInterval(interval); + console.log(chalk.red('\nTimeout: Could not fetch PDF results after 10 minutes')); + } + return; + } - if (response.screenshots && response.build?.build_status !== constants.BUILD_RUNNING) { + if (response.screenshots && (response.build.build_status_ind === constants.BUILD_COMPLETE || response.build.build_status_ind === constants.BUILD_ERROR)) { clearInterval(interval); - const pdfGroups = groupScreenshotsByPdf(response.screenshots); + // Flatten screenshots object to array for PDF grouping + const screenshotsArray: any[] = []; + for (const [, variants] of Object.entries(response.screenshots || {})) { + for (const variant of (variants as any[])) { + screenshotsArray.push(variant); + } + } + + const pdfGroups = groupScreenshotsByPdf(screenshotsArray); const pdfsWithMismatches = countPdfsWithMismatches(pdfGroups); - const pagesWithMismatches = countPagesWithMismatches(response.screenshots); + const pagesWithMismatches = countPagesWithMismatches(screenshotsArray); console.log(chalk.green('\nāœ“ PDF Test Results:')); - console.log(chalk.green(`Build Name: ${response.build.name}`)); + console.log(chalk.green(`Build Name: ${response.build.build_name}`)); console.log(chalk.green(`Project Name: ${response.project.name}`)); console.log(chalk.green(`Total PDFs: ${Object.keys(pdfGroups).length}`)); - console.log(chalk.green(`Total Pages: ${response.screenshots.length}`)); + console.log(chalk.green(`Total Pages: ${screenshotsArray.length}`)); if (pdfsWithMismatches > 0 || pagesWithMismatches > 0) { - console.log(chalk.yellow(`${pdfsWithMismatches} PDFs and ${pagesWithMismatches} Pages in build ${response.build.name} have changes present.`)); + console.log(chalk.yellow(`${pdfsWithMismatches} PDFs and ${pagesWithMismatches} Pages in build ${response.build.build_name} have changes present.`)); } else { console.log(chalk.green('All PDFs match the baseline.')); } Object.entries(pdfGroups).forEach(([pdfName, pages]) => { - const hasMismatch = pages.some(page => page.mismatch_percentage > 0); + const hasMismatch = pages.some(page => isPageMismatch(page)); const statusColor = hasMismatch ? chalk.yellow : chalk.green; console.log(statusColor(`\nšŸ“„ ${pdfName} (${pages.length} pages)`)); pages.forEach(page => { - const pageStatusColor = page.mismatch_percentage > 0 ? chalk.yellow : chalk.green; - console.log(pageStatusColor(` - Page ${getPageNumber(page.screenshot_name)}: ${page.status} (Mismatch: ${page.mismatch_percentage}%)`)); + const pageStatusColor = isPageMismatch(page) ? chalk.yellow : chalk.green; + const mismatchInfo = page.mismatch_percentage !== undefined ? ` (Mismatch: ${page.mismatch_percentage}%)` : ''; + console.log(pageStatusColor(` - Page ${getPageNumber(page.screenshot_name)}: ${page.status}${mismatchInfo}`)); }); }); const formattedResults = { status: 'success', data: { - buildId: response.build.id, - buildName: response.build.name, + buildId: response.build.build_id, + buildName: response.build.build_name, projectName: response.project.name, - buildStatus: response.build.build_satus, + buildStatus: response.build.build_status, pdfs: formatPdfsForOutput(pdfGroups) } }; @@ -699,7 +713,7 @@ export function startPdfPolling(ctx: Context) { if (attempts >= maxAttempts) { clearInterval(interval); - console.log(chalk.red('\nTimeout: Could not fetch PDF results after 5 minutes')); + console.log(chalk.red('\nTimeout: Could not fetch PDF results after 10 minutes')); return; } @@ -708,7 +722,7 @@ export function startPdfPolling(ctx: Context) { if (attempts >= maxAttempts) { clearInterval(interval); - console.log(chalk.red('\nTimeout: Could not fetch PDF results after 5 minutes')); + console.log(chalk.red('\nTimeout: Could not fetch PDF results after 10 minutes')); if (error.response && error.response.data) { console.log(chalk.red(`Error details: ${JSON.stringify(error.response.data)}`)); } else { @@ -738,11 +752,17 @@ function groupScreenshotsByPdf(screenshots: any[]): Record { return pdfGroups; } +const NON_MISMATCH_STATUSES = ['Approved', 'moved', 'new-screenshot']; + +function isPageMismatch(page: any): boolean { + return !NON_MISMATCH_STATUSES.includes(page.status); +} + function countPdfsWithMismatches(pdfGroups: Record): number { let count = 0; Object.values(pdfGroups).forEach(pages => { - if (pages.some(page => page.mismatch_percentage > 0)) { + if (pages.some(page => isPageMismatch(page))) { count++; } }); @@ -751,7 +771,7 @@ function countPdfsWithMismatches(pdfGroups: Record): number { } function countPagesWithMismatches(screenshots: any[]): number { - return screenshots.filter(screenshot => screenshot.mismatch_percentage > 0).length; + return screenshots.filter(screenshot => isPageMismatch(screenshot)).length; } function formatPdfsForOutput(pdfGroups: Record): any[] { From 4d7d970305ad4736ee9f0d95604669759b44bbdb Mon Sep 17 00:00:00 2001 From: Shrinish Vhanbatte Date: Tue, 21 Apr 2026 13:52:33 +0530 Subject: [PATCH 2/2] log --- package.json | 2 +- src/lib/httpClient.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index a63be3e..fa6b3ca 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lambdatest/smartui-cli", - "version": "4.1.64-up-1", + "version": "4.1.69", "description": "A command line interface (CLI) to run SmartUI tests on LambdaTest", "files": [ "dist/**/*" diff --git a/src/lib/httpClient.ts b/src/lib/httpClient.ts index a90e378..abab5bc 100644 --- a/src/lib/httpClient.ts +++ b/src/lib/httpClient.ts @@ -852,9 +852,12 @@ export default class httpClient { const auth = Buffer.from(`${this.username}:${this.accessKey}`).toString('base64'); + const url = ctx.env.SMARTUI_UPLOAD_URL + '/smartui/2.0/build/screenshots'; + ctx.log.debug(`Fetching PDF results from URL: ${url} with params: ${JSON.stringify(params)}`); + try { const response = await axios.request({ - url: ctx.env.SMARTUI_UPLOAD_URL + '/smartui/2.0/build/screenshots', + url: url, method: 'GET', params: params, headers: {