mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-05 01:50:27 +08:00
95 lines
3.5 KiB
TypeScript
95 lines
3.5 KiB
TypeScript
import { after, beforeEach, describe, it } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
import { tmpdir } from 'node:os';
|
|
import { dirname, join } from 'node:path';
|
|
import { createRequire } from 'node:module';
|
|
|
|
import { compareSnapshots, updateBaseline } from './visual-tester.ts';
|
|
|
|
const require = createRequire(import.meta.url);
|
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
const { PNG } = require('pngjs') as typeof import('pngjs');
|
|
|
|
const ORIGINAL_ENV = { ...process.env };
|
|
|
|
function writeSolidPng(filePath: string, rgba: [number, number, number, number], pixelCount = 100): void {
|
|
const size = Math.max(1, Math.floor(Math.sqrt(pixelCount)));
|
|
const png = new PNG({ width: size, height: size });
|
|
|
|
for (let i = 0; i < png.data.length; i += 4) {
|
|
png.data[i] = rgba[0];
|
|
png.data[i + 1] = rgba[1];
|
|
png.data[i + 2] = rgba[2];
|
|
png.data[i + 3] = rgba[3];
|
|
}
|
|
|
|
mkdirSync(dirname(filePath), { recursive: true });
|
|
writeFileSync(filePath, PNG.sync.write(png));
|
|
}
|
|
|
|
describe('visual-tester helpers', () => {
|
|
const snapshotRoot = mkdtempSync(join(tmpdir(), 'ccw-visual-snapshots-'));
|
|
|
|
beforeEach(() => {
|
|
process.env = { ...ORIGINAL_ENV, CCW_VISUAL_SNAPSHOT_ROOT: snapshotRoot };
|
|
});
|
|
|
|
after(() => {
|
|
process.env = ORIGINAL_ENV;
|
|
rmSync(snapshotRoot, { recursive: true, force: true });
|
|
});
|
|
|
|
it('updates baseline from current snapshots', () => {
|
|
const currentPath = join(snapshotRoot, 'current', 'baseline-copy.png');
|
|
writeSolidPng(currentPath, [10, 20, 30, 255]);
|
|
|
|
const baselinePath = updateBaseline('baseline-copy');
|
|
assert.deepEqual(readFileSync(baselinePath), readFileSync(currentPath));
|
|
});
|
|
|
|
it('compares identical PNGs as pass', () => {
|
|
const baselinePath = join(snapshotRoot, 'baseline', 'same.png');
|
|
const currentPath = join(snapshotRoot, 'current', 'same.png');
|
|
writeSolidPng(currentPath, [255, 0, 0, 255]);
|
|
writeSolidPng(baselinePath, [255, 0, 0, 255]);
|
|
|
|
const result = compareSnapshots(baselinePath, currentPath);
|
|
assert.equal(result.pass, true);
|
|
assert.equal(result.diffPixels, 0);
|
|
});
|
|
|
|
it('fails and generates a diff PNG when over tolerance', () => {
|
|
const baselinePath = join(snapshotRoot, 'baseline', 'different.png');
|
|
const currentPath = join(snapshotRoot, 'current', 'different.png');
|
|
writeSolidPng(baselinePath, [255, 255, 255, 255]);
|
|
writeSolidPng(currentPath, [255, 255, 255, 255]);
|
|
|
|
const png = PNG.sync.read(readFileSync(currentPath));
|
|
png.data[0] = 0;
|
|
writeFileSync(currentPath, PNG.sync.write(png));
|
|
|
|
const result = compareSnapshots(baselinePath, currentPath, 0.1);
|
|
assert.equal(result.pass, false);
|
|
assert.ok(result.diffPath);
|
|
assert.ok(readFileSync(result.diffPath!).length > 0);
|
|
});
|
|
|
|
it('respects configured tolerance percent', () => {
|
|
const baselinePath = join(snapshotRoot, 'baseline', 'tolerance.png');
|
|
const currentPath = join(snapshotRoot, 'current', 'tolerance.png');
|
|
writeSolidPng(baselinePath, [0, 0, 0, 255]);
|
|
writeSolidPng(currentPath, [0, 0, 0, 255]);
|
|
|
|
const png = PNG.sync.read(readFileSync(currentPath));
|
|
png.data[0] = 255;
|
|
writeFileSync(currentPath, PNG.sync.write(png));
|
|
|
|
const failResult = compareSnapshots(baselinePath, currentPath, 0.1);
|
|
assert.equal(failResult.pass, false);
|
|
|
|
const passResult = compareSnapshots(baselinePath, currentPath, 100);
|
|
assert.equal(passResult.pass, true);
|
|
});
|
|
});
|