hy-farm/tools/compare_ui_baseline.mjs
2026-05-29 19:54:56 +08:00

62 lines
1.9 KiB
JavaScript

import fs from 'node:fs';
import path from 'node:path';
import { pathToFileURL } from 'node:url';
import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);
const nodePathEntries = (process.env.NODE_PATH || '')
.split(path.delimiter)
.filter(Boolean);
const resolveOptions = nodePathEntries.length > 0 ? { paths: nodePathEntries } : undefined;
const { default: pixelmatch } = await import(pathToFileURL(require.resolve('pixelmatch', resolveOptions)));
const { PNG } = require(require.resolve('pngjs', resolveOptions));
const [expectedPath, actualPath, diffPath = 'docs/ui-baseline/login-diff.png'] = process.argv.slice(2);
if (!expectedPath || !actualPath) {
console.error('Usage: node tools/compare_ui_baseline.mjs <expected.png> <actual.png> [diff.png]');
process.exit(2);
}
const expected = PNG.sync.read(fs.readFileSync(expectedPath));
const actual = PNG.sync.read(fs.readFileSync(actualPath));
if (expected.width !== actual.width || expected.height !== actual.height) {
console.error(JSON.stringify({
ok: false,
error: 'Image dimensions differ.',
expected: { width: expected.width, height: expected.height },
actual: { width: actual.width, height: actual.height },
}, null, 2));
process.exit(1);
}
const diff = new PNG({ width: expected.width, height: expected.height });
const mismatchedPixels = pixelmatch(
expected.data,
actual.data,
diff.data,
expected.width,
expected.height,
{ threshold: 0.1, includeAA: true }
);
fs.mkdirSync(path.dirname(diffPath), { recursive: true });
fs.writeFileSync(diffPath, PNG.sync.write(diff));
const totalPixels = expected.width * expected.height;
const result = {
ok: mismatchedPixels === 0,
expected: expectedPath,
actual: actualPath,
diff: diffPath,
width: expected.width,
height: expected.height,
mismatchedPixels,
totalPixels,
mismatchRatio: Number((mismatchedPixels / totalPixels).toFixed(6)),
};
console.log(JSON.stringify(result, null, 2));
process.exit(result.ok ? 0 : 1);