fix(verifiers): own browser fixture setup and cleanup in one scope
This commit is contained in:
parent
278d7fb284
commit
fd8a2e98ff
|
|
@ -14,36 +14,42 @@ import { webModuleTraceResultSchema } from "../../dist/domain/webModuleTrace.js"
|
|||
import { NativeModuleResolver } from "../../dist/browser/modules/NativeModuleResolver.js";
|
||||
import { startBrowserModuleSite } from "../fixtures/browser-module-site.mjs";
|
||||
import { mcpTextValue } from "./mcp-verifier-results.mjs";
|
||||
import { closeRuntimeFixtureResources } from "./browser-runtime-fixture-lifecycle.mjs";
|
||||
|
||||
/** Check native URL resolution against an independently loaded module graph through CLI/MCP. */
|
||||
export async function verifyBrowserModules(
|
||||
executable,
|
||||
entrypoint = fileURLToPath(new URL("../rea.mjs", import.meta.url)),
|
||||
) {
|
||||
const site = await startBrowserModuleSite();
|
||||
const root = await mkdtemp(join(tmpdir(), "rea-browser-modules-"));
|
||||
const env = {
|
||||
...process.env,
|
||||
REA_LOG_LEVEL: "silent",
|
||||
REA_BROWSER_EXECUTABLE: executable,
|
||||
HOPPER_LAUNCHER_PATH: "/rea-unconfigured-provider/hopper",
|
||||
};
|
||||
const cli = async (...args) => {
|
||||
const { stdout } = await promisify(execFile)(
|
||||
process.execPath,
|
||||
[entrypoint, ...args, "--json"],
|
||||
{ env, timeout: 45000, maxBuffer: 16 * 1024 * 1024 },
|
||||
);
|
||||
return parseEvidence(JSON.parse(stdout));
|
||||
};
|
||||
const transport = new StdioClientTransport({
|
||||
command: process.execPath,
|
||||
args: [entrypoint, "mcp"],
|
||||
env,
|
||||
stderr: "pipe",
|
||||
});
|
||||
const client = new Client({ name: "module-real-e2e", version: "1" });
|
||||
let site;
|
||||
let root;
|
||||
let transport;
|
||||
let client;
|
||||
let primaryError;
|
||||
try {
|
||||
site = await startBrowserModuleSite();
|
||||
root = await mkdtemp(join(tmpdir(), "rea-browser-modules-"));
|
||||
const env = {
|
||||
...process.env,
|
||||
REA_LOG_LEVEL: "silent",
|
||||
REA_BROWSER_EXECUTABLE: executable,
|
||||
HOPPER_LAUNCHER_PATH: "/rea-unconfigured-provider/hopper",
|
||||
};
|
||||
const cli = async (...args) => {
|
||||
const { stdout } = await promisify(execFile)(
|
||||
process.execPath,
|
||||
[entrypoint, ...args, "--json"],
|
||||
{ env, timeout: 45000, maxBuffer: 16 * 1024 * 1024 },
|
||||
);
|
||||
return parseEvidence(JSON.parse(stdout));
|
||||
};
|
||||
transport = new StdioClientTransport({
|
||||
command: process.execPath,
|
||||
args: [entrypoint, "mcp"],
|
||||
env,
|
||||
stderr: "pipe",
|
||||
});
|
||||
client = new Client({ name: "module-real-e2e", version: "1" });
|
||||
const oracle = await loadingOracle(executable, site);
|
||||
const scenario = {
|
||||
browser: { mode: "launch", executable_path: executable },
|
||||
|
|
@ -298,11 +304,17 @@ export async function verifyBrowserModules(
|
|||
map_identity_verified: true,
|
||||
implicit_refetches: 0,
|
||||
};
|
||||
} catch (cause) {
|
||||
primaryError = cause;
|
||||
throw cause;
|
||||
} finally {
|
||||
await client.close();
|
||||
await transport.close();
|
||||
await site.close();
|
||||
await rm(root, { recursive: true, force: true });
|
||||
const cleanup = [];
|
||||
if (client !== undefined) cleanup.push(() => client.close());
|
||||
if (transport !== undefined) cleanup.push(() => transport.close());
|
||||
if (site !== undefined) cleanup.push(() => site.close());
|
||||
if (root !== undefined)
|
||||
cleanup.push(() => rm(root, { recursive: true, force: true }));
|
||||
await closeRuntimeFixtureResources(cleanup, primaryError);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import {
|
|||
} from "../fixtures/browser-network-site.mjs";
|
||||
import { assertBrowserNetworkEvidence } from "./browser-network-assertions.mjs";
|
||||
import { scenarioProfiles } from "./browser-scenario-verifier.mjs";
|
||||
import { closeRuntimeFixtureResources } from "./browser-runtime-fixture-lifecycle.mjs";
|
||||
|
||||
/** Exercise selected network content through real CLI and stdio MCP, one browser at a time. */
|
||||
export async function verifyBrowserNetworkEvidence(
|
||||
|
|
@ -21,9 +22,14 @@ export async function verifyBrowserNetworkEvidence(
|
|||
entrypoint = fileURLToPath(new URL("../rea.mjs", import.meta.url)),
|
||||
attachment,
|
||||
) {
|
||||
const site = await startBrowserNetworkSite();
|
||||
const profilesBefore = await scenarioProfiles();
|
||||
let site;
|
||||
let profilesBefore;
|
||||
let transport;
|
||||
let client;
|
||||
let primaryError;
|
||||
try {
|
||||
site = await startBrowserNetworkSite();
|
||||
profilesBefore = await scenarioProfiles();
|
||||
const scenario = browserScenarioSchema.parse({
|
||||
browser: { mode: "launch", executable_path: executable },
|
||||
start_url: { url: site.origin },
|
||||
|
|
@ -97,58 +103,50 @@ export async function verifyBrowserNetworkEvidence(
|
|||
() => assertBrowserNetworkEvidence(swapped, site.origin),
|
||||
/associated with a different same-URL request/,
|
||||
);
|
||||
const transport = new StdioClientTransport({
|
||||
transport = new StdioClientTransport({
|
||||
command: process.execPath,
|
||||
args: [entrypoint, "mcp"],
|
||||
env,
|
||||
stderr: "pipe",
|
||||
});
|
||||
const client = new Client({ name: "network-real-e2e", version: "1" });
|
||||
client = new Client({ name: "network-real-e2e", version: "1" });
|
||||
let mcpProof;
|
||||
try {
|
||||
await client.connect(transport);
|
||||
const result = await client.callTool(
|
||||
{ name: "capture_browser_scenario", arguments: scenario },
|
||||
await client.connect(transport);
|
||||
const result = await client.callTool(
|
||||
{ name: "capture_browser_scenario", arguments: scenario },
|
||||
{ timeout: 60_000 },
|
||||
);
|
||||
assert.notEqual(result.isError, true, JSON.stringify(result));
|
||||
const evidence = parseEvidence(result.structuredContent);
|
||||
mcpProof = assertBrowserNetworkEvidence(
|
||||
browserScenarioCaptureSchema.parse(evidence.normalized_result),
|
||||
site.origin,
|
||||
);
|
||||
if (attachment !== undefined) {
|
||||
const connectedScenario = browserScenarioSchema.parse({
|
||||
...scenario,
|
||||
browser: { mode: "connect", ...attachment },
|
||||
});
|
||||
const connected = await client.callTool(
|
||||
{ name: "capture_browser_scenario", arguments: connectedScenario },
|
||||
{ timeout: 60_000 },
|
||||
);
|
||||
assert.notEqual(result.isError, true, JSON.stringify(result));
|
||||
const evidence = parseEvidence(result.structuredContent);
|
||||
mcpProof = assertBrowserNetworkEvidence(
|
||||
browserScenarioCaptureSchema.parse(evidence.normalized_result),
|
||||
site.origin,
|
||||
);
|
||||
if (attachment !== undefined) {
|
||||
const connectedScenario = browserScenarioSchema.parse({
|
||||
...scenario,
|
||||
browser: { mode: "connect", ...attachment },
|
||||
});
|
||||
const connected = await client.callTool(
|
||||
{ name: "capture_browser_scenario", arguments: connectedScenario },
|
||||
{ timeout: 60_000 },
|
||||
);
|
||||
assert.notEqual(connected.isError, true, JSON.stringify(connected));
|
||||
const connectedEvidence = parseEvidence(connected.structuredContent);
|
||||
assert.deepEqual(
|
||||
assertBrowserNetworkEvidence(
|
||||
browserScenarioCaptureSchema.parse(
|
||||
connectedEvidence.normalized_result,
|
||||
),
|
||||
site.origin,
|
||||
"disconnected-external",
|
||||
assert.notEqual(connected.isError, true, JSON.stringify(connected));
|
||||
const connectedEvidence = parseEvidence(connected.structuredContent);
|
||||
assert.deepEqual(
|
||||
assertBrowserNetworkEvidence(
|
||||
browserScenarioCaptureSchema.parse(
|
||||
connectedEvidence.normalized_result,
|
||||
),
|
||||
cliProof,
|
||||
);
|
||||
assert.ok(
|
||||
(await fetch(`${attachment.cdp_endpoint}/json/version`)).ok,
|
||||
"Network capture closed the external browser",
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
await client.close();
|
||||
} finally {
|
||||
await transport.close();
|
||||
}
|
||||
site.origin,
|
||||
"disconnected-external",
|
||||
),
|
||||
cliProof,
|
||||
);
|
||||
assert.ok(
|
||||
(await fetch(`${attachment.cdp_endpoint}/json/version`)).ok,
|
||||
"Network capture closed the external browser",
|
||||
);
|
||||
}
|
||||
assert.deepEqual(mcpProof, cliProof);
|
||||
for (const path of [
|
||||
|
|
@ -180,7 +178,14 @@ export async function verifyBrowserNetworkEvidence(
|
|||
profile_cleanup: true,
|
||||
connected_network_verified: attachment !== undefined,
|
||||
};
|
||||
} catch (cause) {
|
||||
primaryError = cause;
|
||||
throw cause;
|
||||
} finally {
|
||||
await site.close();
|
||||
const cleanup = [];
|
||||
if (client !== undefined) cleanup.push(() => client.close());
|
||||
if (transport !== undefined) cleanup.push(() => transport.close());
|
||||
if (site !== undefined) cleanup.push(() => site.close());
|
||||
await closeRuntimeFixtureResources(cleanup, primaryError);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import {
|
|||
assertExportedScriptAnalysis,
|
||||
} from "./browser-script-export-assertions.mjs";
|
||||
import { mcpTextValue } from "./mcp-verifier-results.mjs";
|
||||
import { closeRuntimeFixtureResources } from "./browser-runtime-fixture-lifecycle.mjs";
|
||||
|
||||
/** Verify capture → export → existing analysis through real CLI and stdio MCP. */
|
||||
export async function verifyBrowserScriptExport(
|
||||
|
|
@ -22,24 +23,29 @@ export async function verifyBrowserScriptExport(
|
|||
entrypoint = fileURLToPath(new URL("../rea.mjs", import.meta.url)),
|
||||
attachment,
|
||||
) {
|
||||
const site = await startBrowserScriptSite();
|
||||
const root = await mkdtemp(join(tmpdir(), "rea-browser-script-export-"));
|
||||
const env = {
|
||||
...process.env,
|
||||
REA_LOG_LEVEL: "silent",
|
||||
HOPPER_LAUNCHER_PATH: "/rea-unconfigured-provider/hopper",
|
||||
};
|
||||
const cli = exportCli(entrypoint, env);
|
||||
const scenario = scriptCaptureScenario(executable, site.origin);
|
||||
const save = (name, capture) => saveCapture(root, name, capture);
|
||||
const transport = new StdioClientTransport({
|
||||
command: process.execPath,
|
||||
args: [entrypoint, "mcp"],
|
||||
env,
|
||||
stderr: "pipe",
|
||||
});
|
||||
const client = new Client({ name: "web-script-real-e2e", version: "1" });
|
||||
let site;
|
||||
let root;
|
||||
let transport;
|
||||
let client;
|
||||
let primaryError;
|
||||
try {
|
||||
site = await startBrowserScriptSite();
|
||||
root = await mkdtemp(join(tmpdir(), "rea-browser-script-export-"));
|
||||
const env = {
|
||||
...process.env,
|
||||
REA_LOG_LEVEL: "silent",
|
||||
HOPPER_LAUNCHER_PATH: "/rea-unconfigured-provider/hopper",
|
||||
};
|
||||
const cli = exportCli(entrypoint, env);
|
||||
const scenario = scriptCaptureScenario(executable, site.origin);
|
||||
const save = (name, capture) => saveCapture(root, name, capture);
|
||||
transport = new StdioClientTransport({
|
||||
command: process.execPath,
|
||||
args: [entrypoint, "mcp"],
|
||||
env,
|
||||
stderr: "pipe",
|
||||
});
|
||||
client = new Client({ name: "web-script-real-e2e", version: "1" });
|
||||
const cliCapture = await cli(
|
||||
"capture-browser-scenario",
|
||||
JSON.stringify(scenario),
|
||||
|
|
@ -103,11 +109,17 @@ export async function verifyBrowserScriptExport(
|
|||
query_variants_isolated: true,
|
||||
implicit_refetches: 0,
|
||||
};
|
||||
} catch (cause) {
|
||||
primaryError = cause;
|
||||
throw cause;
|
||||
} finally {
|
||||
await client.close();
|
||||
await transport.close();
|
||||
await site.close();
|
||||
await rm(root, { recursive: true, force: true });
|
||||
const cleanup = [];
|
||||
if (client !== undefined) cleanup.push(() => client.close());
|
||||
if (transport !== undefined) cleanup.push(() => transport.close());
|
||||
if (site !== undefined) cleanup.push(() => site.close());
|
||||
if (root !== undefined)
|
||||
cleanup.push(() => rm(root, { recursive: true, force: true }));
|
||||
await closeRuntimeFixtureResources(cleanup, primaryError);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,35 +12,41 @@ import { parseEvidence } from "../../dist/domain/evidence.js";
|
|||
import { webSourceLocationResultSchema } from "../../dist/domain/webSourceLocation.js";
|
||||
import { startBrowserSourceMapSite } from "../fixtures/browser-source-map-site.mjs";
|
||||
import { mcpTextValue } from "./mcp-verifier-results.mjs";
|
||||
import { closeRuntimeFixtureResources } from "./browser-runtime-fixture-lifecycle.mjs";
|
||||
|
||||
/** Verify real Chrome capture → export → original compiler point through packaged CLI/MCP. */
|
||||
export async function verifyBrowserSourceMap(
|
||||
executable,
|
||||
entrypoint = fileURLToPath(new URL("../rea.mjs", import.meta.url)),
|
||||
) {
|
||||
const site = await startBrowserSourceMapSite();
|
||||
const root = await mkdtemp(join(tmpdir(), "rea-browser-source-map-"));
|
||||
const env = {
|
||||
...process.env,
|
||||
REA_LOG_LEVEL: "silent",
|
||||
HOPPER_LAUNCHER_PATH: "/rea-unconfigured-provider/hopper",
|
||||
};
|
||||
const cli = async (...args) => {
|
||||
const { stdout } = await promisify(execFile)(
|
||||
process.execPath,
|
||||
[entrypoint, ...args, "--json"],
|
||||
{ env, timeout: 45000, maxBuffer: 16 * 1024 * 1024 },
|
||||
);
|
||||
return parseEvidence(JSON.parse(stdout));
|
||||
};
|
||||
const transport = new StdioClientTransport({
|
||||
command: process.execPath,
|
||||
args: [entrypoint, "mcp"],
|
||||
env,
|
||||
stderr: "pipe",
|
||||
});
|
||||
const client = new Client({ name: "source-map-real-e2e", version: "1" });
|
||||
let site;
|
||||
let root;
|
||||
let transport;
|
||||
let client;
|
||||
let primaryError;
|
||||
try {
|
||||
site = await startBrowserSourceMapSite();
|
||||
root = await mkdtemp(join(tmpdir(), "rea-browser-source-map-"));
|
||||
const env = {
|
||||
...process.env,
|
||||
REA_LOG_LEVEL: "silent",
|
||||
HOPPER_LAUNCHER_PATH: "/rea-unconfigured-provider/hopper",
|
||||
};
|
||||
const cli = async (...args) => {
|
||||
const { stdout } = await promisify(execFile)(
|
||||
process.execPath,
|
||||
[entrypoint, ...args, "--json"],
|
||||
{ env, timeout: 45000, maxBuffer: 16 * 1024 * 1024 },
|
||||
);
|
||||
return parseEvidence(JSON.parse(stdout));
|
||||
};
|
||||
transport = new StdioClientTransport({
|
||||
command: process.execPath,
|
||||
args: [entrypoint, "mcp"],
|
||||
env,
|
||||
stderr: "pipe",
|
||||
});
|
||||
client = new Client({ name: "source-map-real-e2e", version: "1" });
|
||||
const capture = await cli(
|
||||
"capture-browser-scenario",
|
||||
JSON.stringify({
|
||||
|
|
@ -126,11 +132,17 @@ export async function verifyBrowserSourceMap(
|
|||
selected_inert_userinfo_context_preserved: true,
|
||||
public_point_cases: 4,
|
||||
};
|
||||
} catch (cause) {
|
||||
primaryError = cause;
|
||||
throw cause;
|
||||
} finally {
|
||||
await client.close();
|
||||
await transport.close();
|
||||
await site.close();
|
||||
await rm(root, { recursive: true, force: true });
|
||||
const cleanup = [];
|
||||
if (client !== undefined) cleanup.push(() => client.close());
|
||||
if (transport !== undefined) cleanup.push(() => transport.close());
|
||||
if (site !== undefined) cleanup.push(() => site.close());
|
||||
if (root !== undefined)
|
||||
cleanup.push(() => rm(root, { recursive: true, force: true }));
|
||||
await closeRuntimeFixtureResources(cleanup, primaryError);
|
||||
}
|
||||
}
|
||||
function assertPoint(evidence, { site, input, capture, identity }) {
|
||||
|
|
|
|||
|
|
@ -6,15 +6,21 @@ import { join } from "node:path";
|
|||
import { chromium } from "playwright-core";
|
||||
import { startBrowserVerifierSite } from "./fixtures/browser-verifier-site.mjs";
|
||||
import { verifyBrowserDomDestinations } from "./lib/browser-dom-destinations-e2e.mjs";
|
||||
import { closeRuntimeFixtureResources } from "./lib/browser-runtime-fixture-lifecycle.mjs";
|
||||
import { requireOrdinaryWindowsVerifierCaller } from "./lib/windows-ordinary-user-verifier.mjs";
|
||||
|
||||
const executable = process.env.REA_BROWSER_EXECUTABLE;
|
||||
if (!executable)
|
||||
throw new Error("verify:browser:dom requires REA_BROWSER_EXECUTABLE");
|
||||
const profile = await mkdtemp(join(tmpdir(), "rea-browser-dom-"));
|
||||
const site = await startBrowserVerifierSite();
|
||||
await requireOrdinaryWindowsVerifierCaller();
|
||||
let profile;
|
||||
let site;
|
||||
let context;
|
||||
let report;
|
||||
let primaryError;
|
||||
try {
|
||||
profile = await mkdtemp(join(tmpdir(), "rea-browser-dom-"));
|
||||
site = await startBrowserVerifierSite();
|
||||
context = await chromium.launchPersistentContext(profile, {
|
||||
executablePath: executable,
|
||||
headless: true,
|
||||
|
|
@ -50,9 +56,15 @@ try {
|
|||
native_oracle: true,
|
||||
verified: true,
|
||||
};
|
||||
} catch (cause) {
|
||||
primaryError = cause;
|
||||
throw cause;
|
||||
} finally {
|
||||
await context?.close();
|
||||
await site.close();
|
||||
await rm(profile, { recursive: true, force: true });
|
||||
const cleanup = [];
|
||||
if (context !== undefined) cleanup.push(() => context.close());
|
||||
if (site !== undefined) cleanup.push(() => site.close());
|
||||
if (profile !== undefined)
|
||||
cleanup.push(() => rm(profile, { recursive: true, force: true }));
|
||||
await closeRuntimeFixtureResources(cleanup, primaryError);
|
||||
}
|
||||
process.stdout.write(`${JSON.stringify(report)}\n`);
|
||||
|
|
|
|||
|
|
@ -2,12 +2,14 @@
|
|||
import { access } from "node:fs/promises";
|
||||
import { verifyBrowserModules } from "./lib/browser-module-e2e.mjs";
|
||||
import { createVerifierRun, completeVerifierRun } from "./lib/verifier-run.mjs";
|
||||
import { requireOrdinaryWindowsVerifierCaller } from "./lib/windows-ordinary-user-verifier.mjs";
|
||||
|
||||
const executable = process.env.REA_BROWSER_EXECUTABLE;
|
||||
if (!executable)
|
||||
throw new Error(
|
||||
"verify:browser:modules requires REA_BROWSER_EXECUTABLE for caller-supplied Chromium",
|
||||
);
|
||||
await requireOrdinaryWindowsVerifierCaller();
|
||||
await access(executable);
|
||||
const run = createVerifierRun();
|
||||
const proof = await verifyBrowserModules(executable, process.argv[2]);
|
||||
|
|
|
|||
|
|
@ -2,12 +2,14 @@
|
|||
import { access } from "node:fs/promises";
|
||||
import { verifyBrowserNetworkEvidence } from "./lib/browser-network-e2e.mjs";
|
||||
import { createVerifierRun, completeVerifierRun } from "./lib/verifier-run.mjs";
|
||||
import { requireOrdinaryWindowsVerifierCaller } from "./lib/windows-ordinary-user-verifier.mjs";
|
||||
|
||||
const executable = process.env.REA_BROWSER_EXECUTABLE;
|
||||
if (executable === undefined || executable === "")
|
||||
throw new Error(
|
||||
"verify:browser:network requires REA_BROWSER_EXECUTABLE pointing to an installed Chrome-family browser",
|
||||
);
|
||||
await requireOrdinaryWindowsVerifierCaller();
|
||||
await access(executable);
|
||||
const run = createVerifierRun();
|
||||
const proof = await verifyBrowserNetworkEvidence(executable, process.argv[2]);
|
||||
|
|
|
|||
|
|
@ -2,12 +2,14 @@
|
|||
import { access } from "node:fs/promises";
|
||||
import { verifyBrowserScriptExport } from "./lib/browser-script-export-e2e.mjs";
|
||||
import { createVerifierRun, completeVerifierRun } from "./lib/verifier-run.mjs";
|
||||
import { requireOrdinaryWindowsVerifierCaller } from "./lib/windows-ordinary-user-verifier.mjs";
|
||||
|
||||
const executable = process.env.REA_BROWSER_EXECUTABLE;
|
||||
if (executable === undefined || executable === "")
|
||||
throw new Error(
|
||||
"verify:browser:scripts requires REA_BROWSER_EXECUTABLE pointing to an installed Chrome-family browser",
|
||||
);
|
||||
await requireOrdinaryWindowsVerifierCaller();
|
||||
await access(executable);
|
||||
const run = createVerifierRun();
|
||||
const proof = await verifyBrowserScriptExport(executable, process.argv[2]);
|
||||
|
|
|
|||
Loading…
Reference in New Issue