85 lines
2.7 KiB
JavaScript
85 lines
2.7 KiB
JavaScript
import { spawnSync } from "node:child_process";
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
const repoRoot = path.resolve(here, "../../..");
|
|
const designRoot = "file:///Users/maidong/Desktop/zyc/qiyuan_gitea/AirShelf/电商AI平台";
|
|
const targetRoot = "http://127.0.0.1:5173/exact";
|
|
const manifest = JSON.parse(fs.readFileSync(path.join(here, "pages.json"), "utf8"));
|
|
|
|
function arg(name, fallback = "") {
|
|
const index = process.argv.indexOf(`--${name}`);
|
|
return index >= 0 ? process.argv[index + 1] : fallback;
|
|
}
|
|
|
|
function asUrl(root, value) {
|
|
if (value.startsWith("http://") || value.startsWith("https://") || value.startsWith("file://")) return value;
|
|
return `${root}/${value}`;
|
|
}
|
|
|
|
const viewport = arg("viewport", "1440x900");
|
|
const only = arg("only", "");
|
|
const pages = only ? manifest.filter((item) => item.name.includes(only)) : manifest;
|
|
const results = [];
|
|
|
|
for (const item of pages) {
|
|
const source = asUrl(designRoot, item.source);
|
|
const target = item.target || asUrl(targetRoot, item.targetPath || item.source);
|
|
const args = [
|
|
path.join(here, "compare-page.mjs"),
|
|
"--name", item.name,
|
|
"--source", source,
|
|
"--target", target,
|
|
"--viewport", viewport,
|
|
"--clear-target-storage"
|
|
];
|
|
console.log(`\n[visual-parity] ${item.name}`);
|
|
const run = spawnSync(process.execPath, args, {
|
|
cwd: here,
|
|
encoding: "utf8",
|
|
stdio: ["ignore", "pipe", "pipe"]
|
|
});
|
|
if (run.stdout) process.stdout.write(run.stdout);
|
|
if (run.stderr) process.stderr.write(run.stderr);
|
|
const reportFile = path.join(repoRoot, "core/qa/visual-parity/output", `${item.name}.report.json`);
|
|
let report = null;
|
|
if (fs.existsSync(reportFile)) {
|
|
report = JSON.parse(fs.readFileSync(reportFile, "utf8"));
|
|
}
|
|
results.push({
|
|
name: item.name,
|
|
ok: run.status === 0 && report?.pass === true,
|
|
status: run.status,
|
|
diffPixels: report?.diffPixels ?? null,
|
|
diffRatio: report?.diffRatio ?? null,
|
|
note: item.note || ""
|
|
});
|
|
}
|
|
|
|
const failed = results.filter((item) => !item.ok);
|
|
const summary = {
|
|
viewport,
|
|
total: results.length,
|
|
passed: results.length - failed.length,
|
|
failed: failed.length,
|
|
results
|
|
};
|
|
|
|
const summaryPath = path.join(repoRoot, "core/qa/visual-parity/output/all.report.json");
|
|
fs.mkdirSync(path.dirname(summaryPath), { recursive: true });
|
|
fs.writeFileSync(summaryPath, `${JSON.stringify(summary, null, 2)}\n`);
|
|
|
|
console.log("\n[visual-parity] summary");
|
|
console.table(results.map((item) => ({
|
|
page: item.name,
|
|
ok: item.ok,
|
|
diffPixels: item.diffPixels,
|
|
diffRatio: item.diffRatio
|
|
})));
|
|
|
|
if (failed.length) {
|
|
process.exitCode = 1;
|
|
}
|