diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index de6a5e4e0..85cc94501 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: - node-version: [18.x, 20.x, 22.x] + node-version: [18.x, 20.x, 22.6] # https://github.com/nodejs/node/issues/54532 steps: - uses: actions/checkout@v2 diff --git a/lib/adapters/test-result/playwright.ts b/lib/adapters/test-result/playwright.ts index 56c69ec57..a13636413 100644 --- a/lib/adapters/test-result/playwright.ts +++ b/lib/adapters/test-result/playwright.ts @@ -34,6 +34,8 @@ export type PwtImageDiffError = ExtendedError<{snapshotName: string, diffCluster export type PwtNoRefImageError = ExtendedError<{snapshotName: string}>; +export type PlaywrightImageFile = ImageFile & { relativePath: string }; + export enum PwtTestStatus { PASSED = 'passed', FAILED = 'failed', @@ -139,7 +141,7 @@ const extractToMatchScreenshotError = (result: PlaywrightTestResult, {state, exp } : null; }; -const getImageData = (attachment: PlaywrightAttachment | undefined): ImageFile | null => { +const getImageData = (attachment: PlaywrightAttachment | undefined): PlaywrightImageFile | null => { if (!attachment) { return null; } @@ -147,7 +149,7 @@ const getImageData = (attachment: PlaywrightAttachment | undefined): ImageFile | return { path: attachment.path as string, size: !attachment.size ? _.pick(sizeOf(attachment.path as string), ['height', 'width']) as ImageSize : attachment.size, - ...(attachment.relativePath ? {relativePath: attachment.relativePath} : {}) + relativePath: attachment.relativePath || path.relative(process.cwd(), attachment.path as string) }; }; @@ -239,7 +241,7 @@ export class PlaywrightTestResultAdapter implements ReporterTestResult { const error = extractToMatchScreenshotError(this._testResult, {state, expectedAttachment, diffAttachment, actualAttachment}) || this.error; - // We don't provide refImg here, because on some pwt versions it's impossible to provide correct path: + // We now provide refImg here, though on some pwt versions it's impossible to provide correct path: // older pwt versions had test-results directory in expected path instead of project directory. if (error?.name === ErrorName.IMAGE_DIFF && expectedImg && diffImg && actualImg) { return { @@ -248,6 +250,7 @@ export class PlaywrightTestResultAdapter implements ReporterTestResult { diffImg, actualImg, expectedImg, + refImg: _.clone(expectedImg), diffClusters: _.get(error, 'diffClusters', []), // TODO: extract diffOptions from config diffOptions: {current: actualImg.path, reference: expectedImg.path, ...DEFAULT_DIFF_OPTIONS} @@ -257,7 +260,8 @@ export class PlaywrightTestResultAdapter implements ReporterTestResult { status: ERROR, stateName: state, error: _.pick(error, ['message', 'name', 'stack']), - actualImg + actualImg, + ...(expectedImg ? {refImg: _.clone(expectedImg)} : {}) } satisfies ImageInfoNoRef; } else if (expectedAttachment?.isUpdated && expectedImg && actualImg) { return { diff --git a/lib/common-utils.ts b/lib/common-utils.ts index 5f9401302..c52161c5b 100644 --- a/lib/common-utils.ts +++ b/lib/common-utils.ts @@ -123,6 +123,10 @@ export const isNoRefImageError = (error?: unknown): error is NoRefImageError => return (error as {name?: string})?.name === ErrorName.NO_REF_IMAGE; }; +export const isImageError = (error?: unknown): boolean => { + return isAssertViewError(error) || isImageDiffError(error) || isNoRefImageError(error); +}; + export const hasNoRefImageErrors = ({assertViewResults = []}: {assertViewResults?: {name?: string}[]}): boolean => { return assertViewResults.some((assertViewResult) => isNoRefImageError(assertViewResult)); }; diff --git a/lib/static/modules/reducers/tree/helpers.js b/lib/static/modules/reducers/tree/helpers.js index e16039fe7..0fc08cb46 100644 --- a/lib/static/modules/reducers/tree/helpers.js +++ b/lib/static/modules/reducers/tree/helpers.js @@ -1,7 +1,7 @@ import {get, pick, set, uniq, isEmpty} from 'lodash'; import {EXPAND_ALL, EXPAND_ERRORS, EXPAND_RETRIES} from '../../../../constants/expand-modes'; import {ensureDiffProperty, getUpdatedProperty} from '../../utils/state'; -import {determineFinalStatus, determineStatus, isAssertViewError, isUpdatedStatus} from '../../../../common-utils'; +import {determineFinalStatus, determineStatus, isImageError, isUpdatedStatus} from '../../../../common-utils'; import {updateParentSuitesStatus, calcSuitesShowness, calcSuitesOpenness} from './nodes/suites'; import {calcBrowsersShowness, calcBrowsersOpenness} from './nodes/browsers'; import {changeImageStatus, calcImagesOpenness} from './nodes/images'; @@ -110,9 +110,9 @@ export function updateImagesStatus({tree, view, images, imageIdsArray, newStatus .map(imageId => getUpdatedProperty(tree, diff, ['images', 'byId', imageId, 'status'])); const finalStatus = determineFinalStatus(imageStatuses); - const trueResultStatus = isAssertViewError(result.error) && finalStatus === ERROR ? FAIL : finalStatus; + const trueResultStatus = isImageError(result.error) && finalStatus === ERROR ? FAIL : finalStatus; - if (isAssertViewError(result.error) && trueResultStatus !== result.status) { + if (isImageError(result.error) && trueResultStatus !== result.status) { browserIds.push(result.parentId); changeNodeState(tree.results.byId, resultId, {status: trueResultStatus}, diff.results.byId); } diff --git a/test/unit/lib/adapters/test-result/playwright.ts b/test/unit/lib/adapters/test-result/playwright.ts index c7f3567ad..f8f4de6ed 100644 --- a/test/unit/lib/adapters/test-result/playwright.ts +++ b/test/unit/lib/adapters/test-result/playwright.ts @@ -6,6 +6,7 @@ import { DEFAULT_DIFF_OPTIONS, ImageTitleEnding, PlaywrightAttachment, + PlaywrightImageFile, PwtTestStatus } from 'lib/adapters/test-result/playwright'; import {ErrorName} from 'lib/errors'; @@ -189,14 +190,35 @@ describe('PlaywrightTestResultAdapter', () => { assert.equal(adapter.imagesInfo.length, 2); assert.deepEqual(adapter.imagesInfo.find(info => (info as ImageInfoDiff).stateName === undefined), { status: ERROR, - actualImg: {path: `test-results/test-name-1.png`, size: {height: 100, width: 200}} + actualImg: { + path: `test-results/test-name-1.png`, + relativePath: `test-results/test-name-1.png`, + size: {height: 100, width: 200} + } as PlaywrightImageFile }); assert.deepEqual(adapter.imagesInfo.find(info => (info as ImageInfoDiff).stateName === 'header'), { status: FAIL, stateName: 'header', - actualImg: {path: `test-results/header-actual.png`, size: {height: 100, width: 200}}, - expectedImg: {path: 'project-dir/header-expected.png', size: {height: 100, width: 200}}, - diffImg: {path: 'test-results/header-diff.png', size: {height: 100, width: 200}}, + actualImg: { + path: `test-results/header-actual.png`, + relativePath: `test-results/header-actual.png`, + size: {height: 100, width: 200} + } as PlaywrightImageFile, + expectedImg: { + path: 'project-dir/header-expected.png', + relativePath: 'project-dir/header-expected.png', + size: {height: 100, width: 200} + } as PlaywrightImageFile, + refImg: { + path: 'project-dir/header-expected.png', + relativePath: 'project-dir/header-expected.png', + size: {height: 100, width: 200} + } as PlaywrightImageFile, + diffImg: { + path: 'test-results/header-diff.png', + relativePath: 'test-results/header-diff.png', + size: {height: 100, width: 200} + } as PlaywrightImageFile, diffClusters: [], diffOptions: {current: 'test-results/header-actual.png', reference: 'project-dir/header-expected.png', ...DEFAULT_DIFF_OPTIONS} }); @@ -214,7 +236,11 @@ describe('PlaywrightTestResultAdapter', () => { assert.equal(adapter.imagesInfo.length, 2); assert.deepEqual(adapter.imagesInfo.find(info => (info as ImageInfoNoRef).stateName === undefined), { status: ERROR, - actualImg: {path: `test-results/test-name-1.png`, size: {height: 100, width: 200}} + actualImg: { + path: `test-results/test-name-1.png`, + relativePath: `test-results/test-name-1.png`, + size: {height: 100, width: 200} + } as PlaywrightImageFile }); assert.deepEqual(adapter.imagesInfo.find(info => (info as ImageInfoNoRef).stateName === 'header'), { status: ERROR, @@ -224,7 +250,11 @@ describe('PlaywrightTestResultAdapter', () => { message: 'snapshot doesn\'t exist at some.png', stack: '' }, - actualImg: {path: `test-results/header-actual.png`, size: {height: 100, width: 200}} + actualImg: { + path: `test-results/header-actual.png`, + relativePath: `test-results/header-actual.png`, + size: {height: 100, width: 200} + } as PlaywrightImageFile }); }); });