diff --git a/package.json b/package.json index deaee65..6f7845f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lambdatest/smartui-cli", - "version": "4.1.63", + "version": "4.1.64-shri", "description": "A command line interface (CLI) to run SmartUI tests on LambdaTest", "files": [ "dist/**/*" @@ -20,6 +20,9 @@ "smartui", "cli" ], + "engines": { + "node": ">=20" + }, "author": "LambdaTest ", "license": "MIT", "dependencies": { @@ -43,6 +46,7 @@ "json-stringify-safe": "^5.0.1", "listr2": "^7.0.1", "node-cache": "^5.1.2", + "pnpm": "^10.33.0", "postcss": "^8.5.6", "sharp": "^0.33.4", "uuid": "^11.0.3", @@ -54,7 +58,7 @@ }, "devDependencies": { "find-free-port": "^2.0.0", - "typescript": "^5.3.2", - "tsup": "^8.5.1" + "tsup": "^8.5.1", + "typescript": "^5.3.2" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7c7a858..9854c24 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -68,6 +68,9 @@ importers: node-cache: specifier: ^5.1.2 version: 5.1.2 + pnpm: + specifier: ^10.33.0 + version: 10.33.0 postcss: specifier: ^8.5.6 version: 8.5.9 @@ -313,72 +316,84 @@ packages: engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-arm@1.0.2': resolution: {integrity: sha512-iLWCvrKgeFoglQxdEwzu1eQV04o8YeYGFXtfWU26Zr2wWT3q3MTzC+QTCO3ZQfWd3doKHT4Pm2kRmLbupT+sZw==} engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-s390x@1.0.2': resolution: {integrity: sha512-cmhQ1J4qVhfmS6szYW7RT+gLJq9dH2i4maq+qyXayUSn9/3iY2ZeWpbAgSpSVbV2E1JUL2Gg7pwnYQ1h8rQIog==} engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-x64@1.0.2': resolution: {integrity: sha512-E441q4Qdb+7yuyiADVi5J+44x8ctlrqn8XgkDTwr4qPJzWkaHwD489iZ4nGDgcuya4iMN3ULV6NwbhRZJ9Z7SQ==} engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linuxmusl-arm64@1.0.2': resolution: {integrity: sha512-3CAkndNpYUrlDqkCM5qhksfE+qSIREVpyoeHIU6jd48SJZViAmznoQQLAv4hVXF7xyUB9zf+G++e2v1ABjCbEQ==} engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-libvips-linuxmusl-x64@1.0.2': resolution: {integrity: sha512-VI94Q6khIHqHWNOh6LLdm9s2Ry4zdjWJwH56WoiJU7NTeDwyApdZZ8c+SADC8OH98KWNQXnE01UdJ9CSfZvwZw==} engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-linux-arm64@0.33.4': resolution: {integrity: sha512-2800clwVg1ZQtxwSoTlHvtm9ObgAax7V6MTAB/hDT945Tfyy3hVkmiHpeLPCKYqYR1Gcmv1uDZ3a4OFwkdBL7Q==} engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-linux-arm@0.33.4': resolution: {integrity: sha512-RUgBD1c0+gCYZGCCe6mMdTiOFS0Zc/XrN0fYd6hISIKcDUbAW5NtSQW9g/powkrXYm6Vzwd6y+fqmExDuCdHNQ==} engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-linux-s390x@0.33.4': resolution: {integrity: sha512-h3RAL3siQoyzSoH36tUeS0PDmb5wINKGYzcLB5C6DIiAn2F3udeFAum+gj8IbA/82+8RGCTn7XW8WTFnqag4tQ==} engines: {glibc: '>=2.31', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-linux-x64@0.33.4': resolution: {integrity: sha512-GoR++s0XW9DGVi8SUGQ/U4AeIzLdNjHka6jidVwapQ/JebGVQIpi52OdyxCNVRE++n1FCLzjDovJNozif7w/Aw==} engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-linuxmusl-arm64@0.33.4': resolution: {integrity: sha512-nhr1yC3BlVrKDTl6cO12gTpXMl4ITBUZieehFvMntlCXFzH2bvKG76tBL2Y/OqhupZt81pR7R+Q5YhJxW0rGgQ==} engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-linuxmusl-x64@0.33.4': resolution: {integrity: sha512-uCPTku0zwqDmZEOi4ILyGdmW76tH7dm8kKlOIV1XC5cLyJ71ENAAqarOHQh0RLfpIpbV5KOpXzdU6XkJtS0daw==} engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-wasm32@0.33.4': resolution: {integrity: sha512-Bmmauh4sXUsUqkleQahpdNXKvo+wa1V9KhT2pDA4VJGKwnKMJXiSTGphn0gnJrlooda0QxCtXc6RX1XAU6hMnQ==} @@ -475,66 +490,79 @@ packages: resolution: {integrity: sha512-L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g==} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.60.1': resolution: {integrity: sha512-n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg==} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.60.1': resolution: {integrity: sha512-Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.60.1': resolution: {integrity: sha512-+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-loong64-gnu@4.60.1': resolution: {integrity: sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ==} cpu: [loong64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-loong64-musl@4.60.1': resolution: {integrity: sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw==} cpu: [loong64] os: [linux] + libc: [musl] '@rollup/rollup-linux-ppc64-gnu@4.60.1': resolution: {integrity: sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw==} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-ppc64-musl@4.60.1': resolution: {integrity: sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg==} cpu: [ppc64] os: [linux] + libc: [musl] '@rollup/rollup-linux-riscv64-gnu@4.60.1': resolution: {integrity: sha512-QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.60.1': resolution: {integrity: sha512-RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg==} cpu: [riscv64] os: [linux] + libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.60.1': resolution: {integrity: sha512-wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ==} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.60.1': resolution: {integrity: sha512-77PpsFQUCOiZR9+LQEFg9GClyfkNXj1MP6wRnzYs0EeWbPcHs02AXu4xuUbM1zhwn3wqaizle3AEYg5aeoohhg==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.60.1': resolution: {integrity: sha512-5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9w==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-openbsd-x64@4.60.1': resolution: {integrity: sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw==} @@ -1080,6 +1108,11 @@ packages: engines: {node: '>=18'} hasBin: true + pnpm@10.33.0: + resolution: {integrity: sha512-EFaLtKavtYyes2MNqQzJUWQXq+vT+rvmc58K55VyjaFJHp21pUTHatjrdXD1xLs9bGN7LLQb/c20f6gjyGSTGQ==} + engines: {node: '>=18.12'} + hasBin: true + postcss-load-config@6.0.1: resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} engines: {node: '>= 18'} @@ -2184,6 +2217,8 @@ snapshots: optionalDependencies: fsevents: 2.3.2 + pnpm@10.33.0: {} + postcss-load-config@6.0.1(postcss@8.5.9): dependencies: lilconfig: 3.1.3 diff --git a/src/lib/httpClient.ts b/src/lib/httpClient.ts index a90e378..354c4fe 100644 --- a/src/lib/httpClient.ts +++ b/src/lib/httpClient.ts @@ -841,38 +841,17 @@ export default class httpClient { } async fetchPdfResults(ctx: Context): Promise { - const params: Record = {}; - - if (ctx.build.projectId) { - params.project_id = ctx.build.projectId; - } else { - throw new Error('Project ID not found to fetch PDF results'); - } - params.build_id = ctx.build.id; - - const auth = Buffer.from(`${this.username}:${this.accessKey}`).toString('base64'); - - try { - const response = await axios.request({ - url: ctx.env.SMARTUI_UPLOAD_URL + '/smartui/2.0/build/screenshots', - method: 'GET', - params: params, - headers: { - 'accept': 'application/json', - 'Authorization': `Basic ${auth}` - } - }); - - ctx.log.debug(`http response: ${JSON.stringify({ - status: response.status, - headers: response.headers, - body: response.data - })}`); + const params: Record = { + buildId: ctx.build.id, + baseline: false, + buildName: '' + }; - return response.data; - } catch (error: any) { - this.handleHttpError(error, ctx.log); - } + return this.request({ + url: '/screenshot', + method: 'GET', + params, + }, ctx.log); } } diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 75ca63d..bf481bf 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -644,44 +644,39 @@ export function startPdfPolling(ctx: Context) { try { const response = await ctx.client.fetchPdfResults(ctx); - if (response.screenshots && response.build?.build_status !== constants.BUILD_RUNNING) { + if (response.screenshots && response.build?.build_status_ind !== constants.BUILD_RUNNING) { clearInterval(interval); - const pdfGroups = groupScreenshotsByPdf(response.screenshots); - const pdfsWithMismatches = countPdfsWithMismatches(pdfGroups); - const pagesWithMismatches = countPagesWithMismatches(response.screenshots); - - console.log(chalk.green('\nāœ“ PDF Test Results:')); - console.log(chalk.green(`Build Name: ${response.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}`)); + // Flatten screenshots object into array, filtering to only PDF screenshots + const allScreenshots = Array.isArray(response.screenshots) + ? response.screenshots + : Object.values(response.screenshots).flat(); + const screenshotsArray = allScreenshots.filter( + (s: any) => s.browser_name?.endsWith('.pdf') + ); - if (pdfsWithMismatches > 0 || pagesWithMismatches > 0) { - console.log(chalk.yellow(`${pdfsWithMismatches} PDFs and ${pagesWithMismatches} Pages in build ${response.build.name} have changes present.`)); - } else { - console.log(chalk.green('All PDFs match the baseline.')); - } + const pdfGroups = groupScreenshotsByPdf(screenshotsArray); Object.entries(pdfGroups).forEach(([pdfName, pages]) => { - const hasMismatch = pages.some(page => page.mismatch_percentage > 0); + const hasMismatch = pages.some(page => page.status !== 'Approved' && page.status !== 'new'); 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 = page.status !== 'Approved' && page.status !== 'new' ? chalk.yellow : chalk.green; + const mismatchInfo = page.mismatch_percentage != null ? ` (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) } }; @@ -742,7 +737,7 @@ 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 => page.status !== 'Approved' && page.status !== 'new')) { count++; } }); @@ -751,7 +746,7 @@ function countPdfsWithMismatches(pdfGroups: Record): number { } function countPagesWithMismatches(screenshots: any[]): number { - return screenshots.filter(screenshot => screenshot.mismatch_percentage > 0).length; + return screenshots.filter(screenshot => screenshot.status !== 'Approved' && screenshot.status !== 'new').length; } function formatPdfsForOutput(pdfGroups: Record): any[] { @@ -761,10 +756,10 @@ function formatPdfsForOutput(pdfGroups: Record): any[] { pageCount: pages.length, pages: pages.map(page => ({ pageNumber: getPageNumber(page.screenshot_name), - screenshotId: page.captured_image_id, - mismatchPercentage: page.mismatch_percentage, + screenshotId: page.captured_image, + ...(page.mismatch_percentage != null && { mismatchPercentage: page.mismatch_percentage }), status: page.status, - screenshotUrl: page.shareable_link + screenshotUrl: page.captured_image })) }; });