From 41a78bb9bd42cb5e15fb9319face502ec3e2eee7 Mon Sep 17 00:00:00 2001 From: Jinwoo Hong <73622457+Jinwoo-H@users.noreply.github.com> Date: Thu, 15 Oct 2026 03:00:40 -0400 Subject: [PATCH] test(layout): list the window-parity differences that are not bugs separately (#29014) * test(layout): list the window-parity differences that are not bugs separately The parity test listed five differences between the window's startup view of a stored session and of the shared Loader's rewrite of it. Three are not bugs: the row terminal rewrite (the pane binding wins on mount), legacy surface tombstones (the window is the outlier) and label over title (only phones and the CLI show the row title). They move to ACCEPTED_DIFFERENCES with a reason each; KNOWN_DIFFERENCES keeps only the ghost tab. Co-Authored-By: Claude Opus 5.5 * test(layout): pin the values of accepted window-parity differences Co-Authored-By: Claude Opus 5.5 --------- Co-authored-by: Claude Opus 5.5 --- .../app-shell/startup-window-parity.test.ts | 66 +++++++++++++++---- .../startup-window-view.test-fixture.ts | 3 +- 2 files changed, 57 insertions(+), 12 deletions(-) diff --git a/src/renderer/src/app-shell/startup-window-parity.test.ts b/src/renderer/src/app-shell/startup-window-parity.test.ts index 0d44305c330..25212c876f7 100644 --- a/src/renderer/src/app-shell/startup-window-parity.test.ts +++ b/src/renderer/src/app-shell/startup-window-parity.test.ts @@ -1,6 +1,7 @@ // Window parity: for each stored profile, the window's startup hydration of the session as stored // and of the shared Loader's rewrite of it (load then save) must show the same thing. Where they -// differ today, the difference is listed below with the Loader rule that causes it. +// differ today, the difference is listed below with the Loader rule that causes it: as work to +// do, or as accepted with the reason it is not a bug. import { describe, expect, it, vi } from 'vitest' import type * as AgentStatusModule from '@/lib/agent-status' @@ -28,7 +29,7 @@ createStoreSessionMockApi() const GIT = 'repo-1::/Users/dev/orca' const terminal = (tabId: string) => - ['title', 'panes', 'focused pane', 'reattaches'].map( + ['phone and CLI title', 'panes', 'focused pane', 'reattaches'].map( (field) => `${GIT} terminal ${tabId} ${field}` ) @@ -40,32 +41,58 @@ type KnownDifference = { paths: string[] } -/** Today's differences. Entries may only be removed: fix the rule, then delete its entry. */ +/** Differences to fix. Entries may only be removed: fix the rule, then delete its entry. */ const KNOWN_DIFFERENCES: readonly KnownDifference[] = [ { fixture: 'row without a tab-bar entry or a terminal', rule: 'ghost tab: the Loader gives every row a tab-bar entry; the window adopts only rows it can reattach', paths: [`${GIT} group 0 tabs`, `${GIT} tab tab-b`, ...terminal('tab-b')] - }, + } +] + +type AcceptedDifference = Omit & { + reason: string + /** Each differing view path with its stored and normalized values; absent means not shown. */ + values: Record +} + +/** Differences that are not bugs: the user sees the same thing, or the window is the outlier. */ +const ACCEPTED_DIFFERENCES: readonly AcceptedDifference[] = [ { fixture: 'row terminal differs from its focused pane’s', rule: 'row.ptyId rewrite: the Loader sets the row terminal to its focused pane’s, which changes what the tab reattaches', - paths: [`${GIT} terminal tab-a reattaches`] + reason: 'the pane’s own terminal binding wins on mount, so the user sees the same terminal', + values: { [`${GIT} terminal tab-a reattaches`]: { stored: 'pty-stale', normalized: 'pty-a' } } }, { fixture: 'row with no terminal while its pane has one', rule: 'row.ptyId rewrite: the Loader sets the row terminal to its focused pane’s, which changes what the tab reattaches', - paths: [`${GIT} terminal tab-a reattaches`] + reason: 'the pane’s own terminal binding wins on mount, so the user sees the same terminal', + values: { [`${GIT} terminal tab-a reattaches`]: { stored: null, normalized: 'pty-a' } } }, { fixture: 'legacy surface tombstone on a pane still showing its terminal', rule: 'tombstones: the Loader closes a pane a legacy surface tombstone names; the window ignores the tombstone and shows the pane', - paths: [`${GIT} group 0 tabs`, `${GIT} tab tab-b`, ...terminal('tab-b')] + reason: 'the window is the outlier: main already retires panes these tombstones name', + values: { + [`${GIT} group 0 tabs`]: { stored: ['tab-a', 'tab-b'], normalized: ['tab-a'] }, + [`${GIT} tab tab-b`]: { + stored: { kind: 'terminal', shows: 'tab-b', group: 0, label: 'Terminal 2' } + }, + [`${GIT} terminal tab-b phone and CLI title`]: { stored: 'Terminal 2' }, + [`${GIT} terminal tab-b panes`]: { stored: { pane: 'pty-b' } }, + [`${GIT} terminal tab-b focused pane`]: { stored: 'root' }, + [`${GIT} terminal tab-b reattaches`]: { stored: 'pty-b' } + } }, { fixture: 'tab-bar label differing from the row title', - rule: 'label over title: the Loader writes the tab-bar label into the row title the window shows', - paths: [`${GIT} terminal tab-a title`] + rule: 'label over title: the Loader writes the tab-bar label into the row title', + reason: + 'the desktop tab shows the label, which is unchanged; only phones and the CLI show the row title', + values: { + [`${GIT} terminal tab-a phone and CLI title`]: { stored: 'Terminal 1', normalized: 'vim' } + } } ] @@ -102,10 +129,25 @@ describe('the window shows the same session before and after the shared Loader r } const differences = diffStartupWindowViews(storedView, normalizedView) const known = KNOWN_DIFFERENCES.filter((entry) => entry.fixture === name) + const accepted = ACCEPTED_DIFFERENCES.filter((entry) => entry.fixture === name) expect( differences.map((difference) => difference.path).sort(), `window differences (stored vs normalized):\n${JSON.stringify(differences, null, 2)}` - ).toEqual(known.flatMap((entry) => entry.paths).sort()) + ).toEqual( + [ + ...known.flatMap((entry) => entry.paths), + ...accepted.flatMap((entry) => Object.keys(entry.values)) + ].sort() + ) + // An accepted difference stays accepted only while it shows exactly the recorded values. + const acceptedValues = Object.assign({}, ...accepted.map((entry) => entry.values)) + expect( + Object.fromEntries( + differences + .filter((difference) => difference.path in acceptedValues) + .map(({ path, stored, normalized }) => [path, { stored, normalized }]) + ) + ).toEqual(acceptedValues) } ) @@ -137,6 +179,8 @@ describe('the window shows the same session before and after the shared Loader r it('lists differences only for fixtures that exist', () => { const names = new Set(PROFILES.map((profile) => profile.name)) - expect(KNOWN_DIFFERENCES.filter((entry) => !names.has(entry.fixture))).toEqual([]) + expect( + [...KNOWN_DIFFERENCES, ...ACCEPTED_DIFFERENCES].filter((entry) => !names.has(entry.fixture)) + ).toEqual([]) }) }) diff --git a/src/renderer/src/app-shell/startup-window-view.test-fixture.ts b/src/renderer/src/app-shell/startup-window-view.test-fixture.ts index ae0267af904..2c301508694 100644 --- a/src/renderer/src/app-shell/startup-window-view.test-fixture.ts +++ b/src/renderer/src/app-shell/startup-window-view.test-fixture.ts @@ -185,7 +185,8 @@ export function projectStartupWindowView(state: AppState): Record