





















@@ -25,6 +25,7 @@ import { startNodeRealtimeAudioBridge } from "./src/realtime-node.js";
2525import { startCommandRealtimeAudioBridge } from "./src/realtime.js";
2626import { normalizeMeetUrl } from "./src/runtime.js";
2727import { noopLogger, setupGoogleMeetPlugin } from "./src/test-support/plugin-harness.js";
28+import { __testing as chromeTransportTesting } from "./src/transports/chrome.js";
2829import { buildMeetDtmfSequence, normalizeDialInNumber } from "./src/transports/twilio.js";
29303031const voiceCallMocks = vi.hoisted(() => ({
@@ -224,6 +225,7 @@ describe("google-meet plugin", () => {
224225225226afterEach(() => {
226227vi.unstubAllGlobals();
228+chromeTransportTesting.setDepsForTest(null);
227229});
228230229231it("defaults to chrome realtime with safe read-only tools", () => {
@@ -1607,6 +1609,76 @@ describe("google-meet plugin", () => {
16071609);
16081610});
160916111612+it("recovers and inspects an existing local Chrome Meet tab", async () => {
1613+const callGatewayFromCli = vi.fn(
1614+async (
1615+_method: string,
1616+_opts: unknown,
1617+params?: unknown,
1618+_extra?: unknown,
1619+): Promise<Record<string, unknown>> => {
1620+const request = params as { path?: string; body?: { targetId?: string } };
1621+if (request.path === "/tabs") {
1622+return {
1623+tabs: [
1624+{
1625+targetId: "local-meet-tab",
1626+title: "Meet",
1627+url: "https://meet.google.com/abc-defg-hij?authuser=me@example.com",
1628+},
1629+],
1630+};
1631+}
1632+if (request.path === "/tabs/focus") {
1633+return { ok: true };
1634+}
1635+if (request.path === "/act") {
1636+return {
1637+result: JSON.stringify({
1638+inCall: false,
1639+manualActionRequired: true,
1640+manualActionReason: "meet-admission-required",
1641+manualActionMessage: "Admit the OpenClaw browser participant in Google Meet.",
1642+title: "Meet",
1643+url: "https://meet.google.com/abc-defg-hij?authuser=me@example.com",
1644+}),
1645+};
1646+}
1647+throw new Error(`unexpected browser request path ${request.path}`);
1648+},
1649+);
1650+chromeTransportTesting.setDepsForTest({ callGatewayFromCli });
1651+const { tools, nodesInvoke } = setup({ defaultTransport: "chrome" });
1652+const tool = tools[0] as {
1653+execute: (
1654+id: string,
1655+params: unknown,
1656+) => Promise<{ details: { transport?: string; found?: boolean; browser?: unknown } }>;
1657+};
1658+1659+const result = await tool.execute("id", {
1660+action: "recover_current_tab",
1661+url: "https://meet.google.com/abc-defg-hij",
1662+});
1663+1664+expect(result.details).toMatchObject({
1665+transport: "chrome",
1666+found: true,
1667+targetId: "local-meet-tab",
1668+browser: {
1669+manualActionRequired: true,
1670+manualActionReason: "meet-admission-required",
1671+},
1672+});
1673+expect(callGatewayFromCli).toHaveBeenCalledWith(
1674+"browser.request",
1675+expect.any(Object),
1676+expect.objectContaining({ method: "POST", path: "/tabs/focus" }),
1677+{ progress: false },
1678+);
1679+expect(nodesInvoke).not.toHaveBeenCalled();
1680+});
1681+16101682it("exposes a test-speech action that joins the requested meeting", async () => {
16111683const { tools, nodesInvoke } = setup(
16121684{
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。