54 lines
1.8 KiB
TypeScript
54 lines
1.8 KiB
TypeScript
import { readFileSync } from "node:fs";
|
|
import { resolve } from "node:path";
|
|
import { expect, test } from "@playwright/test";
|
|
import {
|
|
isClawdTransportInterruption,
|
|
shouldRestoreClawdComposerAfterFailure,
|
|
} from "@/lib/openclaw-chat/request-lifecycle";
|
|
|
|
function readSource(path: string) {
|
|
return readFileSync(resolve(process.cwd(), path), "utf8");
|
|
}
|
|
|
|
test.describe("Claw request lifecycle", () => {
|
|
test("restores the composer only after an explicit user cancellation", () => {
|
|
expect(
|
|
shouldRestoreClawdComposerAfterFailure({ explicitlyCanceled: true })
|
|
).toBe(true);
|
|
expect(
|
|
shouldRestoreClawdComposerAfterFailure({ explicitlyCanceled: false })
|
|
).toBe(false);
|
|
});
|
|
|
|
test("recognizes browser and network interruptions without treating them as edits", () => {
|
|
expect(
|
|
isClawdTransportInterruption(
|
|
new DOMException("The operation was aborted", "AbortError")
|
|
)
|
|
).toBe(true);
|
|
expect(isClawdTransportInterruption(new Error("fetch failed"))).toBe(true);
|
|
expect(isClawdTransportInterruption(new Error("provider unavailable"))).toBe(
|
|
false
|
|
);
|
|
});
|
|
|
|
test("does not cancel the upstream request when the browser connection closes", () => {
|
|
const source = readSource("app/api/canvas/clawd-chat/route.ts");
|
|
|
|
expect(source).not.toContain('request.signal.addEventListener("abort"');
|
|
expect(source).not.toContain("cancelClawdRequest(cancelKey)");
|
|
expect(source).toMatch(
|
|
/registerActiveClawdRequest\(\s*(?:params\.)?cancelKey/
|
|
);
|
|
});
|
|
|
|
test("does not classify every AbortError as an explicit stop action", () => {
|
|
const source = readSource("components/canvas/CanvasChatPanel.tsx");
|
|
|
|
expect(source).toContain("shouldRestoreClawdComposerAfterFailure");
|
|
expect(source).not.toContain(
|
|
'(error instanceof Error && error.name === "AbortError")'
|
|
);
|
|
});
|
|
});
|