Files
rea/tests/boundary/cli/nativeUiScenarioInputCli.test.ts
T
Kaoru0822andClaude Opus 5.5 96d1f0f3fb fix(cli): refuse scenario steps on passive native UI observation (#2712)
observe-native-ui and capture-native-ui-scenario were registered in one
loop with a shared option schema and description. The passive command
therefore advertised `--steps` ("Observe or run a scenario"), accepted
any value, and then dispatched observe_native_ui without it, so a
caller who selected the wrong command never learned that no scenario ran.

Register each command against its own contract. Observation declares
only the passive scope options, so `--steps` is rejected as an unknown
flag; the scenario command keeps its JSON step decoding and validation.
Each command now has its own description.

Fixes #2674

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 06:59:33 -07:00

98 lines
2.5 KiB
TypeScript

import { describe, expect } from "vitest";
import { cliTest } from "../../support/cli/cliFixture.js";
import type { TestCli } from "../../support/cli/cliFixture.js";
const runCapture = async (cli: TestCli, steps: string | undefined) => {
const arguments_ = [
"capture-native-ui-scenario",
"/provider-must-not-be-invoked",
"--pid",
"1",
"--window-id",
"1",
];
if (steps !== undefined) arguments_.push("--steps", steps);
arguments_.push("--json");
return cli.run({
arguments: arguments_,
environment: { REA_LOG_LEVEL: "silent" },
});
};
describe("native UI scenario CLI input", () => {
cliTest(
"rejects omitted steps under the shared scenario contract",
async ({ cli }) => {
const result = await runCapture(cli, undefined);
expect(result.exitCode).not.toBe(0);
expect(result.json).toMatchObject({
code: "invalid_request",
details: {
operation: "capture_native_ui_scenario",
issues: [{ path: ["steps"], reason: "missing_argument" }],
},
});
},
);
cliTest("rejects malformed JSON as invalid input", async ({ cli }) => {
const result = await runCapture(cli, "[");
expect(result.exitCode).not.toBe(0);
expect(result.json).toMatchObject({
code: "invalid_request",
details: {
operation: "capture_native_ui_scenario",
issues: [
{
path: ["steps"],
reason: "invalid_format",
expected: "JSON",
},
],
},
});
});
cliTest(
"requires at least one schema-valid scenario step",
async ({ cli }) => {
const result = await runCapture(cli, "[]");
expect(result.exitCode).not.toBe(0);
expect(result.json).toMatchObject({
code: "invalid_request",
details: {
operation: "capture_native_ui_scenario",
issues: [{ path: ["steps"], reason: "out_of_range", minimum: 1 }],
},
});
},
);
cliTest(
"refuses scenario steps on passive observation instead of dropping them",
async ({ cli }) => {
const result = await cli.run({
arguments: [
"observe-native-ui",
"/provider-must-not-be-invoked",
"--pid",
"1",
"--window-id",
"1",
"--steps",
'[{"kind":"wait","milliseconds":0}]',
"--json",
],
environment: { REA_LOG_LEVEL: "silent" },
});
expect(result.exitCode).not.toBe(0);
expect(result.stdout).toContain("Unknown flag: --steps");
},
);
});