Files
hermes-mcp/product/site/compare-screenshot.mjs
2026-04-29 09:52:53 -04:00

54 lines
1.6 KiB
JavaScript

import fs from "fs";
import { PNG } from "pngjs";
import pixelmatch from "pixelmatch";
const actualPath = process.argv[2];
const baselinePath = process.argv[3];
const diffPath = process.argv[4] || "/tmp/squaremcp-visual-diff.png";
const threshold = Number(process.argv[5] || "0.02");
const maxDiffRatio = Number(process.argv[6] || "0.01");
if (!actualPath || !baselinePath) {
console.error("usage: node compare-screenshot.mjs <actual> <baseline> [diff] [threshold] [maxDiffRatio]");
process.exit(1);
}
if (!fs.existsSync(actualPath) || !fs.existsSync(baselinePath)) {
console.error("actual or baseline screenshot is missing");
process.exit(1);
}
const actual = PNG.sync.read(fs.readFileSync(actualPath));
const baseline = PNG.sync.read(fs.readFileSync(baselinePath));
if (actual.width !== baseline.width || actual.height !== baseline.height) {
console.error(
`dimension mismatch: actual ${actual.width}x${actual.height}, baseline ${baseline.width}x${baseline.height}`
);
process.exit(1);
}
const diff = new PNG({ width: actual.width, height: actual.height });
const mismatchedPixels = pixelmatch(
actual.data,
baseline.data,
diff.data,
actual.width,
actual.height,
{ threshold }
);
const diffRatio = mismatchedPixels / (actual.width * actual.height);
fs.writeFileSync(diffPath, PNG.sync.write(diff));
if (diffRatio > maxDiffRatio) {
console.error(
`visual diff exceeded threshold: mismatched=${mismatchedPixels} ratio=${diffRatio.toFixed(6)} diff=${diffPath}`
);
process.exit(1);
}
console.log(
`visual diff PASS: mismatched=${mismatchedPixels} ratio=${diffRatio.toFixed(6)} diff=${diffPath}`
);