mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-02 09:01:33 +00:00
test(ui): isolate full chat-pane lifecycle tests to fix core-runtime-media-ui flake (#112566)
The core-runtime-media-ui shard runs its ui config non-isolated for speed, but the full chat-pane lifecycle tests instantiate the pane component, which relies on chat-thread/chat-message module-level singletons (thread-state map, confirmation dismisser WeakMap, module-scoped document context-menu listeners) and spies on those modules. Under the shared non-isolated graph a stateful predecessor file can leave those modules duplicated, so the pane binds to a different instance than the test's spy/registry -- producing order-dependent flakes: `removeEventListener`-not-called teardown assertions or 120s session-lifecycle hangs. Reproduced deterministically on a Linux Node 24 Testbox (MAX_WORKERS=1); isolating a single file only shifted the failure to a sibling pane test, so the whole full-pane family shares the fragility. Route the 7 full-pane lifecycle test files through a new isolated jsdom lane (vitest.ui-isolated.config.ts, isolate: true) for a fresh module graph; the other ~370 ui tests stay fast and non-isolated. Registered in both shard registries (ci-node-test-plan.mjs, vitest.test-shards.mjs) and excluded from vitest.ui.config.ts. Verified on Testbox: the deterministic single-worker media-ui shard goes from failing to 5182 passed / 0 failed. Test-infrastructure only; no product code changes.
This commit is contained in:
committed by
GitHub
parent
c24a215fe4
commit
f2a3371656
@@ -1129,6 +1129,7 @@ const SPLIT_NODE_SHARDS = new Map([
|
||||
"test/vitest/vitest.media-understanding.config.ts",
|
||||
"test/vitest/vitest.tui.config.ts",
|
||||
"test/vitest/vitest.ui.config.ts",
|
||||
"test/vitest/vitest.ui-isolated.config.ts",
|
||||
"test/vitest/vitest.wizard.config.ts",
|
||||
],
|
||||
requiresDist: false,
|
||||
|
||||
@@ -664,6 +664,7 @@ describe("scripts/lib/ci-node-test-plan.mjs", () => {
|
||||
"test/vitest/vitest.media-understanding.config.ts",
|
||||
"test/vitest/vitest.tui.config.ts",
|
||||
"test/vitest/vitest.ui.config.ts",
|
||||
"test/vitest/vitest.ui-isolated.config.ts",
|
||||
"test/vitest/vitest.wizard.config.ts",
|
||||
],
|
||||
requiresDist: false,
|
||||
|
||||
@@ -4731,6 +4731,7 @@ describe("scripts/test-projects full-suite sharding", () => {
|
||||
"test/vitest/vitest.tui.config.ts",
|
||||
"test/vitest/vitest.tui-pty.config.ts",
|
||||
"test/vitest/vitest.ui.config.ts",
|
||||
"test/vitest/vitest.ui-isolated.config.ts",
|
||||
"test/vitest/vitest.utils.config.ts",
|
||||
"test/vitest/vitest.wizard.config.ts",
|
||||
"test/vitest/vitest.gateway-core.config.ts",
|
||||
|
||||
@@ -84,6 +84,7 @@ export const fullSuiteVitestShards = [
|
||||
"test/vitest/vitest.tui.config.ts",
|
||||
"test/vitest/vitest.tui-pty.config.ts",
|
||||
"test/vitest/vitest.ui.config.ts",
|
||||
"test/vitest/vitest.ui-isolated.config.ts",
|
||||
"test/vitest/vitest.utils.config.ts",
|
||||
"test/vitest/vitest.wizard.config.ts",
|
||||
],
|
||||
|
||||
23
test/vitest/vitest.ui-isolated.config.ts
Normal file
23
test/vitest/vitest.ui-isolated.config.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
// Vitest ui-isolated config runs jsdom ui tests that need a fresh module graph.
|
||||
// The shared ui shard runs non-isolated for speed, but tests that spy on module
|
||||
// internals and assert the component uses that spy must not share a module cache
|
||||
// with stateful predecessor files (see UI_ISOLATED_TEST_FILES).
|
||||
import { createScopedVitestConfig } from "./vitest.scoped-config.ts";
|
||||
import { jsdomOptimizedDeps } from "./vitest.shared.config.ts";
|
||||
import { UI_ISOLATED_TEST_FILES } from "./vitest.ui.config.ts";
|
||||
|
||||
export function createUiIsolatedVitestConfig(env?: Record<string, string | undefined>) {
|
||||
return createScopedVitestConfig(UI_ISOLATED_TEST_FILES, {
|
||||
deps: jsdomOptimizedDeps,
|
||||
environment: "jsdom",
|
||||
env,
|
||||
excludeUnitFastTests: false,
|
||||
includeOpenClawRuntimeSetup: false,
|
||||
isolate: true,
|
||||
name: "ui-isolated",
|
||||
setupFiles: ["ui/src/test-helpers/lit-warnings.setup.ts"],
|
||||
useNonIsolatedRunner: false,
|
||||
});
|
||||
}
|
||||
|
||||
export default createUiIsolatedVitestConfig();
|
||||
@@ -2,12 +2,32 @@
|
||||
import { createScopedVitestConfig } from "./vitest.scoped-config.ts";
|
||||
import { jsdomOptimizedDeps } from "./vitest.shared.config.ts";
|
||||
|
||||
// Full chat-pane lifecycle tests instantiate the pane component, which relies on
|
||||
// chat-thread/chat-message module-level singletons (thread state maps, module-scoped
|
||||
// document context-menu listeners) and spies on those modules. Under the non-isolated
|
||||
// ui runner a stateful predecessor file can leave those modules duplicated across the
|
||||
// shared graph, so the pane binds to a different instance than the test's spy/registry
|
||||
// — surfacing as flaky teardown assertions or 120s session-lifecycle hangs, depending
|
||||
// on file order. These tests run in the isolated ui lane for a fresh module graph;
|
||||
// keep this list in sync with vitest.ui-isolated.config.ts's include.
|
||||
export const UI_ISOLATED_TEST_FILES = [
|
||||
"ui/src/pages/chat/chat-pane-history.test.ts",
|
||||
"ui/src/pages/chat/chat-pane-lifecycle.test.ts",
|
||||
"ui/src/pages/chat/chat-pane-pull-requests.test.ts",
|
||||
"ui/src/pages/chat/chat-pane.message-cut.test.ts",
|
||||
"ui/src/pages/chat/chat-pane.read-marker.test.ts",
|
||||
"ui/src/pages/chat/chat-pane.session-discussion.test.ts",
|
||||
"ui/src/pages/chat/chat-pane.test.ts",
|
||||
];
|
||||
|
||||
export function createUiVitestConfig(
|
||||
env?: Record<string, string | undefined>,
|
||||
options?: { includePatterns?: string[]; name?: string },
|
||||
) {
|
||||
const includePatterns = options?.includePatterns ?? ["ui/src/**/*.test.ts"];
|
||||
const exclude = options?.includePatterns ? [] : ["ui/src/**/*.e2e.test.ts"];
|
||||
const exclude = options?.includePatterns
|
||||
? []
|
||||
: ["ui/src/**/*.e2e.test.ts", ...UI_ISOLATED_TEST_FILES];
|
||||
return createScopedVitestConfig(includePatterns, {
|
||||
deps: jsdomOptimizedDeps,
|
||||
environment: "jsdom",
|
||||
|
||||
Reference in New Issue
Block a user