Files
rea/tests/acceptance/applications/javascriptWindowOptionsCli.test.ts
YsopwnableandKaoru0822 d72d856f58 feat(electron): resolve stable local constant window options
Resolve stable local constant BrowserWindow options with retained provenance and shared early-exit mutation queries. Preserve source ordering and unknown results for relevant mutations or escapes.

Includes real Joplin correctness/cost receipts and regression coverage.

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-16 14:52:33 +08:00

110 lines
4.5 KiB
TypeScript

import { expect } from "vitest";
import { cliTest } from "../../support/cli/cliFixture.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { connectLocalToolsMcp } from "../../fixtures/localToolsMcp.js";
import { writeFixtureFiles } from "../../support/javascriptApplicationFixture.js";
import { parseEvidence } from "../../../src/domain/evidence.js";
import { javascriptApplicationAnalysisResultSchema } from "../../../src/domain/javascript/javascriptApplicationAnalysis.js";
import { analysisViewResultSchema } from "../../../src/domain/analysisView/analysisView.js";
cliTest(
"retains constant window preferences and inferred source provenance through CLI, MCP and fact views",
async ({ cli }) => {
const root = await createTestTempDirectory("rea-window-options-");
await writeFixtureFiles(root, {
"main.js": [
'throw new Error("Static input must never execute");',
'const { BrowserWindow } = require("electron");',
"function open() {",
' const prefs = {nodeIntegration: true, contextIsolation: false, preload: "./preload.js"};',
" const options = {webPreferences: prefs};",
' if (linux) options.icon = "icon.png";',
" new BrowserWindow(options);",
" const escaped = {webPreferences: {sandbox: true}};",
" patch(escaped); new BrowserWindow(escaped);",
" new BrowserWindow({webPreferences: {sandbox: true}});",
"}",
].join("\n"),
"preload.js": "// Inert preload source",
});
const cliResponse = await cli.run({
arguments: ["analyze-javascript-application", root, "--format", "json"],
});
expect(cliResponse.exitCode, JSON.stringify(cliResponse.json)).toBe(0);
const cliResult = javascriptApplicationAnalysisResultSchema.parse(
parseEvidence(cliResponse.json).normalized_result,
);
const { call } = await connectLocalToolsMcp();
const response = await call("analyze_javascript_application", {
input_path: root,
format: "directory",
});
expect(response.isError).not.toBe(true);
const parent = parseEvidence(response.structuredContent);
const result = javascriptApplicationAnalysisResultSchema.parse(
parent.normalized_result,
);
expect(result.graph).toEqual(cliResult.graph);
expect(result.summary).toEqual(cliResult.summary);
expect(result.summary).toMatchObject({
browser_windows: 3,
explicit_web_preferences: 4,
preload_entrypoints: 1,
});
const windows = result.graph.nodes.filter(
(node) => node.kind === "browser-window",
);
const resolved = windows.find(
(node) =>
node.observations[0]?.properties.resolution_sources !== undefined,
);
expect(resolved?.observations[0]).toMatchObject({
properties: {
source_path: "main.js",
options_status: "object-literal",
resolution_sources: [
{ source: "main.js", start: { line: 5 } },
{ source: "main.js", start: { line: 4 } },
],
},
evidence: {
state: "inferred",
authority: "static-relationship-inference",
location: { value: { source: "main.js", start: { line: 7 } } },
},
});
expect(
windows.filter(
(node) =>
node.observations[0]?.properties.web_preferences_status === "dynamic",
),
).toHaveLength(1);
expect(
windows.filter(
(node) => node.observations[0]?.evidence.state === "observed",
),
).toHaveLength(2);
const viewResponse = await call("inspect_analysis_view", {
source: { kind: "retained-evidence", evidence_id: parent.evidence_id },
view: {
kind: "javascript-facts",
where: { paths: ["main.js"], kinds: ["browser-window"] },
property_keys: ["web_preferences", "resolution_sources"],
},
});
expect(viewResponse.isError).not.toBe(true);
const view = analysisViewResultSchema.parse(
parseEvidence(viewResponse.structuredContent).normalized_result,
);
if (view.kind !== "javascript-facts") throw new Error("Expected fact view");
expect(view.rows).toHaveLength(3);
const row = view.rows.find((row) => row.node_id === resolved?.node_id);
expect(row?.evidence).toEqual(resolved?.observations[0]?.evidence);
expect(row?.properties).toEqual({
web_preferences: resolved?.observations[0]?.properties.web_preferences,
resolution_sources:
resolved?.observations[0]?.properties.resolution_sources,
});
},
);