



























@@ -288,6 +288,59 @@ describe("chrome MCP page parsing", () => {
288288expect(message).not.toContain(secretToken);
289289});
290290291+it("redacts home-relative user data dirs from attach failures", async () => {
292+const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-chrome-mcp-test-"));
293+const homeDir = os.homedir();
294+const userDataDir = path.join(
295+homeDir,
296+"Library",
297+"Application Support",
298+"Google",
299+"Chrome",
300+"Profile 1",
301+);
302+const fakeMcpCommand = path.join(tempDir, "fake-mcp.mjs");
303+await fs.writeFile(
304+fakeMcpCommand,
305+`#!/usr/bin/env node
306+ let input = "";
307+ process.stdin.on("data", (chunk) => {
308+ input += chunk;
309+ const match = input.match(/"id"\\s*:\\s*(\\d+)/);
310+ if (!match) return;
311+ const body = JSON.stringify({
312+ jsonrpc: "2.0",
313+ id: Number(match[1]),
314+ error: { code: -32000, message: "attach failed" },
315+ });
316+ process.stdout.write(body + "\\n");
317+ });
318+ `,
319+);
320+await fs.chmod(fakeMcpCommand, 0o755);
321+322+let message = "";
323+try {
324+await ensureChromeMcpAvailable(
325+"home-profile",
326+{
327+ userDataDir,
328+mcpCommand: fakeMcpCommand,
329+},
330+{ ephemeral: true },
331+);
332+} catch (err) {
333+message = err instanceof Error ? err.message : String(err);
334+} finally {
335+await fs.rm(tempDir, { recursive: true, force: true });
336+}
337+338+expect(message).toContain("Chrome MCP existing-session attach failed");
339+expect(message).toContain("~/Library/Application Support/Google/Chrome/Profile 1");
340+expect(message).not.toContain(homeDir);
341+expect(message).not.toContain(userDataDir);
342+});
343+291344it("parses new_page text responses and returns the created tab", async () => {
292345const factory: ChromeMcpSessionFactory = async () => createFakeSession();
293346setChromeMcpSessionFactoryForTest(factory);
@@ -795,6 +848,40 @@ describe("chrome MCP page parsing", () => {
795848expect(closeMock).toHaveBeenCalledTimes(1);
796849});
797850851+it("redacts home-relative profile labels from availability timeout diagnostics", async () => {
852+vi.useFakeTimers();
853+const closeMock = vi.fn().mockResolvedValue(undefined);
854+const factory: ChromeMcpSessionFactory = async () =>
855+({
856+client: {
857+callTool: vi.fn(),
858+listTools: vi.fn(),
859+close: closeMock,
860+connect: vi.fn(),
861+},
862+transport: {
863+pid: 123,
864+},
865+ready: new Promise<void>(() => {}),
866+}) as unknown as ChromeMcpSession;
867+setChromeMcpSessionFactoryForTest(factory);
868+869+const homeDir = os.homedir();
870+const profileName = path.join(homeDir, "Library", "Application Support", "Google", "Chrome");
871+const promise = ensureChromeMcpAvailable(profileName, undefined, {
872+ephemeral: true,
873+timeoutMs: 50,
874+});
875+void promise.catch(() => {});
876+877+await vi.advanceTimersByTimeAsync(50);
878+879+await expect(promise).rejects.toThrow(/timed out after 50ms/i);
880+await expect(promise).rejects.toThrow("~/Library/Application Support/Google/Chrome");
881+await expect(promise).rejects.not.toThrow(homeDir);
882+expect(closeMock).toHaveBeenCalledTimes(1);
883+});
884+798885it("honors abort signals while waiting for ephemeral availability probes", async () => {
799886const closeMock = vi.fn().mockResolvedValue(undefined);
800887const factory: ChromeMcpSessionFactory = async () =>
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。