mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 08:20:43 +00:00
fix(browser): tighten WS3 status probes
# Conflicts: # extensions/browser/src/browser/chrome-mcp.test.ts # extensions/browser/src/browser/chrome-mcp.ts # extensions/browser/src/browser/routes/basic.ts
This commit is contained in:
@@ -98,6 +98,7 @@ function createFakeSession(): ChromeMcpSession {
|
||||
describe("chrome MCP page parsing", () => {
|
||||
beforeEach(async () => {
|
||||
await resetChromeMcpSessionsForTest();
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -474,7 +475,6 @@ describe("chrome MCP page parsing", () => {
|
||||
expect(factoryCalls).toBe(2);
|
||||
expect(tabs).toHaveLength(2);
|
||||
});
|
||||
|
||||
it("reconnects and retries list_pages once when Chrome MCP reports a stale selected page", async () => {
|
||||
let factoryCalls = 0;
|
||||
const factory: ChromeMcpSessionFactory = async () => {
|
||||
@@ -613,4 +613,34 @@ describe("chrome MCP page parsing", () => {
|
||||
expect(factoryCalls).toBe(2);
|
||||
expect(tabs).toHaveLength(2);
|
||||
});
|
||||
|
||||
it("honors timeoutMs for ephemeral availability probes", async () => {
|
||||
vi.useFakeTimers();
|
||||
const closeMock = vi.fn().mockResolvedValue(undefined);
|
||||
const factory: ChromeMcpSessionFactory = async () =>
|
||||
({
|
||||
client: {
|
||||
callTool: vi.fn(),
|
||||
listTools: vi.fn(),
|
||||
close: closeMock,
|
||||
connect: vi.fn(),
|
||||
},
|
||||
transport: {
|
||||
pid: 123,
|
||||
},
|
||||
ready: new Promise<void>(() => {}),
|
||||
}) as unknown as ChromeMcpSession;
|
||||
setChromeMcpSessionFactoryForTest(factory);
|
||||
|
||||
const promise = ensureChromeMcpAvailable("chrome-live", undefined, {
|
||||
ephemeral: true,
|
||||
timeoutMs: 50,
|
||||
});
|
||||
const expectation = expect(promise).rejects.toThrow(/timed out after 50ms/i);
|
||||
|
||||
await vi.advanceTimersByTimeAsync(50);
|
||||
|
||||
await expectation;
|
||||
expect(closeMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -463,6 +463,37 @@ async function getExistingSession(
|
||||
}
|
||||
}
|
||||
|
||||
async function waitForChromeMcpReady(
|
||||
session: ChromeMcpSession,
|
||||
profileName: string,
|
||||
timeoutMs?: number,
|
||||
): Promise<void> {
|
||||
if (!timeoutMs || timeoutMs <= 0) {
|
||||
await session.ready;
|
||||
return;
|
||||
}
|
||||
|
||||
let timer: ReturnType<typeof setTimeout> | undefined;
|
||||
try {
|
||||
await Promise.race([
|
||||
session.ready,
|
||||
new Promise<never>((_, reject) => {
|
||||
timer = setTimeout(() => {
|
||||
reject(
|
||||
new BrowserProfileUnavailableError(
|
||||
`Chrome MCP existing-session attach for profile "${profileName}" timed out after ${timeoutMs}ms.`,
|
||||
),
|
||||
);
|
||||
}, timeoutMs);
|
||||
}),
|
||||
]);
|
||||
} finally {
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function createEphemeralSession(
|
||||
profileName: string,
|
||||
userDataDir?: string,
|
||||
|
||||
@@ -63,7 +63,7 @@ describe("basic browser routes", () => {
|
||||
it("maps existing-session status failures to JSON browser errors", async () => {
|
||||
const response = await callBasicRouteWithState({
|
||||
state: createExistingSessionProfileState({
|
||||
isHttpReachable: async () => {
|
||||
isTransportAvailable: async () => {
|
||||
throw new BrowserProfileUnavailableError("attach failed");
|
||||
},
|
||||
}),
|
||||
@@ -109,4 +109,25 @@ describe("basic browser routes", () => {
|
||||
cdpReady: true,
|
||||
});
|
||||
});
|
||||
|
||||
it("probes Chrome MCP transport only once for status", async () => {
|
||||
const isHttpReachable = vi.fn(async () => true);
|
||||
const isTransportAvailable = vi.fn(async () => true);
|
||||
|
||||
const response = await callBasicRouteWithState({
|
||||
state: createExistingSessionProfileState({
|
||||
isHttpReachable,
|
||||
isTransportAvailable,
|
||||
}),
|
||||
});
|
||||
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(isTransportAvailable).toHaveBeenCalledTimes(1);
|
||||
expect(isHttpReachable).not.toHaveBeenCalled();
|
||||
expect(response.body).toMatchObject({
|
||||
cdpHttp: true,
|
||||
cdpReady: true,
|
||||
running: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -105,7 +105,7 @@ describe("browser server-context existing-session profile", () => {
|
||||
expect(chromeMcp.ensureChromeMcpAvailable).toHaveBeenCalledWith(
|
||||
"chrome-live",
|
||||
"/tmp/brave-profile",
|
||||
{ ephemeral: true },
|
||||
{ ephemeral: true, timeoutMs: 300 },
|
||||
);
|
||||
expect(chromeMcp.listChromeMcpTabs).toHaveBeenCalledWith("chrome-live", "/tmp/brave-profile", {
|
||||
ephemeral: true,
|
||||
|
||||
Reference in New Issue
Block a user