81 lines
3.0 KiB
JavaScript
81 lines
3.0 KiB
JavaScript
#!/usr/bin/env node
|
|
import assert from "node:assert/strict";
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { runCli } from "../tools/hwlab-cli/lib/cli.mjs";
|
|
|
|
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
|
|
async function captureCli(args) {
|
|
let stdout = "";
|
|
let stderr = "";
|
|
const exitCode = await runCli(args, {
|
|
cwd: repoRoot,
|
|
stdout: {
|
|
write(chunk) {
|
|
stdout += chunk;
|
|
}
|
|
},
|
|
stderr: {
|
|
write(chunk) {
|
|
stderr += chunk;
|
|
}
|
|
}
|
|
});
|
|
return { exitCode, stdout, stderr };
|
|
}
|
|
|
|
const dryRun = await captureCli(["test", "e2e", "--env", "dev", "--mvp"]);
|
|
assert.equal(dryRun.exitCode, 0, dryRun.stderr);
|
|
const dryRunJson = JSON.parse(dryRun.stdout);
|
|
assert.equal(dryRunJson.mode, "dry-run");
|
|
assert.equal(dryRunJson.environment, "dev");
|
|
assert.match(String(dryRunJson.endpoint ?? ""), /^http:\/\//u);
|
|
assert.match(dryRunJson.statement, /no DEV\/PROD changes/);
|
|
|
|
const explicitDryRun = await captureCli(["test", "e2e", "--env", "dev", "--mvp", "--dry-run"]);
|
|
assert.equal(explicitDryRun.exitCode, 0, explicitDryRun.stderr);
|
|
assert.equal(JSON.parse(explicitDryRun.stdout).mode, "dry-run");
|
|
|
|
const liveBlocked = await captureCli([
|
|
"test",
|
|
"e2e",
|
|
"--env",
|
|
"dev",
|
|
"--mvp",
|
|
"--live",
|
|
"--confirm-dev",
|
|
"--confirmed-non-production"
|
|
]);
|
|
assert.equal(liveBlocked.exitCode, 2);
|
|
const liveBlockedJson = JSON.parse(liveBlocked.stderr);
|
|
assert.equal(liveBlockedJson.code, "BLOCKED");
|
|
assert.ok(Array.isArray(liveBlockedJson.blockers));
|
|
|
|
const activeWebSource = [
|
|
"web/hwlab-cloud-web/index.html",
|
|
"web/hwlab-cloud-web/app.ts",
|
|
"web/hwlab-cloud-web/app-device-pod.ts",
|
|
"web/hwlab-cloud-web/app-conversation.ts",
|
|
"web/hwlab-cloud-web/app-trace.ts",
|
|
"web/hwlab-cloud-web/app-helpers.ts",
|
|
"web/hwlab-cloud-web/live-status.ts",
|
|
"web/hwlab-cloud-web/help.md"
|
|
].map((file) => fs.readFileSync(path.resolve(repoRoot, file), "utf8")).join("\n");
|
|
const distContract = fs.readFileSync(path.resolve(repoRoot, "web/hwlab-cloud-web/scripts/dist-contract.ts"), "utf8");
|
|
|
|
assert.match(activeWebSource, /Device Pod/u);
|
|
assert.match(activeWebSource, /\/v1\/device-pods/u);
|
|
for (const legacyTerm of ["Gateway-SIMU", "BOX-SIMU", "Patch Panel", "hwlab-patch-panel", "gateway-simu", "box-simu", "/v1/m3"]) {
|
|
assert.doesNotMatch(activeWebSource, new RegExp(escapeRegExp(legacyTerm), "u"), `legacy frontend term returned: ${legacyTerm}`);
|
|
}
|
|
assert.doesNotMatch(distContract, /gate-summary\.mjs/u, "Cloud Web dist must not ship the legacy gate-summary topology asset");
|
|
assert.equal(fs.existsSync(path.resolve(repoRoot, "web/hwlab-cloud-web/gate-summary.mjs")), false, "legacy web gate-summary asset must be removed");
|
|
|
|
console.log("L6 CLI/Web smoke passed: CLI dry-run remains non-mutating and Cloud Web uses the Device Pod contract without the legacy gate-summary topology asset");
|
|
|
|
function escapeRegExp(value) {
|
|
return String(value).replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
}
|