diff --git a/src/browser/bridge-server.auth.test.ts b/src/browser/bridge-server.auth.test.ts index e5b3904b10..38e1ff51f4 100644 --- a/src/browser/bridge-server.auth.test.ts +++ b/src/browser/bridge-server.auth.test.ts @@ -1,11 +1,12 @@ import { afterEach, describe, expect, it } from "vitest"; import { startBrowserBridgeServer, stopBrowserBridgeServer } from "./bridge-server.js"; +import type { ResolvedBrowserConfig } from "./config.js"; import { DEFAULT_OPENCLAW_BROWSER_COLOR, DEFAULT_OPENCLAW_BROWSER_PROFILE_NAME, } from "./constants.js"; -function buildResolvedConfig() { +function buildResolvedConfig(): ResolvedBrowserConfig { return { enabled: true, evaluateEnabled: false, @@ -15,6 +16,7 @@ function buildResolvedConfig() { cdpIsLoopback: true, remoteCdpTimeoutMs: 1500, remoteCdpHandshakeTimeoutMs: 3000, + extraArgs: [], color: DEFAULT_OPENCLAW_BROWSER_COLOR, executablePath: undefined, headless: true, @@ -27,7 +29,7 @@ function buildResolvedConfig() { color: DEFAULT_OPENCLAW_BROWSER_COLOR, }, }, - } as const; + } as unknown as ResolvedBrowserConfig; } describe("startBrowserBridgeServer auth", () => { diff --git a/src/browser/cdp.test.ts b/src/browser/cdp.test.ts index 9657989b20..24a97d1aa1 100644 --- a/src/browser/cdp.test.ts +++ b/src/browser/cdp.test.ts @@ -33,6 +33,9 @@ describe("cdp", () => { it("creates a target via the browser websocket", async () => { const wsPort = await startWsServer(); + if (!wsServer) { + throw new Error("ws server not initialized"); + } wsServer.on("connection", (socket) => { socket.on("message", (data) => { @@ -80,6 +83,9 @@ describe("cdp", () => { it("evaluates javascript via CDP", async () => { const wsPort = await startWsServer(); + if (!wsServer) { + throw new Error("ws server not initialized"); + } wsServer.on("connection", (socket) => { socket.on("message", (data) => { @@ -115,6 +121,9 @@ describe("cdp", () => { it("captures an aria snapshot via CDP", async () => { const wsPort = await startWsServer(); + if (!wsServer) { + throw new Error("ws server not initialized"); + } wsServer.on("connection", (socket) => { socket.on("message", (data) => { diff --git a/src/browser/profiles.test.ts b/src/browser/profiles.test.ts index b5b4d0fdba..cf706aab36 100644 --- a/src/browser/profiles.test.ts +++ b/src/browser/profiles.test.ts @@ -153,7 +153,9 @@ describe("port collision prevention", () => { const { resolveBrowserConfig } = await import("./config.js"); // Simulate what happens with raw config (empty) vs resolved config - const rawConfig = { browser: {} }; // Fresh config, no profiles + const rawConfig: { browser: { profiles?: Record } } = { + browser: {}, + }; // Fresh config, no profiles const buggyUsedPorts = getUsedPorts(rawConfig.browser?.profiles); const buggyAllocatedPort = allocateCdpPort(buggyUsedPorts); @@ -161,7 +163,9 @@ describe("port collision prevention", () => { expect(buggyAllocatedPort).toBe(CDP_PORT_RANGE_START); // Resolved config: includes implicit openclaw at 18800 - const resolved = resolveBrowserConfig(rawConfig.browser); + const resolved = resolveBrowserConfig( + rawConfig.browser as Parameters[0], + ); const fixedUsedPorts = getUsedPorts(resolved.profiles); const fixedAllocatedPort = allocateCdpPort(fixedUsedPorts); diff --git a/src/browser/pw-ai.test.ts b/src/browser/pw-ai.test.ts index 393be9c3d4..c182996efd 100644 --- a/src/browser/pw-ai.test.ts +++ b/src/browser/pw-ai.test.ts @@ -51,7 +51,7 @@ function createBrowser(pages: unknown[]) { contexts: () => [ctx], on: vi.fn(), close: vi.fn().mockResolvedValue(undefined), - }; + } as unknown as import("playwright-core").Browser; } let chromiumMock: typeof import("playwright-core").chromium; diff --git a/src/browser/pw-tools-core.last-file-chooser-arm-wins.test.ts b/src/browser/pw-tools-core.last-file-chooser-arm-wins.test.ts index 78c6068e58..3afbb2b9d4 100644 --- a/src/browser/pw-tools-core.last-file-chooser-arm-wins.test.ts +++ b/src/browser/pw-tools-core.last-file-chooser-arm-wins.test.ts @@ -44,8 +44,11 @@ describe("pw-tools-core", () => { paths: ["/tmp/2"], }); - resolve1?.(fc1); - resolve2?.(fc2); + if (!resolve1 || !resolve2) { + throw new Error("file chooser handlers were not registered"); + } + (resolve1 as (value: unknown) => void)(fc1); + (resolve2 as (value: unknown) => void)(fc2); await Promise.resolve(); expect(fc1.setFiles).not.toHaveBeenCalled(); diff --git a/src/browser/server-context.ensure-tab-available.prefers-last-target.test.ts b/src/browser/server-context.ensure-tab-available.prefers-last-target.test.ts index ee7f5e8dda..46e0be4a51 100644 --- a/src/browser/server-context.ensure-tab-available.prefers-last-target.test.ts +++ b/src/browser/server-context.ensure-tab-available.prefers-last-target.test.ts @@ -14,6 +14,10 @@ function makeBrowserState(): BrowserServerState { cdpProtocol: "http", cdpHost: "127.0.0.1", cdpIsLoopback: true, + evaluateEnabled: false, + remoteCdpTimeoutMs: 1500, + remoteCdpHandshakeTimeoutMs: 3000, + extraArgs: [], color: "#FF4500", headless: true, noSandbox: false, diff --git a/src/cli/browser-cli-extension.test.ts b/src/cli/browser-cli-extension.test.ts index be5957f314..d5232b6361 100644 --- a/src/cli/browser-cli-extension.test.ts +++ b/src/cli/browser-cli-extension.test.ts @@ -180,7 +180,7 @@ describe("browser extension install (fs-mocked)", () => { const { Command } = await import("commander"); const program = new Command(); - const browser = program.command("browser").option("--json", false); + const browser = program.command("browser").option("--json", "JSON output", false); registerBrowserExtensionCommands( browser, (cmd) => cmd.parent?.opts?.() as { json?: boolean }, diff --git a/src/cli/browser-cli-inspect.test.ts b/src/cli/browser-cli-inspect.test.ts index f4223a1d06..6dff715191 100644 --- a/src/cli/browser-cli-inspect.test.ts +++ b/src/cli/browser-cli-inspect.test.ts @@ -69,7 +69,7 @@ describe("browser cli snapshot defaults", () => { const { registerBrowserInspectCommands } = await import("./browser-cli-inspect.js"); const program = new Command(); - const browser = program.command("browser").option("--json", false); + const browser = program.command("browser").option("--json", "JSON output", false); registerBrowserInspectCommands(browser, () => ({})); await program.parseAsync(["browser", "snapshot"], { from: "user" }); @@ -93,12 +93,12 @@ describe("browser cli snapshot defaults", () => { format: "aria", targetId: "t1", url: "https://example.com", - nodes: [], + snapshot: "ok", }); const { registerBrowserInspectCommands } = await import("./browser-cli-inspect.js"); const program = new Command(); - const browser = program.command("browser").option("--json", false); + const browser = program.command("browser").option("--json", "JSON output", false); registerBrowserInspectCommands(browser, () => ({})); await program.parseAsync(["browser", "snapshot", "--format", "aria"], { from: "user" }); diff --git a/src/cli/cron-cli.test.ts b/src/cli/cron-cli.test.ts index b4e6fbc7ed..9677c03e9b 100644 --- a/src/cli/cron-cli.test.ts +++ b/src/cli/cron-cli.test.ts @@ -15,7 +15,7 @@ vi.mock("./gateway-rpc.js", async () => { return { ...actual, callGatewayFromCli: (method: string, opts: unknown, params?: unknown, extra?: unknown) => - callGatewayFromCli(method, opts, params, extra), + callGatewayFromCli(method, opts, params, extra as number | undefined), }; }); diff --git a/src/cli/gateway-cli/run-loop.test.ts b/src/cli/gateway-cli/run-loop.test.ts index 2740e1956e..636c994623 100644 --- a/src/cli/gateway-cli/run-loop.test.ts +++ b/src/cli/gateway-cli/run-loop.test.ts @@ -99,11 +99,14 @@ describe("runGatewayLoop", () => { ); const { runGatewayLoop } = await import("./run-loop.js"); + const runtime = { + log: vi.fn(), + error: vi.fn(), + exit: vi.fn(), + }; const loopPromise = runGatewayLoop({ - start, - runtime: { - exit: vi.fn(), - } as unknown as { exit: (code: number) => never }, + start: start as unknown as Parameters[0]["start"], + runtime: runtime as unknown as Parameters[0]["runtime"], }); try { diff --git a/src/cli/program.nodes-basic.e2e.test.ts b/src/cli/program.nodes-basic.e2e.test.ts index ae9c2439ce..32f17489b1 100644 --- a/src/cli/program.nodes-basic.e2e.test.ts +++ b/src/cli/program.nodes-basic.e2e.test.ts @@ -39,7 +39,8 @@ describe("cli program (nodes basics)", () => { it("runs nodes list --connected and filters to connected nodes", async () => { const now = Date.now(); - callGateway.mockImplementation(async (opts: { method?: string }) => { + callGateway.mockImplementation(async (...args: unknown[]) => { + const opts = (args[0] ?? {}) as { method?: string }; if (opts.method === "node.pair.list") { return { pending: [], @@ -81,7 +82,8 @@ describe("cli program (nodes basics)", () => { it("runs nodes status --last-connected and filters by age", async () => { const now = Date.now(); - callGateway.mockImplementation(async (opts: { method?: string }) => { + callGateway.mockImplementation(async (...args: unknown[]) => { + const opts = (args[0] ?? {}) as { method?: string }; if (opts.method === "node.list") { return { ts: now, @@ -188,7 +190,8 @@ describe("cli program (nodes basics)", () => { }); it("runs nodes describe and calls node.describe", async () => { - callGateway.mockImplementation(async (opts: { method?: string }) => { + callGateway.mockImplementation(async (...args: unknown[]) => { + const opts = (args[0] ?? {}) as { method?: string }; if (opts.method === "node.list") { return { ts: Date.now(), @@ -254,7 +257,8 @@ describe("cli program (nodes basics)", () => { }); it("runs nodes invoke and calls node.invoke", async () => { - callGateway.mockImplementation(async (opts: { method?: string }) => { + callGateway.mockImplementation(async (...args: unknown[]) => { + const opts = (args[0] ?? {}) as { method?: string }; if (opts.method === "node.list") { return { ts: Date.now(), diff --git a/src/cli/program.nodes-media.e2e.test.ts b/src/cli/program.nodes-media.e2e.test.ts index 02c30cedd0..538de141c5 100644 --- a/src/cli/program.nodes-media.e2e.test.ts +++ b/src/cli/program.nodes-media.e2e.test.ts @@ -38,7 +38,8 @@ const IOS_NODE = { } as const; function mockNodeGateway(command?: string, payload?: Record) { - callGateway.mockImplementation(async (opts: { method?: string }) => { + callGateway.mockImplementation(async (...args: unknown[]) => { + const opts = (args[0] ?? {}) as { method?: string }; if (opts.method === "node.list") { return { ts: Date.now(), @@ -77,7 +78,7 @@ describe("cli program (nodes media)", () => { .filter((call) => call.method === "node.invoke"); const facings = invokeCalls .map((call) => (call.params?.params as { facing?: string } | undefined)?.facing) - .filter(Boolean) + .filter((facing): facing is string => Boolean(facing)) .toSorted((a, b) => a.localeCompare(b)); expect(facings).toEqual(["back", "front"]); diff --git a/src/cli/update-cli.test.ts b/src/cli/update-cli.test.ts index 13220417ad..9164d18d4b 100644 --- a/src/cli/update-cli.test.ts +++ b/src/cli/update-cli.test.ts @@ -2,6 +2,7 @@ import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import type { OpenClawConfig, ConfigFileSnapshot } from "../config/types.openclaw.js"; import type { UpdateRunResult } from "../infra/update-runner.js"; import { captureEnv } from "../test-utils/env.js"; @@ -136,11 +137,19 @@ describe("update-cli", () => { await fs.rm(fixtureRoot, { recursive: true, force: true }); }); - const baseSnapshot = { + const baseConfig = {} as OpenClawConfig; + const baseSnapshot: ConfigFileSnapshot = { + path: "/tmp/openclaw-config.json", + exists: true, + raw: "{}", + parsed: {}, + resolved: baseConfig, valid: true, - config: {}, + config: baseConfig, issues: [], - } as const; + warnings: [], + legacyIssues: [], + }; const setTty = (value: boolean | undefined) => { Object.defineProperty(process.stdin, "isTTY", { @@ -252,6 +261,7 @@ describe("update-cli", () => { code: 0, signal: null, killed: false, + termination: "exit", }); readPackageName.mockResolvedValue("openclaw"); readPackageVersion.mockResolvedValue("1.0.0"); @@ -358,7 +368,7 @@ describe("update-cli", () => { it("uses stored beta channel when configured", async () => { vi.mocked(readConfigFileSnapshot).mockResolvedValue({ ...baseSnapshot, - config: { update: { channel: "beta" } }, + config: { update: { channel: "beta" } } as OpenClawConfig, }); vi.mocked(runGatewayUpdate).mockResolvedValue({ status: "ok", @@ -379,7 +389,7 @@ describe("update-cli", () => { vi.mocked(resolveOpenClawPackageRoot).mockResolvedValue(tempDir); vi.mocked(readConfigFileSnapshot).mockResolvedValue({ ...baseSnapshot, - config: { update: { channel: "beta" } }, + config: { update: { channel: "beta" } } as OpenClawConfig, }); vi.mocked(checkUpdateStatus).mockResolvedValue({ root: tempDir,