Contracts for browser API and browser.* agent capabilities; adapter implements close/list/restore sessions, tabs + reconcile, history, click/type/select/scroll/press, extract, waitForDownload (staged via DownloadSink, sha256), stale-ref guard and automation/human actor check. testkit mock camofox gains an interactive site (login redirect, captcha, click-driven page changes, downloads, PNG screenshots). Co-Authored-By: Claude Opus 5.5 <[email protected]>
62 lines
2.1 KiB
TypeScript
62 lines
2.1 KiB
TypeScript
import type { BrowserCapabilities, BrowserCapabilityFlag, BrowserHealth } from "@umt/contracts";
|
|
import { BROWSER_CAPABILITY_KEYS } from "@umt/contracts";
|
|
import { BrowserError } from "./errors.ts";
|
|
import type { BrowserProvider } from "./provider.ts";
|
|
|
|
const off: BrowserCapabilityFlag = { supported: false, verified: false, source: "static", note: "未配置浏览器服务" };
|
|
|
|
export function noneCapabilities(): BrowserCapabilities {
|
|
const flags = Object.fromEntries(BROWSER_CAPABILITY_KEYS.map((k) => [k, { ...off }])) as Record<
|
|
(typeof BROWSER_CAPABILITY_KEYS)[number],
|
|
BrowserCapabilityFlag
|
|
>;
|
|
return { ...flags, upstreamVersion: null, probedAt: null };
|
|
}
|
|
|
|
const unavailable = () => Promise.reject(new BrowserError("unavailable", "未配置浏览器服务"));
|
|
|
|
/**
|
|
* 默认实现:未配置浏览器服务。所有动作返回 unavailable,能力全部 false;
|
|
* 业务侧据此在界面标注"浏览器不可用",不回退到其他浏览器。
|
|
*/
|
|
export function createNoneBrowserProvider(): BrowserProvider {
|
|
return {
|
|
kind: "none",
|
|
async health(): Promise<BrowserHealth> {
|
|
return { status: "disabled", kind: "none", detail: {}, checkedAt: new Date().toISOString() };
|
|
},
|
|
async capabilities() {
|
|
return noneCapabilities();
|
|
},
|
|
openSession: unavailable,
|
|
closeSession: unavailable,
|
|
async listSessions() {
|
|
return [];
|
|
},
|
|
navigate: unavailable,
|
|
snapshot: unavailable,
|
|
screenshot: unavailable,
|
|
click: unavailable,
|
|
type: unavailable,
|
|
extract: unavailable,
|
|
waitForDownload: unavailable,
|
|
acquireControl: unavailable,
|
|
releaseControl: unavailable,
|
|
openTab: unavailable,
|
|
closeTab: unavailable,
|
|
history: unavailable,
|
|
select: unavailable,
|
|
scroll: unavailable,
|
|
press: unavailable,
|
|
setController() {
|
|
throw new BrowserError("unavailable", "未配置浏览器服务");
|
|
},
|
|
restoreSession() {
|
|
throw new BrowserError("unavailable", "未配置浏览器服务");
|
|
},
|
|
reconcileTabs: unavailable,
|
|
sessionInfo: () => null,
|
|
drain: async () => {},
|
|
};
|
|
}
|