Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c9320992c5 | ||
|
|
05ba40e3cb |
@@ -59,13 +59,18 @@ const registerWebMcp = (
|
|||||||
run: ({ args, options }) =>
|
run: ({ args, options }) =>
|
||||||
logCliCommand(logger, "discover-webmcp-tools", async () => {
|
logCliCommand(logger, "discover-webmcp-tools", async () => {
|
||||||
const context = browserContext();
|
const context = browserContext();
|
||||||
const parsed = discoverWebMcpToolsInputSchema.safeParse({
|
const input = {
|
||||||
cdp_endpoint: args.endpoint,
|
cdp_endpoint: args.endpoint,
|
||||||
allowed_origins: options.allowedOrigins,
|
allowed_origins: options.allowedOrigins,
|
||||||
target_id: args.targetId,
|
target_id: args.targetId,
|
||||||
observation_ms: options.observationMs,
|
observation_ms: options.observationMs,
|
||||||
});
|
};
|
||||||
if (!parsed.success) return inputError("discover_webmcp_tools");
|
const parsed = discoverWebMcpToolsInputSchema.safeParse(input);
|
||||||
|
if (!parsed.success)
|
||||||
|
return inputError(
|
||||||
|
"discover_webmcp_tools",
|
||||||
|
projectInputIssues(parsed.error.issues, input),
|
||||||
|
);
|
||||||
const result = await discoverWebMcpTools(context.provider, parsed.data);
|
const result = await discoverWebMcpTools(context.provider, parsed.data);
|
||||||
return result.ok ? result.value : browserCliError(result.error);
|
return result.ok ? result.value : browserCliError(result.error);
|
||||||
}),
|
}),
|
||||||
@@ -113,7 +118,11 @@ const registerCaptureDiff = (
|
|||||||
const parsed = scenarioComparison.success
|
const parsed = scenarioComparison.success
|
||||||
? scenarioComparison
|
? scenarioComparison
|
||||||
: browserCaptureComparisonInputSchema.safeParse({ before, after });
|
: browserCaptureComparisonInputSchema.safeParse({ before, after });
|
||||||
if (!parsed.success) return inputError("compare_web_captures");
|
if (!parsed.success)
|
||||||
|
return inputError(
|
||||||
|
"compare_web_captures",
|
||||||
|
projectInputIssues(parsed.error.issues, { before, after }),
|
||||||
|
);
|
||||||
const result = await compareWebCaptureEvidence(
|
const result = await compareWebCaptureEvidence(
|
||||||
new CdpBrowserProvider(),
|
new CdpBrowserProvider(),
|
||||||
parsed.data,
|
parsed.data,
|
||||||
@@ -140,12 +149,17 @@ const registerScreenshot = (
|
|||||||
run: ({ args, options }) =>
|
run: ({ args, options }) =>
|
||||||
logCliCommand(logger, "capture-web-screenshot", async () => {
|
logCliCommand(logger, "capture-web-screenshot", async () => {
|
||||||
const context = browserContext();
|
const context = browserContext();
|
||||||
const parsed = captureWebScreenshotInputSchema.safeParse({
|
const input = {
|
||||||
cdp_endpoint: args.endpoint,
|
cdp_endpoint: args.endpoint,
|
||||||
allowed_origins: options.allowedOrigins,
|
allowed_origins: options.allowedOrigins,
|
||||||
target_id: args.targetId,
|
target_id: args.targetId,
|
||||||
});
|
};
|
||||||
if (!parsed.success) return inputError("capture_web_screenshot");
|
const parsed = captureWebScreenshotInputSchema.safeParse(input);
|
||||||
|
if (!parsed.success)
|
||||||
|
return inputError(
|
||||||
|
"capture_web_screenshot",
|
||||||
|
projectInputIssues(parsed.error.issues, input),
|
||||||
|
);
|
||||||
const result = await captureWebScreenshot(
|
const result = await captureWebScreenshot(
|
||||||
context.provider,
|
context.provider,
|
||||||
parsed.data,
|
parsed.data,
|
||||||
|
|||||||
+39
-13
@@ -14,7 +14,7 @@ import {
|
|||||||
} from "../domain/browserObservation.js";
|
} from "../domain/browserObservation.js";
|
||||||
import { analyzeWebBundleInputSchema } from "../domain/webBundleAnalysis.js";
|
import { analyzeWebBundleInputSchema } from "../domain/webBundleAnalysis.js";
|
||||||
import { observeWebSessionInputSchema } from "../domain/browserSession.js";
|
import { observeWebSessionInputSchema } from "../domain/browserSession.js";
|
||||||
import { AnalysisInputError } from "../domain/analysisErrorCore.js";
|
import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js";
|
||||||
import type { Logger } from "pino";
|
import type { Logger } from "pino";
|
||||||
import { CLI_COMMANDS } from "../cliCommandNames.js";
|
import { CLI_COMMANDS } from "../cliCommandNames.js";
|
||||||
import {
|
import {
|
||||||
@@ -48,13 +48,18 @@ const registerTargetList = (
|
|||||||
run: ({ args, options }) =>
|
run: ({ args, options }) =>
|
||||||
logCliCommand(logger, "list-browser-targets", async () => {
|
logCliCommand(logger, "list-browser-targets", async () => {
|
||||||
const context = browserContext();
|
const context = browserContext();
|
||||||
const parsed = listBrowserTargetsInputSchema.safeParse({
|
const input = {
|
||||||
cdp_endpoint: args.endpoint,
|
cdp_endpoint: args.endpoint,
|
||||||
allowed_origins: options.allowedOrigins,
|
allowed_origins: options.allowedOrigins,
|
||||||
});
|
};
|
||||||
|
const parsed = listBrowserTargetsInputSchema.safeParse(input);
|
||||||
if (!parsed.success)
|
if (!parsed.success)
|
||||||
return browserCliError(
|
return browserCliError(
|
||||||
new AnalysisInputError("list_browser_targets"),
|
analysisInputErrorFromIssues(
|
||||||
|
"list_browser_targets",
|
||||||
|
parsed.error.issues,
|
||||||
|
input,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
const result = await listBrowserTargets(context.provider, parsed.data);
|
const result = await listBrowserTargets(context.provider, parsed.data);
|
||||||
return result.ok ? result.value : browserCliError(result.error);
|
return result.ok ? result.value : browserCliError(result.error);
|
||||||
@@ -77,7 +82,7 @@ const registerPageInspection = (
|
|||||||
run: ({ args, options }) =>
|
run: ({ args, options }) =>
|
||||||
logCliCommand(logger, "inspect-web-page", async () => {
|
logCliCommand(logger, "inspect-web-page", async () => {
|
||||||
const context = browserContext();
|
const context = browserContext();
|
||||||
const parsed = inspectWebPageInputSchema.safeParse({
|
const input = {
|
||||||
cdp_endpoint: args.endpoint,
|
cdp_endpoint: args.endpoint,
|
||||||
allowed_origins: options.allowedOrigins,
|
allowed_origins: options.allowedOrigins,
|
||||||
target_id: args.targetId,
|
target_id: args.targetId,
|
||||||
@@ -89,9 +94,16 @@ const registerPageInspection = (
|
|||||||
include_script_sources: options.includeScriptSources,
|
include_script_sources: options.includeScriptSources,
|
||||||
include_storage_keys: options.includeStorageKeys,
|
include_storage_keys: options.includeStorageKeys,
|
||||||
include_storage_fingerprints: options.includeStorageFingerprints,
|
include_storage_fingerprints: options.includeStorageFingerprints,
|
||||||
});
|
};
|
||||||
|
const parsed = inspectWebPageInputSchema.safeParse(input);
|
||||||
if (!parsed.success)
|
if (!parsed.success)
|
||||||
return browserCliError(new AnalysisInputError("inspect_web_page"));
|
return browserCliError(
|
||||||
|
analysisInputErrorFromIssues(
|
||||||
|
"inspect_web_page",
|
||||||
|
parsed.error.issues,
|
||||||
|
input,
|
||||||
|
),
|
||||||
|
);
|
||||||
const result = await inspectWebPage(context.provider, parsed.data);
|
const result = await inspectWebPage(context.provider, parsed.data);
|
||||||
return result.ok ? result.value : browserCliError(result.error);
|
return result.ok ? result.value : browserCliError(result.error);
|
||||||
}),
|
}),
|
||||||
@@ -120,16 +132,23 @@ const registerBundleAnalysis = (
|
|||||||
run: ({ args, options }) =>
|
run: ({ args, options }) =>
|
||||||
logCliCommand(logger, "analyze-web-bundle", async () => {
|
logCliCommand(logger, "analyze-web-bundle", async () => {
|
||||||
const context = browserContext();
|
const context = browserContext();
|
||||||
const parsed = analyzeWebBundleInputSchema.safeParse({
|
const input = {
|
||||||
cdp_endpoint: args.endpoint,
|
cdp_endpoint: args.endpoint,
|
||||||
allowed_origins: options.allowedOrigins,
|
allowed_origins: options.allowedOrigins,
|
||||||
target_id: args.targetId,
|
target_id: args.targetId,
|
||||||
observation_ms: options.observationMs,
|
observation_ms: options.observationMs,
|
||||||
include_script_sources: true,
|
include_script_sources: true,
|
||||||
fetch_source_maps: options.fetchSourceMaps,
|
fetch_source_maps: options.fetchSourceMaps,
|
||||||
});
|
};
|
||||||
|
const parsed = analyzeWebBundleInputSchema.safeParse(input);
|
||||||
if (!parsed.success)
|
if (!parsed.success)
|
||||||
return browserCliError(new AnalysisInputError("analyze_web_bundle"));
|
return browserCliError(
|
||||||
|
analysisInputErrorFromIssues(
|
||||||
|
"analyze_web_bundle",
|
||||||
|
parsed.error.issues,
|
||||||
|
input,
|
||||||
|
),
|
||||||
|
);
|
||||||
const result = await analyzeWebBundle(context.provider, parsed.data);
|
const result = await analyzeWebBundle(context.provider, parsed.data);
|
||||||
return result.ok ? result.value : browserCliError(result.error);
|
return result.ok ? result.value : browserCliError(result.error);
|
||||||
}),
|
}),
|
||||||
@@ -153,14 +172,21 @@ const registerObservationSession = (
|
|||||||
run: ({ args, options }) =>
|
run: ({ args, options }) =>
|
||||||
logCliCommand(logger, "observe-web-session", async () => {
|
logCliCommand(logger, "observe-web-session", async () => {
|
||||||
const context = browserContext();
|
const context = browserContext();
|
||||||
const parsed = observeWebSessionInputSchema.safeParse({
|
const input = {
|
||||||
cdp_endpoint: args.endpoint,
|
cdp_endpoint: args.endpoint,
|
||||||
allowed_origins: options.allowedOrigins,
|
allowed_origins: options.allowedOrigins,
|
||||||
target_id: args.targetId,
|
target_id: args.targetId,
|
||||||
observation_ms: options.observationMs,
|
observation_ms: options.observationMs,
|
||||||
});
|
};
|
||||||
|
const parsed = observeWebSessionInputSchema.safeParse(input);
|
||||||
if (!parsed.success)
|
if (!parsed.success)
|
||||||
return browserCliError(new AnalysisInputError("observe_web_session"));
|
return browserCliError(
|
||||||
|
analysisInputErrorFromIssues(
|
||||||
|
"observe_web_session",
|
||||||
|
parsed.error.issues,
|
||||||
|
input,
|
||||||
|
),
|
||||||
|
);
|
||||||
const result = await observeWebSession(context.provider, parsed.data);
|
const result = await observeWebSession(context.provider, parsed.data);
|
||||||
return result.ok ? result.value : browserCliError(result.error);
|
return result.ok ? result.value : browserCliError(result.error);
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
listJavaScriptRuntimeTargetsInputSchema,
|
listJavaScriptRuntimeTargetsInputSchema,
|
||||||
observeJavaScriptRuntimeInputSchema,
|
observeJavaScriptRuntimeInputSchema,
|
||||||
} from "./domain/javascript/javascriptRuntimeObservation.js";
|
} from "./domain/javascript/javascriptRuntimeObservation.js";
|
||||||
import { AnalysisInputError } from "./domain/analysisErrorCore.js";
|
import { analysisInputErrorFromIssues } from "./domain/inputIssueProjection.js";
|
||||||
import { projectAnalysisError } from "./domain/analysisErrorProjection.js";
|
import { projectAnalysisError } from "./domain/analysisErrorProjection.js";
|
||||||
import type { JsonValue } from "./domain/jsonValue.js";
|
import type { JsonValue } from "./domain/jsonValue.js";
|
||||||
import type { Logger } from "pino";
|
import type { Logger } from "pino";
|
||||||
@@ -47,11 +47,19 @@ export const registerJavaScriptRuntimeObservationCommands = (
|
|||||||
CLI_COMMANDS.listJavaScriptRuntimeTargets,
|
CLI_COMMANDS.listJavaScriptRuntimeTargets,
|
||||||
async () => {
|
async () => {
|
||||||
const context = runtimeContext();
|
const context = runtimeContext();
|
||||||
const parsed = listJavaScriptRuntimeTargetsInputSchema.safeParse({
|
const input = {
|
||||||
inspector_endpoint: args.endpoint,
|
inspector_endpoint: args.endpoint,
|
||||||
});
|
};
|
||||||
|
const parsed =
|
||||||
|
listJavaScriptRuntimeTargetsInputSchema.safeParse(input);
|
||||||
if (!parsed.success)
|
if (!parsed.success)
|
||||||
return inputError("list_javascript_runtime_targets");
|
return cliError(
|
||||||
|
analysisInputErrorFromIssues(
|
||||||
|
"list_javascript_runtime_targets",
|
||||||
|
parsed.error.issues,
|
||||||
|
input,
|
||||||
|
),
|
||||||
|
);
|
||||||
const result = await listJavaScriptRuntimeTargets(
|
const result = await listJavaScriptRuntimeTargets(
|
||||||
context.provider,
|
context.provider,
|
||||||
parsed.data,
|
parsed.data,
|
||||||
@@ -73,13 +81,21 @@ export const registerJavaScriptRuntimeObservationCommands = (
|
|||||||
run: ({ args, options }) =>
|
run: ({ args, options }) =>
|
||||||
logCliCommand(logger, CLI_COMMANDS.observeJavaScriptRuntime, async () => {
|
logCliCommand(logger, CLI_COMMANDS.observeJavaScriptRuntime, async () => {
|
||||||
const context = runtimeContext();
|
const context = runtimeContext();
|
||||||
const parsed = observeJavaScriptRuntimeInputSchema.safeParse({
|
const input = {
|
||||||
inspector_endpoint: args.endpoint,
|
inspector_endpoint: args.endpoint,
|
||||||
target_id: args.targetId,
|
target_id: args.targetId,
|
||||||
runtime_kind: options.runtimeKind,
|
runtime_kind: options.runtimeKind,
|
||||||
observation_ms: options.observationMs,
|
observation_ms: options.observationMs,
|
||||||
});
|
};
|
||||||
if (!parsed.success) return inputError("observe_javascript_runtime");
|
const parsed = observeJavaScriptRuntimeInputSchema.safeParse(input);
|
||||||
|
if (!parsed.success)
|
||||||
|
return cliError(
|
||||||
|
analysisInputErrorFromIssues(
|
||||||
|
"observe_javascript_runtime",
|
||||||
|
parsed.error.issues,
|
||||||
|
input,
|
||||||
|
),
|
||||||
|
);
|
||||||
const result = await observeJavaScriptRuntime(
|
const result = await observeJavaScriptRuntime(
|
||||||
context.provider,
|
context.provider,
|
||||||
parsed.data,
|
parsed.data,
|
||||||
@@ -93,9 +109,6 @@ const runtimeContext = () => ({
|
|||||||
provider: createJavaScriptRuntimeObservationProvider(),
|
provider: createJavaScriptRuntimeObservationProvider(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const inputError = (operation: string): JsonValue =>
|
|
||||||
cliError(new AnalysisInputError(operation));
|
|
||||||
|
|
||||||
const cliError = (
|
const cliError = (
|
||||||
error: Parameters<typeof projectAnalysisError>[0],
|
error: Parameters<typeof projectAnalysisError>[0],
|
||||||
): JsonValue => ({
|
): JsonValue => ({
|
||||||
|
|||||||
@@ -0,0 +1,225 @@
|
|||||||
|
import { describe, expect } from "vitest";
|
||||||
|
|
||||||
|
import { workspaceCliTest as cliTest } from "../../support/cli/workspaceCliFixture.js";
|
||||||
|
|
||||||
|
const malformedEndpoint = "not a url";
|
||||||
|
const browserEndpoint = "http://127.0.0.1:9222";
|
||||||
|
const inspectorEndpoint = "http://127.0.0.1:9229";
|
||||||
|
|
||||||
|
const invalidInputs = [
|
||||||
|
{
|
||||||
|
command: "list-browser-targets",
|
||||||
|
arguments: [malformedEndpoint],
|
||||||
|
operation: "list_browser_targets",
|
||||||
|
error: "Browser observation failed",
|
||||||
|
issue: {
|
||||||
|
path: ["cdp_endpoint"],
|
||||||
|
reason: "invalid_value",
|
||||||
|
message: "Invalid CDP endpoint URL",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
command: "inspect-web-page",
|
||||||
|
arguments: [browserEndpoint, ""],
|
||||||
|
operation: "inspect_web_page",
|
||||||
|
error: "Browser observation failed",
|
||||||
|
issue: { path: ["target_id"], reason: "out_of_range", minimum: 1 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
command: "analyze-web-bundle",
|
||||||
|
arguments: [malformedEndpoint, "target"],
|
||||||
|
operation: "analyze_web_bundle",
|
||||||
|
error: "Browser observation failed",
|
||||||
|
issue: {
|
||||||
|
path: ["cdp_endpoint"],
|
||||||
|
reason: "invalid_value",
|
||||||
|
message: "Invalid CDP endpoint URL",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
command: "observe-web-session",
|
||||||
|
arguments: [browserEndpoint, ""],
|
||||||
|
operation: "observe_web_session",
|
||||||
|
error: "Browser observation failed",
|
||||||
|
issue: { path: ["target_id"], reason: "out_of_range", minimum: 1 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
command: "list-javascript-runtime-targets",
|
||||||
|
arguments: [""],
|
||||||
|
operation: "list_javascript_runtime_targets",
|
||||||
|
error: "JavaScript runtime observation failed",
|
||||||
|
issue: {
|
||||||
|
path: ["inspector_endpoint"],
|
||||||
|
reason: "out_of_range",
|
||||||
|
minimum: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
command: "observe-javascript-runtime",
|
||||||
|
arguments: [inspectorEndpoint, ""],
|
||||||
|
operation: "observe_javascript_runtime",
|
||||||
|
error: "JavaScript runtime observation failed",
|
||||||
|
issue: { path: ["target_id"], reason: "out_of_range", minimum: 1 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
command: "discover-webmcp-tools",
|
||||||
|
arguments: [malformedEndpoint, "target"],
|
||||||
|
operation: "discover_webmcp_tools",
|
||||||
|
error: "Browser observation failed",
|
||||||
|
issue: {
|
||||||
|
path: ["cdp_endpoint"],
|
||||||
|
reason: "invalid_value",
|
||||||
|
message: "Invalid CDP endpoint URL",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
command: "capture-web-screenshot",
|
||||||
|
arguments: [browserEndpoint, ""],
|
||||||
|
operation: "capture_web_screenshot",
|
||||||
|
error: "Browser observation failed",
|
||||||
|
issue: { path: ["target_id"], reason: "out_of_range", minimum: 1 },
|
||||||
|
},
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
describe("browser and Inspector CLI input diagnostics", () => {
|
||||||
|
cliTest.for(invalidInputs)(
|
||||||
|
"$command retains the named contract's correction details",
|
||||||
|
async (input, { cli, workspace }) => {
|
||||||
|
const result = await cli.run({
|
||||||
|
arguments: [input.command, ...input.arguments, "--json"],
|
||||||
|
cwd: workspace.root,
|
||||||
|
environment: { ...workspace.environment, REA_LOG_LEVEL: "silent" },
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.exitCode).toBe(1);
|
||||||
|
expect(result.json).toMatchObject({
|
||||||
|
error: input.error,
|
||||||
|
code: "invalid_request",
|
||||||
|
category: "invalid_input",
|
||||||
|
message:
|
||||||
|
"Analysis input is invalid. Check the arguments and try again.",
|
||||||
|
retryable: true,
|
||||||
|
remediation: { action: "Correct the listed arguments and retry." },
|
||||||
|
details: {
|
||||||
|
operation: input.operation,
|
||||||
|
issues: expect.arrayContaining([input.issue]),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(result.stdout).not.toContain(malformedEndpoint);
|
||||||
|
expect(result.stderr).not.toContain(malformedEndpoint);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
cliTest.for([
|
||||||
|
["list-browser-targets", "cdp_endpoint"],
|
||||||
|
["list-javascript-runtime-targets", "inspector_endpoint"],
|
||||||
|
] as const)(
|
||||||
|
"%s does not echo rejected endpoint credentials",
|
||||||
|
async ([command, field], { cli, workspace }) => {
|
||||||
|
const endpoint =
|
||||||
|
"http://rea-diagnostic-user:rea-diagnostic-secret@127.0.0.1:9222/";
|
||||||
|
const result = await cli.run({
|
||||||
|
arguments: [command, endpoint, "--json"],
|
||||||
|
cwd: workspace.root,
|
||||||
|
environment: { ...workspace.environment, REA_LOG_LEVEL: "debug" },
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.exitCode).toBe(1);
|
||||||
|
expect(result.json).toMatchObject({
|
||||||
|
code: "invalid_request",
|
||||||
|
details: {
|
||||||
|
issues: [
|
||||||
|
{
|
||||||
|
path: [field],
|
||||||
|
reason: "invalid_value",
|
||||||
|
message:
|
||||||
|
"CDP endpoint must be an explicit-port HTTP URL on 127.0.0.1 or ::1",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const output = result.stdout + result.stderr;
|
||||||
|
expect(output).not.toContain(endpoint);
|
||||||
|
expect(output).not.toContain("rea-diagnostic-user");
|
||||||
|
expect(output).not.toContain("rea-diagnostic-secret");
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
cliTest(
|
||||||
|
"retains authored cross-field correction guidance",
|
||||||
|
async ({ cli, workspace }) => {
|
||||||
|
const result = await cli.run({
|
||||||
|
arguments: [
|
||||||
|
"inspect-web-page",
|
||||||
|
browserEndpoint,
|
||||||
|
"target",
|
||||||
|
"--include-storage-fingerprints",
|
||||||
|
"--json",
|
||||||
|
],
|
||||||
|
cwd: workspace.root,
|
||||||
|
environment: { ...workspace.environment, REA_LOG_LEVEL: "silent" },
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.exitCode).toBe(1);
|
||||||
|
expect(result.json).toMatchObject({
|
||||||
|
code: "invalid_request",
|
||||||
|
details: {
|
||||||
|
operation: "inspect_web_page",
|
||||||
|
issues: expect.arrayContaining([
|
||||||
|
{
|
||||||
|
path: ["include_storage_fingerprints"],
|
||||||
|
reason: "invalid_value",
|
||||||
|
message: "Storage fingerprints require storage key capture",
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
cliTest(
|
||||||
|
"retains correction details for invalid capture comparison inputs",
|
||||||
|
async ({ cli, workspace }) => {
|
||||||
|
const result = await cli.run({
|
||||||
|
arguments: ["compare-web-captures", "{}", "{}", "--json"],
|
||||||
|
cwd: workspace.root,
|
||||||
|
environment: { ...workspace.environment, REA_LOG_LEVEL: "silent" },
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.exitCode).toBe(1);
|
||||||
|
expect(result.json).toMatchObject({
|
||||||
|
code: "invalid_request",
|
||||||
|
details: {
|
||||||
|
operation: "compare_web_captures",
|
||||||
|
issues: expect.arrayContaining([
|
||||||
|
expect.objectContaining({ reason: expect.any(String) }),
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
cliTest(
|
||||||
|
"preserves the parser diagnostic for an omitted endpoint",
|
||||||
|
async ({ cli, workspace }) => {
|
||||||
|
const result = await cli.run({
|
||||||
|
arguments: ["list-browser-targets", "--json"],
|
||||||
|
cwd: workspace.root,
|
||||||
|
environment: { ...workspace.environment, REA_LOG_LEVEL: "silent" },
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.exitCode).toBe(1);
|
||||||
|
expect(result.json).toMatchObject({
|
||||||
|
code: "VALIDATION_ERROR",
|
||||||
|
fieldErrors: [
|
||||||
|
{
|
||||||
|
path: "endpoint",
|
||||||
|
code: "invalid_type",
|
||||||
|
missing: true,
|
||||||
|
expected: "string",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user