Files
openclaw/extensions/browser/src/browser-tool-binding.test.ts
Peter Steinberger ec8f6e5e03 feat(browser): add secure per-tab copilot panel (#109817)
* feat(browser): add copilot security contracts

* fix(gateway): expose verified client identity to handlers

* feat(browser): add secure per-tab copilot panel

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* refactor(browser): separate copilot gateway hint custody

* fix(browser): preserve legacy pairing parse shape

* fix(browser): harden copilot lifecycle custody

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* fix(browser): enforce copilot lifecycle boundaries

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* style(browser): format copilot sources

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* fix(browser): preserve copilot consent revocation

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* refactor(browser): split copilot custody owners

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* test(browser): normalize websocket array buffers

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* chore(protocol): regenerate Swift gateway models

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* refactor(browser): model copilot runtime entrypoints

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* fix(browser): honor extension build boundaries

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* test(gateway): assert targeted chat delivery

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* test(gateway): cover targeted delivery calls

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* fix(browser): declare copilot build dependencies

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* fix(ci): clear browser copilot gate failures

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* test(ci): cover copilot lint exclusion

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* fix(browser): gate copilot on relay custody

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* test(browser): bound copilot relay frames

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

---------

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>
2026-07-18 01:00:23 +01:00

51 lines
1.6 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { applyBrowserTabToolBinding, parseBrowserTabToolBinding } from "./browser-tool-binding.js";
const binding = {
kind: "tab" as const,
tabId: 17,
target: "node" as const,
node: "desktop",
profile: "chrome",
targetId: "target-a",
};
describe("browser tab tool binding", () => {
it("pins route and nested act targets to the trusted tab", () => {
expect(
applyBrowserTabToolBinding(
{ action: "act", request: { kind: "batch", actions: [{ kind: "click" }] } },
binding,
),
).toMatchObject({
target: "node",
node: "desktop",
profile: "chrome",
targetId: "target-a",
request: {
targetId: "target-a",
actions: [{ kind: "click", targetId: "target-a" }],
},
});
});
it("rejects route, tab, and browser-wide action escapes", () => {
expect(() =>
applyBrowserTabToolBinding({ action: "snapshot", targetId: "target-b" }, binding),
).toThrow("cannot override its run-bound tab target");
expect(() =>
applyBrowserTabToolBinding({ action: "snapshot", node: "other" }, binding),
).toThrow("cannot override its run-bound node");
expect(() => applyBrowserTabToolBinding({ action: "open" }, binding)).toThrow(
"unavailable in a tab-bound run",
);
});
it("fails closed on malformed bindings", () => {
expect(parseBrowserTabToolBinding({ kind: "tab", tabId: 1, target: "host" })).toEqual({
ok: false,
error: "browser tool binding requires target, profile, and targetId",
});
});
});