fix: cover extension startup relay path (#28855) (thanks @Sid-Qin)

This commit is contained in:
Peter Steinberger
2026-03-02 06:19:24 +00:00
parent a555a95bf1
commit bfd3feda2d
2 changed files with 20 additions and 0 deletions

View File

@@ -38,6 +38,7 @@ Docs: https://docs.openclaw.ai
### Fixes
- Browser/Extension startup: stop failing browser startup when relay is reachable but no tab is attached yet; tab attachment is now required only when a tab action actually runs. (#28855) Thanks @Sid-Qin.
- Browser/Remote CDP ownership checks: skip local-process ownership errors for non-loopback remote CDP profiles when HTTP is reachable but the websocket handshake fails, and surface the remote websocket attach/retry path instead. (#15582) Landed from contributor (#28780) Thanks @stubbi, @bsormagec, @unblockedgamesstudio and @vincentkoc.
- Docker/Image health checks: add Dockerfile `HEALTHCHECK` that probes gateway `GET /healthz` so container runtimes can mark unhealthy instances without requiring auth credentials in the probe command. (#11478) Thanks @U-C4N and @vincentkoc.
- Daemon/systemd checks in containers: treat missing `systemctl` invocations (including `spawn systemctl ENOENT`/`EACCES`) as unavailable service state during `is-enabled` checks, preventing container flows from failing with `Gateway service check failed` before install/status handling can continue. (#26089) Thanks @sahilsatralkar and @vincentkoc.

View File

@@ -1,5 +1,7 @@
import { describe, expect, it, vi } from "vitest";
import { withFetchPreconnect } from "../test-utils/fetch-mock.js";
import * as chromeModule from "./chrome.js";
import * as extensionRelayModule from "./extension-relay.js";
import type { BrowserServerState } from "./server-context.js";
import "./server-context.chrome-test-harness.js";
import { createBrowserRouteContext } from "./server-context.js";
@@ -120,4 +122,21 @@ describe("browser server-context ensureTabAvailable", () => {
const chrome = ctx.forProfile("chrome");
await expect(chrome.ensureTabAvailable()).rejects.toThrow(/no attached Chrome tabs/i);
});
it("starts relay without requiring an attached tab during browser availability checks", async () => {
const isChromeReachableMock = vi.mocked(chromeModule.isChromeReachable);
const ensureRelaySpy = vi
.spyOn(extensionRelayModule, "ensureChromeExtensionRelayServer")
.mockResolvedValue(undefined as never);
isChromeReachableMock.mockResolvedValueOnce(false).mockResolvedValueOnce(true);
const state = makeBrowserState();
const ctx = createBrowserRouteContext({ getState: () => state });
const chrome = ctx.forProfile("chrome");
await expect(chrome.ensureBrowserAvailable()).resolves.toBeUndefined();
expect(ensureRelaySpy).toHaveBeenCalledWith({ cdpUrl: "http://127.0.0.1:18792" });
ensureRelaySpy.mockRestore();
});
});