diff --git a/CHANGELOG.md b/CHANGELOG.md index 90111a99068..218e7eb92b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,7 @@ Docs: https://docs.openclaw.ai - Control UI/Talk: stop and clear failed realtime Talk sessions when dismissing runtime error banners, so the next Talk click starts a fresh session instead of only stopping the stale one. Thanks @vincentkoc. - Control UI/Talk: retry from a failed realtime Talk session on the next Talk click instead of requiring a separate stale-session stop click first. Thanks @vincentkoc. - Canvas host: preserve the Gateway TLS scheme in browser canvas host URLs and startup mount logs, so direct HTTPS gateways do not advertise insecure canvas links. Thanks @vincentkoc. +- WhatsApp/login: route login success and failure messages through the injected runtime, so setup/onboarding surfaces capture all login output instead of only the QR. Thanks @vincentkoc. - Google Chat: create an isolated Google auth transport per auth client, so google-auth-library interceptor mutations do not accumulate across webhook verification and access-token clients. Thanks @vincentkoc. - Doctor/plugins: remove orphaned managed npm copies of bundled `@openclaw/*` plugins during `doctor --fix`, so stale package manifests cannot shadow the current bundled plugin config schema. - Control UI/performance: cap long-task and long-animation-frame diagnostics in the shared event log, so slow-render telemetry does not evict gateway/plugin events from the Debug and Overview views. Thanks @vincentkoc. diff --git a/extensions/whatsapp/src/login.coverage.test.ts b/extensions/whatsapp/src/login.coverage.test.ts index 90f07d53208..f845da9b7df 100644 --- a/extensions/whatsapp/src/login.coverage.test.ts +++ b/extensions/whatsapp/src/login.coverage.test.ts @@ -111,6 +111,9 @@ describe("loginWeb coverage", () => { expect(createWaSocketMock).toHaveBeenCalledTimes(2); const firstSock = await createWaSocketMock.mock.results[0]?.value; expect(firstSock.ws.close).toHaveBeenCalled(); + expect(runtime.log).toHaveBeenCalledWith( + expect.stringContaining("Linked after restart; web session ready."), + ); vi.runAllTimers(); const secondSock = await createWaSocketMock.mock.results[1]?.value; expect(secondSock.ws.close).toHaveBeenCalled(); @@ -150,9 +153,11 @@ describe("loginWeb coverage", () => { output: { statusCode: 401 }, }); - await expect(loginWeb(false, waitForWaConnectionMock as never)).rejects.toThrow( + const runtime: RuntimeEnv = { log: vi.fn(), error: vi.fn(), exit: vi.fn() }; + await expect(loginWeb(false, waitForWaConnectionMock as never, runtime)).rejects.toThrow( /cache cleared/i, ); + expect(runtime.error).toHaveBeenCalledWith(expect.stringContaining("session is logged out")); expect(rmMock).toHaveBeenCalledWith(testState.authDir, { recursive: true, force: true, @@ -161,9 +166,13 @@ describe("loginWeb coverage", () => { it("formats and rethrows generic errors", async () => { waitForWaConnectionMock.mockRejectedValueOnce(new Error("boom")); - await expect(loginWeb(false, waitForWaConnectionMock as never)).rejects.toThrow( + const runtime: RuntimeEnv = { log: vi.fn(), error: vi.fn(), exit: vi.fn() }; + await expect(loginWeb(false, waitForWaConnectionMock as never, runtime)).rejects.toThrow( "formatted:Error: boom", ); + expect(runtime.error).toHaveBeenCalledWith( + expect.stringContaining("WhatsApp Web connection ended before fully opening."), + ); expect(formatErrorMock).toHaveBeenCalled(); }); }); diff --git a/extensions/whatsapp/src/login.ts b/extensions/whatsapp/src/login.ts index 497078a47e1..014ec77d263 100644 --- a/extensions/whatsapp/src/login.ts +++ b/extensions/whatsapp/src/login.ts @@ -51,7 +51,7 @@ export async function loginWeb( }, }); if (result.outcome === "connected") { - console.log( + runtime.log( success( result.restarted ? "✅ Linked after restart; web session ready." @@ -64,7 +64,7 @@ export async function loginWeb( } if (result.outcome === "logged-out") { - console.error( + runtime.error( danger( `WhatsApp reported the session is logged out. Cleared cached web session; please rerun ${formatCliCommand("openclaw channels login")} and scan the QR again.`, ), @@ -74,7 +74,7 @@ export async function loginWeb( }); } - console.error(danger(`WhatsApp Web connection ended before fully opening. ${result.message}`)); + runtime.error(danger(`WhatsApp Web connection ended before fully opening. ${result.message}`)); throw new Error(result.message, { cause: result.error }); } finally { // Let Baileys flush any final events before closing the socket.