Files
rea/tests/boundary/browser/callerCancellationReason.test.ts
T

96 lines
3.6 KiB
TypeScript

import { expect, it, vi } from "vitest";
import { WebRuntimeService } from "../../../src/application/WebRuntimeService.js";
import { CdpWebRuntimeProvider } from "../../../src/browser/execution/CdpWebRuntimeProvider.js";
import { AnalysisOutputError } from "../../../src/domain/analysisErrorCore.js";
import { startRuntimeBrowser } from "../../fixtures/webRuntime.js";
it.each([
new Error("operator stopped observation"),
new AnalysisOutputError("inspect_web_page", "caller supplied reason"),
{ requested: "stop the armed observation" },
])(
"preserves caller reason through the armed service workflow and stops instrumentation (%s)",
async (reason) => {
const browser = await startRuntimeBrowser();
const provider = new CdpWebRuntimeProvider();
const service = new WebRuntimeService(provider);
const input = {
cdp_endpoint: browser.endpoint,
target_id: "allowed-page",
observation_ms: 5,
};
try {
const before = await service.observe(input);
if (!before.ok) throw before.error;
const controller = new AbortController();
const cancelled = await service.observe(input, {
signal: controller.signal,
progress: {
report: async (update) => {
if (update.completed === 1) controller.abort(reason);
},
},
});
expect(cancelled.ok).toBe(false);
if (cancelled.ok) throw new Error("Expected cancellation at arming");
expect(cancelled.error._tag).toBe("AnalysisCancelledError");
expect(cancelled.error.cause).toBe(controller.signal.reason);
expect(cancelled.error.cause).toBe(reason);
expect(cancelled.error.cleanupIncomplete).toBe(false);
expect(
browser.commands.filter(
(command) => command.method === "Profiler.stopPreciseCoverage",
),
).toHaveLength(2);
await vi.waitFor(() => expect(browser.activeConnectionCount()).toBe(0));
const after = await service.observe(input);
if (!after.ok) throw after.error;
await vi.waitFor(() => expect(browser.activeConnectionCount()).toBe(0));
} finally {
await provider.close();
await browser.close();
}
},
);
it("preserves the caller reason when a navigation observation is cancelled at arming", async () => {
const { CdpBrowserProvider } =
await import("../../../src/browser/CdpBrowserProvider.js");
const { observeWebSession } =
await import("../../../src/application/BrowserObservationService.js");
const { observeWebSessionInputSchema } =
await import("../../../src/domain/browserSession.js");
const browser = await startRuntimeBrowser();
const provider = new CdpBrowserProvider();
const controller = new AbortController();
const reason = { requested: "stop navigation observation" };
try {
const result = await observeWebSession(
provider,
observeWebSessionInputSchema.parse({
cdp_endpoint: browser.endpoint,
allowed_origins: [browser.allowedOrigin],
target_id: "allowed-page",
observation_ms: 30_000,
}),
{
signal: controller.signal,
progress: {
report: async (update) => {
if (update.completed === 1) controller.abort(reason);
},
},
},
);
expect(result.ok).toBe(false);
if (result.ok) throw new Error("Expected cancelled navigation observation");
expect(result.error._tag).toBe("AnalysisCancelledError");
expect(result.error.cause).toBe(reason);
expect(result.error.cleanupIncomplete).toBe(false);
await vi.waitFor(() => expect(browser.activeConnectionCount()).toBe(0));
} finally {
await provider.close();
await browser.close();
}
});