138 lines
5.1 KiB
JavaScript
138 lines
5.1 KiB
JavaScript
#!/usr/bin/env node
|
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
import {
|
|
parseSmokeArgs,
|
|
printSmokeHelp,
|
|
runDevCloudWorkbenchLayoutSmoke
|
|
} from "./src/dev-cloud-workbench-smoke-lib.mjs";
|
|
import { ensureNotRepoReportsPath, tempReportPath } from "./src/report-paths.mjs";
|
|
|
|
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
|
|
export function parseLayoutSmokeArgs(argv) {
|
|
if (argv.includes("--help")) return { help: true };
|
|
const normalized = ["--layout"];
|
|
for (let index = 0; index < argv.length; index += 1) {
|
|
const arg = argv[index];
|
|
if (arg === "--static" || arg === "--source") {
|
|
continue;
|
|
}
|
|
if (arg === "--live") {
|
|
const next = argv[index + 1];
|
|
if (next && !next.startsWith("--")) {
|
|
normalized.push("--url");
|
|
normalized.push(next);
|
|
index += 1;
|
|
} else {
|
|
normalized.push("--url");
|
|
normalized.push("http://74.48.78.17:16666/");
|
|
}
|
|
continue;
|
|
}
|
|
normalized.push(arg);
|
|
if (["--url", "--report"].includes(arg)) {
|
|
index += 1;
|
|
if (!argv[index]) throw new Error(`${arg} requires a value`);
|
|
normalized.push(argv[index]);
|
|
}
|
|
}
|
|
return parseSmokeArgs(normalized);
|
|
}
|
|
|
|
export function layoutSmokeExitCode(report) {
|
|
return report.status === "pass" || report.status === "usage" ? 0 : report.status === "skip" ? 2 : 2;
|
|
}
|
|
|
|
export function compactLayoutSmokeCliOutput(report) {
|
|
if (report.status === "usage") return report;
|
|
return {
|
|
status: report.status,
|
|
task: report.task,
|
|
issue: report.issue,
|
|
mode: report.mode,
|
|
sourceMode: report.sourceMode,
|
|
url: report.url,
|
|
generatedAt: report.generatedAt,
|
|
evidenceLevel: report.evidenceLevel,
|
|
devLive: report.devLive,
|
|
summary: report.summary,
|
|
failures: (report.failures ?? []).map(compactLayoutFailure),
|
|
blockers: (report.blockers ?? []).map(compactLayoutFailure),
|
|
skipped: (report.skipped ?? []).map((item) => ({
|
|
checkId: item.checkId,
|
|
failureType: item.failureType ?? "skip",
|
|
summary: item.summary
|
|
})),
|
|
artifacts: {
|
|
reportPath: report.artifacts?.reportPath ?? null,
|
|
screenshotDir: report.artifacts?.screenshotDir ?? null,
|
|
screenshotCount: Array.isArray(report.artifacts?.screenshots) ? report.artifacts.screenshots.length : 0
|
|
},
|
|
validationCommands: report.validationCommands,
|
|
safety: {
|
|
layoutOnly: report.safety?.layoutOnly === true,
|
|
codeAgentPostSent: report.safety?.codeAgentPostSent === true,
|
|
hardwareWriteApis: report.safety?.hardwareWriteApis === true,
|
|
hitTestMethod: report.safety?.hitTestMethod ?? null,
|
|
statement: report.safety?.statement ?? null
|
|
}
|
|
};
|
|
}
|
|
|
|
function compactLayoutFailure(failure) {
|
|
return {
|
|
checkId: failure.checkId ?? failure.scope ?? null,
|
|
viewport: failure.viewport ?? null,
|
|
selector: failure.selector ?? null,
|
|
failureType: failure.failureType ?? "blocked",
|
|
summary: failure.summary ?? null,
|
|
artifact: failure.artifact ?? null
|
|
};
|
|
}
|
|
|
|
if (process.argv[1] && fileURLToPath(import.meta.url) === process.argv[1]) {
|
|
try {
|
|
const args = parseLayoutSmokeArgs(process.argv.slice(2));
|
|
const report = args.help
|
|
? {
|
|
...printSmokeHelp(),
|
|
command: `node scripts/dev-cloud-workbench-layout-smoke.mjs [--static|--build|--live --url http://74.48.78.17:16666/] [--report ${tempReportPath("dev-cloud-workbench-layout.json")}]`,
|
|
layoutNotes: [
|
|
"默认 --static 使用 source/static 本地静态服务。",
|
|
"--build 会先运行 cd web/hwlab-cloud-web && bun run build,再检查本地 dist 构建产物。",
|
|
"--live --url http://74.48.78.17:16666/ 只做 DEV live UI 布局/命中/溢出检查,不发送 Code Agent 消息,不调用 Device Pod 或硬件写操作,不等同于硬件验收。",
|
|
"结构化失败会包含 status、viewport、selector、failureType、artifact screenshot/report path。"
|
|
]
|
|
}
|
|
: await runDevCloudWorkbenchLayoutSmoke(args);
|
|
if (args.reportPath && report.status !== "usage") {
|
|
const reportPath = ensureNotRepoReportsPath(repoRoot, path.resolve(process.cwd(), args.reportPath), "--report");
|
|
report.artifacts = { ...(report.artifacts ?? {}), reportPath };
|
|
await mkdir(path.dirname(reportPath), { recursive: true });
|
|
await writeFile(reportPath, `${JSON.stringify(report, null, 2)}\n`, "utf8");
|
|
}
|
|
process.stdout.write(`${JSON.stringify(compactLayoutSmokeCliOutput(report), null, 2)}\n`);
|
|
process.exitCode = layoutSmokeExitCode(report);
|
|
} catch (error) {
|
|
const failure = {
|
|
status: "blocked",
|
|
mode: "layout-browser",
|
|
generatedAt: new Date().toISOString(),
|
|
failureType: "blocked",
|
|
selector: null,
|
|
viewport: null,
|
|
artifact: null,
|
|
reportPath: null,
|
|
summary: error instanceof Error ? error.message : String(error)
|
|
};
|
|
process.stderr.write(`[dev-cloud-workbench-layout-smoke] ${error instanceof Error ? error.stack : String(error)}\n`);
|
|
process.stdout.write(`${JSON.stringify(failure, null, 2)}\n`);
|
|
process.exitCode = 2;
|
|
}
|
|
}
|
|
|
|
export { repoRoot };
|