feat: version topology graph metadata
This commit is contained in:
@@ -37,6 +37,20 @@ test("scan captures a state-local inventory without clicking high-risk actions",
|
||||
assert.equal(graph.elements.some((element) => element.accessibleName === "Delete account"), false);
|
||||
});
|
||||
|
||||
test("graph metadata records generation context and policy versions", async () => {
|
||||
const graph = await withTempOutput("metadata", (out) => scanUrl({ url: fixturePath, out }));
|
||||
assert.equal(graph.schemaVersion, "0.2");
|
||||
assert.equal(graph.metadata.engineVersion, "0.2.0");
|
||||
assert.equal(graph.metadata.runtimeContext.browserName, "chromium");
|
||||
assert.equal(graph.metadata.runtimeContext.viewport.width, 1440);
|
||||
assert.equal(graph.metadata.runtimeContext.viewport.height, 1000);
|
||||
assert.equal(graph.metadata.riskPolicyVersion, "risk-policy-v0.2");
|
||||
assert.equal(graph.metadata.locatorScoringVersion, "locator-scoring-v0.2");
|
||||
assert.equal(typeof graph.metadata.crawlSessionId, "string");
|
||||
assert.equal(graph.metadata.inputUrl, fixturePath);
|
||||
assert.equal(typeof graph.metadata.inputFingerprint, "string");
|
||||
});
|
||||
|
||||
test("explore records low-risk edges and keeps high-risk submit actions out of default execution", async () => {
|
||||
const graph = await withTempOutput("explore", (out) => exploreUrl({ url: fixturePath, maxActions: 8, out }));
|
||||
assert.equal(graph.edges.some((edge) => edge.riskLevel === "low" && edge.toStateId), true);
|
||||
|
||||
45
tests/metadata.test.ts
Normal file
45
tests/metadata.test.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { test } from "node:test";
|
||||
import { buildEmptyGraph } from "../src/metadata.js";
|
||||
|
||||
const graphArgs = {
|
||||
inputUrl: "./examples/simple.html",
|
||||
entryUrl: "file:///examples/simple.html",
|
||||
mode: "scan" as const,
|
||||
};
|
||||
|
||||
test("input fingerprint is stable for the same input and mode", () => {
|
||||
const first = buildEmptyGraph(graphArgs);
|
||||
const second = buildEmptyGraph(graphArgs);
|
||||
|
||||
assert.equal(first.metadata.inputFingerprint, second.metadata.inputFingerprint);
|
||||
});
|
||||
|
||||
test("crawl session id is unique for each generated graph", () => {
|
||||
const first = withFixedDate(() => buildEmptyGraph(graphArgs));
|
||||
const second = withFixedDate(() => buildEmptyGraph(graphArgs));
|
||||
|
||||
assert.notEqual(first.metadata.crawlSessionId, second.metadata.crawlSessionId);
|
||||
});
|
||||
|
||||
function withFixedDate<T>(callback: () => T): T {
|
||||
const RealDate = Date;
|
||||
const fixedTime = new RealDate("2026-06-16T00:00:00.000Z").getTime();
|
||||
|
||||
class FixedDate extends RealDate {
|
||||
constructor(value?: string | number | Date) {
|
||||
super(value ?? fixedTime);
|
||||
}
|
||||
|
||||
static now(): number {
|
||||
return fixedTime;
|
||||
}
|
||||
}
|
||||
|
||||
globalThis.Date = FixedDate as DateConstructor;
|
||||
try {
|
||||
return callback();
|
||||
} finally {
|
||||
globalThis.Date = RealDate;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user