test: serialize subprocess-heavy integrations
This commit is contained in:
parent
40c6f60ac9
commit
f46fc7f1f3
|
|
@ -34,30 +34,10 @@ describe("browser CLI parity", () => {
|
|||
browser.allowedOrigin,
|
||||
]),
|
||||
};
|
||||
const [listed, inspected] = await Promise.all([
|
||||
runCli(
|
||||
["list-browser-targets", browser.endpoint, "--approved", "--json"],
|
||||
environment,
|
||||
),
|
||||
runCli(
|
||||
[
|
||||
"inspect-web-page",
|
||||
browser.endpoint,
|
||||
"allowed-page",
|
||||
"--approved",
|
||||
"--observation-ms",
|
||||
"0",
|
||||
"--include-console-text",
|
||||
"--console-text-approved",
|
||||
"--include-json-body-shapes",
|
||||
"--json-body-schema-approved",
|
||||
"--include-websocket-shapes",
|
||||
"--websocket-shape-approved",
|
||||
"--json",
|
||||
],
|
||||
environment,
|
||||
),
|
||||
]);
|
||||
const listed = await runCli(
|
||||
["list-browser-targets", browser.endpoint, "--approved", "--json"],
|
||||
environment,
|
||||
);
|
||||
expect(listed).toMatchObject({
|
||||
operation: "list_browser_targets",
|
||||
provider: { id: "rea-cdp-browser" },
|
||||
|
|
@ -65,6 +45,24 @@ describe("browser CLI parity", () => {
|
|||
targets: { items: [{ target_id: "allowed-page" }] },
|
||||
},
|
||||
});
|
||||
const inspected = await runCli(
|
||||
[
|
||||
"inspect-web-page",
|
||||
browser.endpoint,
|
||||
"allowed-page",
|
||||
"--approved",
|
||||
"--observation-ms",
|
||||
"0",
|
||||
"--include-console-text",
|
||||
"--console-text-approved",
|
||||
"--include-json-body-shapes",
|
||||
"--json-body-schema-approved",
|
||||
"--include-websocket-shapes",
|
||||
"--websocket-shape-approved",
|
||||
"--json",
|
||||
],
|
||||
environment,
|
||||
);
|
||||
expect(inspected).toMatchObject({
|
||||
operation: "inspect_web_page",
|
||||
provider: { id: "rea-cdp-browser" },
|
||||
|
|
@ -81,30 +79,15 @@ describe("browser CLI parity", () => {
|
|||
},
|
||||
});
|
||||
const inspection = normalizedResult(inspected);
|
||||
const [compared, analyzed] = await Promise.all([
|
||||
runCli(
|
||||
[
|
||||
"compare-web-captures",
|
||||
JSON.stringify({ inspection }),
|
||||
JSON.stringify({ inspection }),
|
||||
"--json",
|
||||
],
|
||||
environment,
|
||||
),
|
||||
runCli(
|
||||
[
|
||||
"analyze-web-bundle",
|
||||
browser.endpoint,
|
||||
"allowed-page",
|
||||
"--approved",
|
||||
"--source-capture-approved",
|
||||
"--observation-ms",
|
||||
"0",
|
||||
"--json",
|
||||
],
|
||||
environment,
|
||||
),
|
||||
]);
|
||||
const compared = await runCli(
|
||||
[
|
||||
"compare-web-captures",
|
||||
JSON.stringify({ inspection }),
|
||||
JSON.stringify({ inspection }),
|
||||
"--json",
|
||||
],
|
||||
environment,
|
||||
);
|
||||
expect(compared).toMatchObject({
|
||||
operation: "compare_web_captures",
|
||||
normalized_result: {
|
||||
|
|
@ -114,6 +97,19 @@ describe("browser CLI parity", () => {
|
|||
},
|
||||
},
|
||||
});
|
||||
const analyzed = await runCli(
|
||||
[
|
||||
"analyze-web-bundle",
|
||||
browser.endpoint,
|
||||
"allowed-page",
|
||||
"--approved",
|
||||
"--source-capture-approved",
|
||||
"--observation-ms",
|
||||
"0",
|
||||
"--json",
|
||||
],
|
||||
environment,
|
||||
);
|
||||
expect(analyzed).toMatchObject({
|
||||
operation: "analyze_web_bundle",
|
||||
normalized_result: {
|
||||
|
|
@ -121,32 +117,18 @@ describe("browser CLI parity", () => {
|
|||
observations: { source_maps: { status: "not_requested" } },
|
||||
},
|
||||
});
|
||||
const [observedSession, webMcp] = await Promise.all([
|
||||
runCli(
|
||||
[
|
||||
"observe-web-session",
|
||||
browser.endpoint,
|
||||
"allowed-page",
|
||||
"--approved",
|
||||
"--observation-ms",
|
||||
"5",
|
||||
"--json",
|
||||
],
|
||||
environment,
|
||||
),
|
||||
runCli(
|
||||
[
|
||||
"discover-webmcp-tools",
|
||||
browser.endpoint,
|
||||
"allowed-page",
|
||||
"--approved",
|
||||
"--observation-ms",
|
||||
"0",
|
||||
"--json",
|
||||
],
|
||||
environment,
|
||||
),
|
||||
]);
|
||||
const observedSession = await runCli(
|
||||
[
|
||||
"observe-web-session",
|
||||
browser.endpoint,
|
||||
"allowed-page",
|
||||
"--approved",
|
||||
"--observation-ms",
|
||||
"5",
|
||||
"--json",
|
||||
],
|
||||
environment,
|
||||
);
|
||||
expect(observedSession).toMatchObject({
|
||||
operation: "observe_web_session",
|
||||
normalized_result: {
|
||||
|
|
@ -156,6 +138,18 @@ describe("browser CLI parity", () => {
|
|||
]),
|
||||
},
|
||||
});
|
||||
const webMcp = await runCli(
|
||||
[
|
||||
"discover-webmcp-tools",
|
||||
browser.endpoint,
|
||||
"allowed-page",
|
||||
"--approved",
|
||||
"--observation-ms",
|
||||
"0",
|
||||
"--json",
|
||||
],
|
||||
environment,
|
||||
);
|
||||
expect(webMcp).toMatchObject({
|
||||
operation: "discover_webmcp_tools",
|
||||
normalized_result: {
|
||||
|
|
@ -164,34 +158,17 @@ describe("browser CLI parity", () => {
|
|||
},
|
||||
},
|
||||
});
|
||||
const [screenshot, policy] = await Promise.all([
|
||||
runCli(
|
||||
[
|
||||
"capture-web-screenshot",
|
||||
browser.endpoint,
|
||||
"allowed-page",
|
||||
"--approved",
|
||||
"--screenshot-approved",
|
||||
"--json",
|
||||
],
|
||||
environment,
|
||||
),
|
||||
runCli(
|
||||
[
|
||||
"policy",
|
||||
"explain",
|
||||
"browser_observe",
|
||||
"--origins",
|
||||
browser.endpoint,
|
||||
"--origins",
|
||||
browser.allowedOrigin,
|
||||
"--network",
|
||||
"loopback",
|
||||
"--json",
|
||||
],
|
||||
environment,
|
||||
),
|
||||
]);
|
||||
const screenshot = await runCli(
|
||||
[
|
||||
"capture-web-screenshot",
|
||||
browser.endpoint,
|
||||
"allowed-page",
|
||||
"--approved",
|
||||
"--screenshot-approved",
|
||||
"--json",
|
||||
],
|
||||
environment,
|
||||
);
|
||||
const artifact = screenshotArtifact(screenshot);
|
||||
expect(artifact).toMatchObject({ media_type: "image/png", bytes: 70 });
|
||||
const visual = await runCli(
|
||||
|
|
@ -207,6 +184,21 @@ describe("browser CLI parity", () => {
|
|||
operation: "compare_web_screenshots",
|
||||
normalized_result: { status: "identical", changed_pixels: 0 },
|
||||
});
|
||||
const policy = await runCli(
|
||||
[
|
||||
"policy",
|
||||
"explain",
|
||||
"browser_observe",
|
||||
"--origins",
|
||||
browser.endpoint,
|
||||
"--origins",
|
||||
browser.allowedOrigin,
|
||||
"--network",
|
||||
"loopback",
|
||||
"--json",
|
||||
],
|
||||
environment,
|
||||
);
|
||||
expect(policy).toEqual({
|
||||
allowed: true,
|
||||
grant_id: "administrator:browser_observe",
|
||||
|
|
|
|||
|
|
@ -66,35 +66,33 @@ describe("CLI output boundary", () => {
|
|||
it(
|
||||
"sanitizes a real missing-argument dispatcher failure",
|
||||
async () => {
|
||||
await Promise.all([
|
||||
expect(
|
||||
execFileAsync(process.execPath, ["scripts/rea.mjs", "analyze"], {
|
||||
cwd: process.cwd(),
|
||||
}),
|
||||
).rejects.toMatchObject({
|
||||
stdout:
|
||||
'code: VALIDATION_ERROR\nmessage: "REA could not read the command arguments. Run `rea --help`, correct the arguments, then try again."\n',
|
||||
await expect(
|
||||
execFileAsync(process.execPath, ["scripts/rea.mjs", "analyze"], {
|
||||
cwd: process.cwd(),
|
||||
}),
|
||||
expect(
|
||||
execFileAsync(
|
||||
process.execPath,
|
||||
["scripts/rea.mjs", "--full-output", "--json", "analyze"],
|
||||
{ cwd: process.cwd() },
|
||||
),
|
||||
).rejects.toMatchObject({
|
||||
stdout: expect.not.stringContaining("fieldErrors"),
|
||||
}),
|
||||
expect(
|
||||
execFileAsync(
|
||||
process.execPath,
|
||||
["scripts/rea.mjs", "--full-output", "analyze"],
|
||||
{ cwd: process.cwd() },
|
||||
),
|
||||
).rejects.toMatchObject({
|
||||
stdout:
|
||||
'ok: false\nerror:\n code: VALIDATION_ERROR\n message: "REA could not read the command arguments. Run `rea --help`, correct the arguments, then try again."\n',
|
||||
}),
|
||||
]);
|
||||
).rejects.toMatchObject({
|
||||
stdout:
|
||||
'code: VALIDATION_ERROR\nmessage: "REA could not read the command arguments. Run `rea --help`, correct the arguments, then try again."\n',
|
||||
});
|
||||
await expect(
|
||||
execFileAsync(
|
||||
process.execPath,
|
||||
["scripts/rea.mjs", "--full-output", "--json", "analyze"],
|
||||
{ cwd: process.cwd() },
|
||||
),
|
||||
).rejects.toMatchObject({
|
||||
stdout: expect.not.stringContaining("fieldErrors"),
|
||||
});
|
||||
await expect(
|
||||
execFileAsync(
|
||||
process.execPath,
|
||||
["scripts/rea.mjs", "--full-output", "analyze"],
|
||||
{ cwd: process.cwd() },
|
||||
),
|
||||
).rejects.toMatchObject({
|
||||
stdout:
|
||||
'ok: false\nerror:\n code: VALIDATION_ERROR\n message: "REA could not read the command arguments. Run `rea --help`, correct the arguments, then try again."\n',
|
||||
});
|
||||
},
|
||||
CLI_INTEGRATION_TIMEOUT_MS,
|
||||
);
|
||||
|
|
@ -110,24 +108,22 @@ describe("CLI output boundary", () => {
|
|||
await createPackageWithOptions(source, archive, { unpack: "*.js" });
|
||||
await writeFile(join(`${archive}.unpacked`, "main.js"), "changed();\n");
|
||||
|
||||
await Promise.all(
|
||||
[["--json"], ["--full-output", "--json"]].map(async (flags) => {
|
||||
const execution = execFileAsync(process.execPath, [
|
||||
"scripts/rea.mjs",
|
||||
...flags,
|
||||
"inventory-artifact",
|
||||
archive,
|
||||
]);
|
||||
const failure = await execution.catch((cause: unknown) => cause);
|
||||
expect(failure).toMatchObject({ code: 1 });
|
||||
const { stdout } = failure as { readonly stdout: string };
|
||||
const output = JSON.stringify(JSON.parse(stdout) as unknown);
|
||||
expect(output).toContain('"logical_path":"main.js"');
|
||||
expect(output).toMatch(/"declared_sha256":"[a-f0-9]{64}"/u);
|
||||
expect(output).toMatch(/"calculated_sha256":"[a-f0-9]{64}"/u);
|
||||
expect(output).toContain('"unpacked":true');
|
||||
}),
|
||||
);
|
||||
for (const flags of [["--json"], ["--full-output", "--json"]]) {
|
||||
const execution = execFileAsync(process.execPath, [
|
||||
"scripts/rea.mjs",
|
||||
...flags,
|
||||
"inventory-artifact",
|
||||
archive,
|
||||
]);
|
||||
const failure = await execution.catch((cause: unknown) => cause);
|
||||
expect(failure).toMatchObject({ code: 1 });
|
||||
const { stdout } = failure as { readonly stdout: string };
|
||||
const output = JSON.stringify(JSON.parse(stdout) as unknown);
|
||||
expect(output).toContain('"logical_path":"main.js"');
|
||||
expect(output).toMatch(/"declared_sha256":"[a-f0-9]{64}"/u);
|
||||
expect(output).toMatch(/"calculated_sha256":"[a-f0-9]{64}"/u);
|
||||
expect(output).toContain('"unpacked":true');
|
||||
}
|
||||
},
|
||||
CLI_INTEGRATION_TIMEOUT_MS,
|
||||
);
|
||||
|
|
@ -147,24 +143,18 @@ describe("CLI output boundary", () => {
|
|||
["--token-count", "--json"],
|
||||
];
|
||||
|
||||
for (let index = 0; index < variants.length; index += 2)
|
||||
await Promise.all(
|
||||
variants.slice(index, index + 2).map(async (flags) => {
|
||||
await expect(
|
||||
execFileAsync(process.execPath, [
|
||||
"scripts/rea.mjs",
|
||||
...flags,
|
||||
"investigate-versions",
|
||||
"/tmp/left",
|
||||
"/tmp/right",
|
||||
"/tmp/workspace.json",
|
||||
]),
|
||||
).rejects.toMatchObject({
|
||||
code: 1,
|
||||
stdout: expect.any(String),
|
||||
});
|
||||
}),
|
||||
);
|
||||
for (const flags of variants) {
|
||||
await expect(
|
||||
execFileAsync(process.execPath, [
|
||||
"scripts/rea.mjs",
|
||||
...flags,
|
||||
"investigate-versions",
|
||||
"/tmp/left",
|
||||
"/tmp/right",
|
||||
"/tmp/workspace.json",
|
||||
]),
|
||||
).rejects.toMatchObject({ code: 1, stdout: expect.any(String) });
|
||||
}
|
||||
},
|
||||
CLI_INTEGRATION_TIMEOUT_MS,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,12 @@ import { defineConfig } from "vitest/config";
|
|||
|
||||
const TEST_FILES = ["tests/**/*.test.ts"];
|
||||
const PROCESS_CAPTURE_TEST = "tests/processCapture.test.ts";
|
||||
const SERIAL_INTEGRATION_TESTS = [
|
||||
"tests/browserCli.test.ts",
|
||||
"tests/cliOutput.test.ts",
|
||||
PROCESS_CAPTURE_TEST,
|
||||
"tests/runtime.test.ts",
|
||||
];
|
||||
const dualCoreProjects =
|
||||
availableParallelism() === 2
|
||||
? {
|
||||
|
|
@ -13,13 +19,13 @@ const dualCoreProjects =
|
|||
test: {
|
||||
name: "parallel",
|
||||
include: TEST_FILES,
|
||||
exclude: [PROCESS_CAPTURE_TEST],
|
||||
exclude: SERIAL_INTEGRATION_TESTS,
|
||||
},
|
||||
},
|
||||
{
|
||||
test: {
|
||||
name: "process-capture",
|
||||
include: [PROCESS_CAPTURE_TEST],
|
||||
name: "serial-integration",
|
||||
include: SERIAL_INTEGRATION_TESTS,
|
||||
fileParallelism: false,
|
||||
},
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue