From df73bbc14a62325207044d22edb7d03cd56096fd Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Thu, 30 Jul 2026 22:25:13 -0700 Subject: [PATCH] fix(tests): clear the persisted Command Center sub-tab between cases (7 of 8 main reds) (#2971) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `main` is red in the dashboard backfill lane. This fixes **7 of the 8** failures. All 8 bisect to #2420 (`4f929acc10`): parent `189f237a07` passes 9/9, that commit fails 5. ### Cause — test-order pollution, not a product bug #2420 made Command Center restore its sub-tab on remount, because the view unmounts on navigation by design: ```ts const [activeTab, setActiveTab] = useState( () => (getCommandCenterState(projectId)?.activeTab as SubViewId | undefined) ?? "overview", ); ``` The panel's test id is derived from that tab (`data-testid={\`command-center-panel-${activeTab}\`}`), and these files click through to other tabs — `tokens`, `team`, `github`, `system`, `mission-control`. Neither `beforeEach` cleared storage, so the **first** case left `mission-control` persisted and every later case rendered `command-center-panel-mission-control`: ``` → Unable to find an element by: [data-testid="command-center-panel-overview"] ``` Nothing in that message points at a previous test, which is what made it look like a component regression. **Confirmed as ordering rather than breakage:** each failing case passes when run alone with `-t`. The "mutation" here is `main` itself — without the `localStorage.clear()` these files fail 7; with it, 11/11. ### Scope Two lines plus the note explaining why they exist, so the next person who adds a tab-switching case knows the persistence is per-project and sticky. **No product code touched** — the persistence behaviour in #2420 is correct and stays as-is. **Verified:** 11/11 across both files, `tsc -p tsconfig.app.json` 0 errors, lint clean, FNXC gate exit 0. Test-only, no changeset. ### The 8th failure is NOT fixed here, deliberately `MainContent.planning-project-remount.test.tsx` fails because #2420 moved Planning out of `MainContent` (its branch now returns `null`) into `PlanningKeepAlive`, mounted by `App.tsx`. The product side is right — the host **is** keyed (`App.tsx:1956`): ```jsx ``` so project switches still remount and I found **no cross-project leak**. But that test was `FNXC:ProjectSwitchModalReset` coverage for a leak-class invariant (Planning carrying a previous project's stream/session), and **nothing asserts it at the new location**: the keep-alive test covers navigation reveal, not project switching, and `App.test.tsx` has no test for the host key. Deleting that `key=` today would fail no test. Restoring it needs an App-level test, which is a bigger change than this fix and worth keeping separate. Detailed on #2420. Co-authored-by: Claude Opus 5 (1M context) --- .../__tests__/CommandCenter.mobile-scroll.test.tsx | 14 ++++++++++++++ .../__tests__/CommandCenter.tablet-layout.test.tsx | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/packages/dashboard/app/components/command-center/__tests__/CommandCenter.mobile-scroll.test.tsx b/packages/dashboard/app/components/command-center/__tests__/CommandCenter.mobile-scroll.test.tsx index f2c7350700..864228ff15 100644 --- a/packages/dashboard/app/components/command-center/__tests__/CommandCenter.mobile-scroll.test.tsx +++ b/packages/dashboard/app/components/command-center/__tests__/CommandCenter.mobile-scroll.test.tsx @@ -368,6 +368,20 @@ async function openChartTab(tab: string) { describe("CommandCenter mobile scroll regression (FN-6595)", () => { beforeEach(() => { + /* + FNXC:CommandCenter 2026-07-30-22:10: + CLEAR THE PERSISTED SUB-TAB — cases in this file are no longer independent without it. + + #2420 made `activeTab` initialise from per-project persisted state + (`getCommandCenterState(projectId)?.activeTab`) instead of always `"overview"`, because Command + Center unmounts on navigation by design and has to restore its sub-tab on remount. These cases + click through to other tabs, so the FIRST case now leaves `mission-control` persisted and every + later case renders `command-center-panel-mission-control` — the `command-center-panel-overview` + lookups then fail with no hint that the cause is a previous test. + + Confirmed as ordering, not breakage: each failing case passes when run alone with `-t`. + */ + localStorage.clear(); apiMock.mockReset(); mockOverviewApi(); injectCommandCenterCss(); diff --git a/packages/dashboard/app/components/command-center/__tests__/CommandCenter.tablet-layout.test.tsx b/packages/dashboard/app/components/command-center/__tests__/CommandCenter.tablet-layout.test.tsx index bc04bb4481..c9a661bfb2 100644 --- a/packages/dashboard/app/components/command-center/__tests__/CommandCenter.tablet-layout.test.tsx +++ b/packages/dashboard/app/components/command-center/__tests__/CommandCenter.tablet-layout.test.tsx @@ -391,6 +391,20 @@ async function openChartTab(tab: string) { describe("CommandCenter tablet layout regression (FN-6679)", () => { beforeEach(() => { + /* + FNXC:CommandCenter 2026-07-30-22:10: + CLEAR THE PERSISTED SUB-TAB — cases in this file are no longer independent without it. + + #2420 made `activeTab` initialise from per-project persisted state + (`getCommandCenterState(projectId)?.activeTab`) instead of always `"overview"`, because Command + Center unmounts on navigation by design and has to restore its sub-tab on remount. These cases + click through to other tabs, so the FIRST case now leaves `mission-control` persisted and every + later case renders `command-center-panel-mission-control` — the `command-center-panel-overview` + lookups then fail with no hint that the cause is a previous test. + + Confirmed as ordering, not breakage: each failing case passes when run alone with `-t`. + */ + localStorage.clear(); apiMock.mockReset(); mockOverviewApi(); injectCommandCenterCss();