Files
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

79 lines
2.3 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type { BrowserNodeWebviewTag } from "@tutti-os/browser-node/react";
import {
cancelBrowserElementWebviewSelection,
executeBrowserElementWebviewScript,
isBrowserElementWebviewReady,
waitForBrowserElementWebviewReady
} from "./browserElementWebview.ts";
class MockBrowserElementWebview extends EventTarget {
isConnected = true;
ready = false;
executedScripts: string[] = [];
executeJavaScript<T>(script: string): Promise<T> {
this.executedScripts.push(script);
return Promise.resolve("selected" as T);
}
getWebContentsId(): number {
if (!this.ready) {
throw new Error(
"The WebView must be attached to the DOM and the dom-ready event emitted"
);
}
return 42;
}
}
function asBrowserWebview(
webview: MockBrowserElementWebview
): BrowserNodeWebviewTag {
return webview as unknown as BrowserNodeWebviewTag;
}
describe("browser element webview", () => {
it("waits for the active webview dom-ready event before execution", async () => {
const mock = new MockBrowserElementWebview();
const webview = asBrowserWebview(mock);
const execution = executeBrowserElementWebviewScript<string>(
webview,
"select()",
true
);
expect(mock.executedScripts).toEqual([]);
mock.ready = true;
mock.dispatchEvent(new Event("dom-ready"));
expect(await execution).toBe("selected");
expect(mock.executedScripts).toEqual(["select()"]);
});
it("fails detached webview readiness without executing", async () => {
const mock = new MockBrowserElementWebview();
mock.isConnected = false;
const webview = asBrowserWebview(mock);
expect(isBrowserElementWebviewReady(webview)).toBe(false);
expect(await waitForBrowserElementWebviewReady(webview, 1)).toBe(false);
await expect(
executeBrowserElementWebviewScript(webview, "select()")
).rejects.toThrow(/not ready/u);
expect(mock.executedScripts).toEqual([]);
});
it("ignores a webview detached during cancellation cleanup", async () => {
const mock = new MockBrowserElementWebview();
mock.isConnected = false;
await cancelBrowserElementWebviewSelection(
asBrowserWebview(mock),
"cancel()"
);
expect(mock.executedScripts).toEqual([]);
});
});