fix: bound Web UX review evidence and cleanup

This commit is contained in:
2026-09-01 23:44:24 +09:00
parent c4a3f4ba1e
commit eea79dead4
13 changed files with 518 additions and 86 deletions
@@ -12,6 +12,9 @@ async function freePort(): Promise<number> {
Deno.test("browser smoke captures distinct owner and non-owner evidence and cleans its server", async () => {
const directory = await Deno.makeTempDir();
const previousSecret = Deno.env.get("WEB_UX_FIXTURE_SECRET");
const fixtureSecret = "fixture-canary-secret";
Deno.env.set("WEB_UX_FIXTURE_SECRET", fixtureSecret);
const port = await freePort();
const baseUrl = `http://127.0.0.1:${port}`;
try {
@@ -45,6 +48,10 @@ Deno.test("browser smoke captures distinct owner and non-owner evidence and clea
id: "browser-smoke",
title: "Browser smoke",
baseUrl,
redact: {
selectors: ["[data-web-ux-redact]"],
text: ["${WEB_UX_FIXTURE_SECRET}"],
},
personas: [
{ id: "owner", label: "Owner", auth: { kind: "storage-state", path: "auth/owner.json" } },
{
@@ -61,17 +68,26 @@ Deno.test("browser smoke captures distinct owner and non-owner evidence and clea
goal: "Verify permission-specific composition",
dataState: "Deterministic fixture repository",
ready: { kind: "selector", selector: "main" },
capturePoints: [{ id: "initial", label: "Initial" }],
capturePoints: [{
id: "initial",
label: "Initial",
interaction: [{
action: "wait",
ready: { kind: "selector", selector: "h1" },
}],
}],
}],
processes: [{
id: "fixture-server",
command: Deno.execPath(),
args: [
"run",
"--allow-env",
"--allow-net",
join(Deno.cwd(), "browser-tests/fixture_server.ts"),
String(port),
],
env: { WEB_UX_FIXTURE_SECRET: "${WEB_UX_FIXTURE_SECRET}" },
readyUrl: `${baseUrl}/health`,
}],
}),
@@ -81,15 +97,28 @@ Deno.test("browser smoke captures distinct owner and non-owner evidence and clea
outputDirectory: join(directory, "artifacts"),
runId: "multi-persona",
});
assertEquals(manifest.status, "completed");
assertEquals(manifest.status, "completed-with-errors");
assertEquals(manifest.captures.map((item) => item.persona.id), ["owner", "non-owner"]);
assertEquals(manifest.captures.every((item) => item.screenshots.length === 1), true);
assertEquals(manifest.contactSheet.png, "contact-sheet.png");
assertEquals(manifest.captures[0].route.ready.kind, "selector");
assertEquals(manifest.captures[0].interactions[0].action, "wait");
assertEquals(manifest.captures[0].errorSummary, {
observed: 150,
retained: 100,
truncated: true,
limit: 100,
});
assertEquals(manifest.contactSheet.png?.bundlePath, "contact-sheet.png");
const runDirectory = join(directory, "artifacts", "multi-persona");
const reviewContext = await Deno.readTextFile(join(runDirectory, "review-context.json"));
assertEquals(reviewContext.includes('"cookies"'), false);
assertEquals(reviewContext.includes(fixtureSecret), false);
const processLog = await Deno.readTextFile(
join(runDirectory, "process-logs", "fixture-server.stdout.log"),
);
assertEquals(processLog.includes(fixtureSecret), false);
if (Deno.build.os !== "windows") {
const screenshot = join(runDirectory, manifest.captures[0].screenshots[0].path);
const screenshot = join(runDirectory, manifest.captures[0].screenshots[0].bundlePath);
assertEquals((await Deno.stat(screenshot)).mode! & 0o777, 0o600);
}
await assertRejects(
@@ -97,6 +126,8 @@ Deno.test("browser smoke captures distinct owner and non-owner evidence and clea
TypeError,
);
} finally {
if (previousSecret === undefined) Deno.env.delete("WEB_UX_FIXTURE_SECRET");
else Deno.env.set("WEB_UX_FIXTURE_SECRET", previousSecret);
await Deno.remove(directory, { recursive: true });
}
});
+4 -1
View File
@@ -1,6 +1,9 @@
const port = Number(Deno.args[0]);
if (!Number.isInteger(port) || port <= 0) throw new Error("port is required");
const canary = Deno.env.get("WEB_UX_FIXTURE_SECRET") ?? "";
console.log(`Authorization: Bearer ${canary}`);
Deno.serve({ hostname: "127.0.0.1", port }, (request) => {
const url = new URL(request.url);
if (url.pathname === "/health") return new Response("ok");
@@ -11,7 +14,7 @@ Deno.serve({ hostname: "127.0.0.1", port }, (request) => {
? '<button type="button">Add repository</button>'
: '<p role="note">Ask a Workspace owner to change repository access.</p>';
return new Response(
`<!doctype html><html><head><title>${title}</title><style>body{font:16px system-ui;margin:0}main{max-width:800px;margin:40px auto}header{border-bottom:1px solid #ccc;padding:16px}section{border:1px solid #ccc;padding:20px}button{background:#06c;color:white;padding:10px 20px}</style></head><body><header>Workspace</header><main><h1>${title}</h1><section><h2>main</h2><p>SSH repository access is configured.</p>${action}</section></main></body></html>`,
`<!doctype html><html><head><title>${title}</title><style>body{font:16px system-ui;margin:0}main{max-width:800px;margin:40px auto}header{border-bottom:1px solid #ccc;padding:16px}section{border:1px solid #ccc;padding:20px}button{background:#06c;color:white;padding:10px 20px}</style></head><body><header>Workspace</header><main><h1>${title}</h1><section><h2>main</h2><p>SSH repository access is configured.</p>${action}<span data-web-ux-redact>${canary}</span><script>for(let index=0;index<150;index++)console.error('fixture error '+index)</script></section></main></body></html>`,
{ headers: { "content-type": "text/html; charset=utf-8" } },
);
});