From 63f81151f5f9f705511ed32a07be2eb6ec7d59cf Mon Sep 17 00:00:00 2001 From: cliffhall Date: Sun, 23 Aug 2026 16:55:17 -0400 Subject: [PATCH] test(web): stop the AppRenderer theme-flip test racing its MutationObserver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unrelated to this PR's subject, and pre-existing — it arrived with #1854. The test set `data-mantine-color-scheme` and asserted the bridge push after a single `await Promise.resolve()`, but how many ticks happy-dom takes to deliver a MutationObserver callback is load-dependent. Observed failing once in a full `npm run ci`, with 0 calls; passes standalone and on re-runs. Adding a dependency the size of `ace-builds` shifts worker timing enough to expose it, so fixing it here rather than leaving a known-intermittent failure in the gate for whoever hits it next. `waitFor` retries the same assertion. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_0177mPHAdECD18nLLCTwR5rh Signed-off-by: cliffhall --- .../elements/AppRenderer/AppRenderer.test.tsx | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/clients/web/src/components/elements/AppRenderer/AppRenderer.test.tsx b/clients/web/src/components/elements/AppRenderer/AppRenderer.test.tsx index a9a167cc..2cf355be 100644 --- a/clients/web/src/components/elements/AppRenderer/AppRenderer.test.tsx +++ b/clients/web/src/components/elements/AppRenderer/AppRenderer.test.tsx @@ -1,5 +1,5 @@ import { createRef, StrictMode } from "react"; -import { act } from "@testing-library/react"; +import { act, waitFor } from "@testing-library/react"; import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; import type { AppBridge } from "@modelcontextprotocol/ext-apps/app-bridge"; import type { CallToolResult, Tool } from "@modelcontextprotocol/client"; @@ -546,15 +546,21 @@ describe("AppRenderer", () => { // MutationObserver callbacks are delivered on a microtask. await Promise.resolve(); }); - expect(bridge.sendHostContextChange).toHaveBeenCalledWith( - expect.objectContaining({ - theme: "dark", - styles: expect.objectContaining({ - variables: expect.objectContaining({ - "--color-background-primary": "#101113", + // `waitFor`, not a bare assertion after the single microtask above: how + // many ticks happy-dom takes to deliver the MutationObserver callback is + // load-dependent, so under a full parallel run the observer can still be + // pending here. Observed failing exactly once that way, with 0 calls. + await waitFor(() => + expect(bridge.sendHostContextChange).toHaveBeenCalledWith( + expect.objectContaining({ + theme: "dark", + styles: expect.objectContaining({ + variables: expect.objectContaining({ + "--color-background-primary": "#101113", + }), }), }), - }), + ), ); } finally { getComputedStyleSpy.mockRestore();