Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 42 additions & 3 deletions src/compare/libs/looks-same/looks-same.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,11 @@ describe('getDiff', () => {
const getImageMock = jest.fn().mockReturnValueOnce(image).mockReturnValueOnce(anotherImage);
service = await initService({ getImageMock });
service.compare = jest.fn().mockReturnValueOnce({ equal: false });
service.createDiff = jest.fn().mockReturnValueOnce('diff name');
service.createDiff = jest.fn().mockReturnValueOnce({
diffName: 'diff name',
diffPercent: 5,
pixelMisMatchCount: 20,
});

const result = await service.getDiff(
{
Expand All @@ -192,9 +196,44 @@ describe('getDiff', () => {
expect(result).toStrictEqual({
status: TestStatus.unresolved,
diffName: 'diff name',
diffPercent: undefined,
pixelMisMatchCount: undefined,
diffPercent: 5,
pixelMisMatchCount: 20,
isSameDimension: true,
});
});
});

describe('createDiff', () => {
it('returns metrics from the generated Looks-Same diff', async () => {
const baseline = new PNG({ width: 2, height: 1 });
const image = new PNG({ width: 2, height: 1 });
baseline.data.fill(255);
image.data.fill(255);
image.data[0] = 0;

const saveImageMock = jest.fn().mockReturnValueOnce('diff name');
service = await initService({ saveImageMock });

const result = await service.createDiff(baseline, image, {
...DEFAULT_CONFIG,
strict: true,
ignoreAntialiasing: false,
});

expect(result).toStrictEqual({
diffName: 'diff name',
diffPercent: 50,
pixelMisMatchCount: 1,
});
expect(saveImageMock).toHaveBeenCalledWith('diff', expect.any(Buffer));
});

it('rejects an equal result instead of silently omitting the artifact', async () => {
const image = new PNG({ width: 1, height: 1 });
service = await initService({});

await expect(service.createDiff(image, image, DEFAULT_CONFIG)).rejects.toThrow(
'Cannot create a diff image for an equal Looks-Same result'
);
});
});
37 changes: 22 additions & 15 deletions src/compare/libs/looks-same/looks-same.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,10 @@ export class LookSameService implements ImageComparator {
} else {
result.status = TestStatus.unresolved;
if (data.saveDiffAsFile) {
result.diffName = await this.createDiff(baselineIgnored, imageIgnored, config);
const diff = await this.createDiff(baselineIgnored, imageIgnored, config);
result.diffName = diff.diffName;
result.diffPercent = diff.diffPercent;
result.pixelMisMatchCount = diff.pixelMisMatchCount;
}
}

Expand All @@ -76,20 +79,24 @@ export class LookSameService implements ImageComparator {
return undefined;
}

async createDiff(baseline: PNG, image: PNG, config: LooksSameConfig): Promise<string | undefined> {
const buffer = await looksSame
.createDiff({
reference: PNG.sync.write(baseline),
current: PNG.sync.write(image),
highlightColor: '#ff00ff',
...config,
})
.catch((error) => {
this.logger.error(error.message);
});
if (buffer) {
return this.staticService.saveImage('diff', buffer);
async createDiff(
baseline: PNG,
image: PNG,
config: LooksSameConfig
): Promise<Pick<DiffResult, 'diffName' | 'diffPercent' | 'pixelMisMatchCount'>> {
const diffResult = await looksSame(PNG.sync.write(baseline), PNG.sync.write(image), {
...config,
createDiffImage: true,
});

if (diffResult.equal) {
throw new Error('Cannot create a diff image for an equal Looks-Same result');
}
return undefined;

return {
diffName: await this.staticService.saveImage('diff', await diffResult.diffImage.createBuffer('png')),
diffPercent: diffResult.totalPixels > 0 ? (diffResult.differentPixels * 100) / diffResult.totalPixels : 0,
pixelMisMatchCount: diffResult.differentPixels,
};
}
}
Loading