




















@@ -2176,6 +2176,102 @@ describe("google-meet plugin", () => {
21762176expect(result.manualActionMessage).toContain("Allow microphone/camera/speaker permissions");
21772177});
217821782179+it("uses the local Meet microphone control instead of remote participant mute buttons", () => {
2180+const makeButton = (label: string, disabled = false) => ({
2181+ disabled,
2182+innerText: "",
2183+textContent: "",
2184+click: vi.fn(),
2185+getAttribute: vi.fn((name: string) => (name === "aria-label" ? label : null)),
2186+});
2187+const remoteMute = makeButton("You can't remotely mute Peter Steinberger's microphone", true);
2188+const localMic = makeButton("Turn on microphone");
2189+const document = {
2190+body: { innerText: "", textContent: "" },
2191+title: "Meet",
2192+querySelector: vi.fn(() => null),
2193+querySelectorAll: vi.fn((selector: string) => {
2194+if (selector === "button") {
2195+return [makeButton("Leave call"), remoteMute, localMic];
2196+}
2197+if (selector === "input") {
2198+return [];
2199+}
2200+return [];
2201+}),
2202+};
2203+const context = createContext({
2204+JSON,
2205+ document,
2206+location: {
2207+href: "https://meet.google.com/abc-defg-hij",
2208+hostname: "meet.google.com",
2209+},
2210+window: {},
2211+});
2212+const inspect = new Script(
2213+`(${chromeTransportTesting.meetStatusScriptForTest({
2214+ allowMicrophone: true,
2215+ autoJoin: false,
2216+ captureCaptions: false,
2217+ guestName: "OpenClaw Agent",
2218+ })})`,
2219+).runInContext(context) as () => string;
2220+2221+const result = JSON.parse(inspect()) as { micMuted?: boolean; notes?: string[] };
2222+2223+expect(result.micMuted).toBe(true);
2224+expect(localMic.click).toHaveBeenCalledTimes(1);
2225+expect(remoteMute.click).not.toHaveBeenCalled();
2226+expect(result.notes).toContain("Attempted to turn on the Meet microphone for realtime mode.");
2227+});
2228+2229+it("blocks realtime speech while the Meet microphone remains muted", async () => {
2230+const originalPlatform = process.platform;
2231+Object.defineProperty(process, "platform", { value: "darwin" });
2232+try {
2233+mockLocalMeetBrowserRequest({
2234+inCall: true,
2235+micMuted: true,
2236+title: "Meet call",
2237+url: "https://meet.google.com/abc-defg-hij",
2238+});
2239+const { methods } = setup({
2240+chrome: {
2241+audioBridgeCommand: ["bridge", "start"],
2242+waitForInCallMs: 1,
2243+},
2244+});
2245+const handler = methods.get("googlemeet.join") as
2246+| ((ctx: {
2247+params: Record<string, unknown>;
2248+respond: ReturnType<typeof vi.fn>;
2249+}) => Promise<void>)
2250+| undefined;
2251+const respond = vi.fn();
2252+2253+await handler?.({
2254+params: { url: "https://meet.google.com/abc-defg-hij" },
2255+ respond,
2256+});
2257+2258+expect(respond.mock.calls[0]?.[1]).toMatchObject({
2259+spoken: false,
2260+session: {
2261+chrome: {
2262+health: {
2263+micMuted: true,
2264+speechReady: false,
2265+speechBlockedReason: "meet-microphone-muted",
2266+},
2267+},
2268+},
2269+});
2270+} finally {
2271+Object.defineProperty(process, "platform", { value: originalPlatform });
2272+}
2273+});
2274+21792275it("joins Chrome on a paired node without local Chrome or BlackHole", async () => {
21802276const { methods, nodesList, nodesInvoke } = setup(
21812277{
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。