From f8a965da8ea86951236112c029af9d7a6164a176 Mon Sep 17 00:00:00 2001 From: Keith Guerin Date: Fri, 27 Mar 2026 13:04:54 -0700 Subject: [PATCH] test(cli): fix config dialog tests --- packages/cli/src/config/footerItems.ts | 3 +- .../ui/components/FooterConfigDialog.test.tsx | 25 ++-- .../src/ui/components/FooterConfigDialog.tsx | 2 +- .../components/UnifiedModeIndicator.test.tsx | 15 +- .../ui/components/UnifiedModeIndicator.tsx | 12 +- ...ts-the-active-item-in-the-preview.snap.svg | 135 +++++++++--------- ...s-correctly-with-default-settings.snap.svg | 108 +++++++------- ...Show-footer-labels-is-toggled-off.snap.svg | 107 +++++++------- .../FooterConfigDialog.test.tsx.snap | 12 +- packages/cli/src/ui/textConstants.ts | 4 + 10 files changed, 236 insertions(+), 187 deletions(-) diff --git a/packages/cli/src/config/footerItems.ts b/packages/cli/src/config/footerItems.ts index 90cd694798..19a545bf81 100644 --- a/packages/cli/src/config/footerItems.ts +++ b/packages/cli/src/config/footerItems.ts @@ -5,6 +5,7 @@ */ import type { MergedSettings } from './settings.js'; +import { MODE_HEADER_DEFAULT } from '../ui/textConstants.js'; export const ALL_ITEMS: ReadonlyArray<{ id: @@ -24,7 +25,7 @@ export const ALL_ITEMS: ReadonlyArray<{ }> = [ { id: 'mode', - header: 'mode (Shift+Tab)', + header: MODE_HEADER_DEFAULT, description: 'Current session state: approval mode, shell mode, markdown mode', }, diff --git a/packages/cli/src/ui/components/FooterConfigDialog.test.tsx b/packages/cli/src/ui/components/FooterConfigDialog.test.tsx index 12829cd99a..9c7336c95b 100644 --- a/packages/cli/src/ui/components/FooterConfigDialog.test.tsx +++ b/packages/cli/src/ui/components/FooterConfigDialog.test.tsx @@ -41,6 +41,10 @@ describe('', () => { { settings }, ); + act(() => { + stdin.write('\u001b[B'); // Down arrow to move from 'mode' to 'workspace' + }); + act(() => { stdin.write('\r'); // Enter to toggle }); @@ -74,6 +78,9 @@ describe('', () => { expect(cwdIdx).toBeLessThan(branchIdx); // Move workspace down (right arrow) + act(() => { + stdin.write('\u001b[B'); // Down arrow to workspace + }); act(() => { stdin.write('\u001b[C'); // Right arrow }); @@ -116,7 +123,7 @@ describe('', () => { expect(lastFrame()).toContain('~/project/path'); // Move focus down to 'code-changes' (which has colored elements) - for (let i = 0; i < 8; i++) { + for (let i = 0; i < 9; i++) { act(() => { stdin.write('\u001b[B'); // Down arrow }); @@ -148,8 +155,8 @@ describe('', () => { { settings }, ); - // Default items are the first 5. We toggle them off. - for (let i = 0; i < 5; i++) { + // Default items are the first 6. We toggle them off. + for (let i = 0; i < 6; i++) { act(() => { stdin.write('\r'); // Toggle off }); @@ -176,7 +183,7 @@ describe('', () => { { settings }, ); - // Default initial items in mock settings are 'git-branch', 'workspace', ... + // Default initial items in mock settings are 'mode', 'workspace', 'git-branch', ... await waitFor(() => { const output = lastFrame(); expect(output).toContain('] git-branch'); @@ -188,22 +195,22 @@ describe('', () => { const workspaceIdx = output.indexOf('] workspace'); expect(workspaceIdx).toBeLessThan(branchIdx); - // Try to move workspace up (left arrow) while it's at the top + // Focus is on 'mode' at index 0. Try to move it up (left arrow). It should do nothing. act(() => { stdin.write('\u001b[D'); // Left arrow }); - // Move workspace down (right arrow) + // Move 'mode' down (right arrow). Order becomes 'workspace', 'mode', 'git-branch'. act(() => { stdin.write('\u001b[C'); // Right arrow }); await waitFor(() => { const outputAfter = lastFrame(); - const bIdxAfter = outputAfter.indexOf('] git-branch'); + const mIdxAfter = outputAfter.indexOf('] mode'); const wIdxAfter = outputAfter.indexOf('] workspace'); - // workspace should now be after git-branch - expect(bIdxAfter).toBeLessThan(wIdxAfter); + // mode should now be after workspace + expect(wIdxAfter).toBeLessThan(mIdxAfter); }); }); diff --git a/packages/cli/src/ui/components/FooterConfigDialog.tsx b/packages/cli/src/ui/components/FooterConfigDialog.tsx index 562bbabd81..2a43756a4c 100644 --- a/packages/cli/src/ui/components/FooterConfigDialog.tsx +++ b/packages/cli/src/ui/components/FooterConfigDialog.tsx @@ -104,7 +104,7 @@ export const FooterConfigDialog: React.FC = ({ key: id, id, label: item.id, - description: item.description as string, + description: item.description, type: 'config' as const, }, }; diff --git a/packages/cli/src/ui/components/UnifiedModeIndicator.test.tsx b/packages/cli/src/ui/components/UnifiedModeIndicator.test.tsx index f526fd8ee1..8e388f5449 100644 --- a/packages/cli/src/ui/components/UnifiedModeIndicator.test.tsx +++ b/packages/cli/src/ui/components/UnifiedModeIndicator.test.tsx @@ -10,31 +10,36 @@ import { UnifiedModeIndicator, getModeHeaderLabel, } from './UnifiedModeIndicator.js'; +import { + MODE_HEADER_SHELL, + MODE_HEADER_YOLO, + MODE_HEADER_DEFAULT, +} from '../textConstants.js'; import { ApprovalMode } from '@google/gemini-cli-core'; describe('UnifiedModeIndicator', () => { describe('getModeHeaderLabel', () => { it('returns shell exit label when shell is active', () => { expect(getModeHeaderLabel(ApprovalMode.DEFAULT, true)).toBe( - 'exit shell (!)', + MODE_HEADER_SHELL, ); }); it('returns yolo toggle label when YOLO is active and shell is NOT active', () => { expect(getModeHeaderLabel(ApprovalMode.YOLO, false)).toBe( - 'toggle yolo (Ctrl+Y)', + MODE_HEADER_YOLO, ); }); it('returns default mode label for other modes', () => { expect(getModeHeaderLabel(ApprovalMode.DEFAULT, false)).toBe( - 'mode (Shift+Tab)', + MODE_HEADER_DEFAULT, ); expect(getModeHeaderLabel(ApprovalMode.PLAN, false)).toBe( - 'mode (Shift+Tab)', + MODE_HEADER_DEFAULT, ); expect(getModeHeaderLabel(ApprovalMode.AUTO_EDIT, false)).toBe( - 'mode (Shift+Tab)', + MODE_HEADER_DEFAULT, ); }); }); diff --git a/packages/cli/src/ui/components/UnifiedModeIndicator.tsx b/packages/cli/src/ui/components/UnifiedModeIndicator.tsx index 65f750cb63..cd07be0824 100644 --- a/packages/cli/src/ui/components/UnifiedModeIndicator.tsx +++ b/packages/cli/src/ui/components/UnifiedModeIndicator.tsx @@ -9,6 +9,12 @@ import { Box, Text } from 'ink'; import { ApprovalMode } from '@google/gemini-cli-core'; import { theme } from '../semantic-colors.js'; +import { + MODE_HEADER_SHELL, + MODE_HEADER_YOLO, + MODE_HEADER_DEFAULT, +} from '../textConstants.js'; + export interface UnifiedModeIndicatorProps { approvalMode: ApprovalMode; shellModeActive: boolean; @@ -23,12 +29,12 @@ export function getModeHeaderLabel( shellModeActive: boolean, ): string { if (shellModeActive) { - return 'exit shell (!)'; + return MODE_HEADER_SHELL; } if (approvalMode === ApprovalMode.YOLO) { - return 'toggle yolo (Ctrl+Y)'; + return MODE_HEADER_YOLO; } - return 'mode (Shift+Tab)'; + return MODE_HEADER_DEFAULT; } /** diff --git a/packages/cli/src/ui/components/__snapshots__/FooterConfigDialog--FooterConfigDialog-highlights-the-active-item-in-the-preview.snap.svg b/packages/cli/src/ui/components/__snapshots__/FooterConfigDialog--FooterConfigDialog-highlights-the-active-item-in-the-preview.snap.svg index d4da9c5fa0..3ebc5f2da7 100644 --- a/packages/cli/src/ui/components/__snapshots__/FooterConfigDialog--FooterConfigDialog-highlights-the-active-item-in-the-preview.snap.svg +++ b/packages/cli/src/ui/components/__snapshots__/FooterConfigDialog--FooterConfigDialog-highlights-the-active-item-in-the-preview.snap.svg @@ -1,8 +1,8 @@ - + - + ╭──────────────────────────────────────────────────────────────────────────────────────────────────╮ @@ -19,140 +19,147 @@ [✓] - workspace + mode - Current working directory + Current session state: approval mode, shell mode, markdown mode [✓] - git-branch + workspace - Current git branch name (not shown when unavailable) + Current working directory [✓] - sandbox + git-branch - Sandbox type and trust indicator + Current git branch name (not shown when unavailable) [✓] - model-name + sandbox - Current model identifier + Sandbox type and trust indicator [✓] - quota + model-name - Remaining usage on daily limit (not shown when unavailable) + Current model identifier - [ ] - context-used + [✓] + quota - Percentage of context window used + Remaining usage on daily limit (not shown when unavailable) [ ] - memory-usage + context-used - Memory used by the application + Percentage of context window used [ ] - session-id + memory-usage - Unique identifier for the current session + Memory used by the application - - > - - - [✓] - - code-changes - + [ ] + session-id - - - Lines added/removed in the session (not shown when zero) - + Unique identifier for the current session - [ ] - token-count + + > + + + [✓] + + code-changes + - Total tokens used in the session (not shown when zero) + + + Lines added/removed in the session (not shown when zero) + - [✓] - Show footer labels + [ ] + token-count + Total tokens used in the session (not shown when zero) - Reset to default footer + [✓] + Show footer labels + Reset to default footer - Enter to select · ↑/↓ to navigate · ←/→ to reorder · Esc to close - ┌────────────────────────────────────────────────────────────────────────────────────────────┐ + Enter to select · ↑/↓ to navigate · ←/→ to reorder · Esc to close - - Preview: - - - workspace (/directory) - branch - sandbox - /model - /stats - - diff - - + ┌────────────────────────────────────────────────────────────────────────────────────────────┐ - ~/project/path - main - docker - gemini-2.5-pro - 97% - - +12 - - - -4 + Preview: - └────────────────────────────────────────────────────────────────────────────────────────────┘ + + workspace (/directory) + branch + sandbox + /model + /stats + + diff + + + + ~/project/path + main + docker + gemini-2.5-pro + 97% + + +12 + + + -4 + - ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ + + └────────────────────────────────────────────────────────────────────────────────────────────┘ + + + + ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ \ No newline at end of file diff --git a/packages/cli/src/ui/components/__snapshots__/FooterConfigDialog--FooterConfigDialog-renders-correctly-with-default-settings.snap.svg b/packages/cli/src/ui/components/__snapshots__/FooterConfigDialog--FooterConfigDialog-renders-correctly-with-default-settings.snap.svg index 41b13e401b..e53d6305d1 100644 --- a/packages/cli/src/ui/components/__snapshots__/FooterConfigDialog--FooterConfigDialog-renders-correctly-with-default-settings.snap.svg +++ b/packages/cli/src/ui/components/__snapshots__/FooterConfigDialog--FooterConfigDialog-renders-correctly-with-default-settings.snap.svg @@ -1,8 +1,8 @@ - + - + ╭──────────────────────────────────────────────────────────────────────────────────────────────────╮ @@ -23,131 +23,135 @@ [✓] - - workspace - + + mode + - - Current working directory - + + Current session state: approval mode, shell mode, markdown mode + [✓] - git-branch + workspace - Current git branch name (not shown when unavailable) + Current working directory [✓] - sandbox + git-branch - Sandbox type and trust indicator + Current git branch name (not shown when unavailable) [✓] - model-name + sandbox - Current model identifier + Sandbox type and trust indicator [✓] - quota + model-name - Remaining usage on daily limit (not shown when unavailable) + Current model identifier - [ ] - context-used + [✓] + quota - Percentage of context window used + Remaining usage on daily limit (not shown when unavailable) [ ] - memory-usage + context-used - Memory used by the application + Percentage of context window used [ ] - session-id + memory-usage - Unique identifier for the current session + Memory used by the application [ ] - code-changes + session-id - Lines added/removed in the session (not shown when zero) + Unique identifier for the current session [ ] - token-count + code-changes - Total tokens used in the session (not shown when zero) + Lines added/removed in the session (not shown when zero) - [✓] - Show footer labels + [ ] + token-count + Total tokens used in the session (not shown when zero) - Reset to default footer + [✓] + Show footer labels + Reset to default footer - Enter to select · ↑/↓ to navigate · ←/→ to reorder · Esc to close - ┌────────────────────────────────────────────────────────────────────────────────────────────┐ + Enter to select · ↑/↓ to navigate · ←/→ to reorder · Esc to close - - Preview: - - - - workspace (/directory) - branch - sandbox - /model - /stats - + ┌────────────────────────────────────────────────────────────────────────────────────────────┐ - - ~/project/path - - main - docker - gemini-2.5-pro - 97% + Preview: - └────────────────────────────────────────────────────────────────────────────────────────────┘ + + workspace (/directory) + branch + sandbox + /model + /stats + + + ~/project/path + main + docker + gemini-2.5-pro + 97% + - ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ + + └────────────────────────────────────────────────────────────────────────────────────────────┘ + + + + ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ \ No newline at end of file diff --git a/packages/cli/src/ui/components/__snapshots__/FooterConfigDialog--FooterConfigDialog-updates-the-preview-when-Show-footer-labels-is-toggled-off.snap.svg b/packages/cli/src/ui/components/__snapshots__/FooterConfigDialog--FooterConfigDialog-updates-the-preview-when-Show-footer-labels-is-toggled-off.snap.svg index 08340ca8ac..3229199acd 100644 --- a/packages/cli/src/ui/components/__snapshots__/FooterConfigDialog--FooterConfigDialog-updates-the-preview-when-Show-footer-labels-is-toggled-off.snap.svg +++ b/packages/cli/src/ui/components/__snapshots__/FooterConfigDialog--FooterConfigDialog-updates-the-preview-when-Show-footer-labels-is-toggled-off.snap.svg @@ -1,8 +1,8 @@ - + - + ╭──────────────────────────────────────────────────────────────────────────────────────────────────╮ @@ -19,125 +19,132 @@ [✓] - workspace + mode - Current working directory + Current session state: approval mode, shell mode, markdown mode [✓] - git-branch + workspace - Current git branch name (not shown when unavailable) + Current working directory [✓] - sandbox + git-branch - Sandbox type and trust indicator + Current git branch name (not shown when unavailable) [✓] - model-name + sandbox - Current model identifier + Sandbox type and trust indicator [✓] - quota + model-name - Remaining usage on daily limit (not shown when unavailable) + Current model identifier - [ ] - context-used + [✓] + quota - Percentage of context window used + Remaining usage on daily limit (not shown when unavailable) [ ] - memory-usage + context-used - Memory used by the application + Percentage of context window used [ ] - session-id + memory-usage - Unique identifier for the current session + Memory used by the application [ ] - code-changes + session-id - Lines added/removed in the session (not shown when zero) + Unique identifier for the current session [ ] - token-count + code-changes - Total tokens used in the session (not shown when zero) + Lines added/removed in the session (not shown when zero) - - > - - [ ] - - Show footer labels - + token-count - + Total tokens used in the session (not shown when zero) - Reset to default footer + + > + + + [ ] + + Show footer labels + + + Reset to default footer - Enter to select · ↑/↓ to navigate · ←/→ to reorder · Esc to close - ┌────────────────────────────────────────────────────────────────────────────────────────────┐ + Enter to select · ↑/↓ to navigate · ←/→ to reorder · Esc to close - - Preview: - - - ~/project/path - · - main - · - docker - · - gemini-2.5-pro - · - 97% - + ┌────────────────────────────────────────────────────────────────────────────────────────────┐ - └────────────────────────────────────────────────────────────────────────────────────────────┘ + + Preview: + + + ~/project/path + · + main + · + docker + · + gemini-2.5-pro + · + 97% + - ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ + + └────────────────────────────────────────────────────────────────────────────────────────────┘ + + + + ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ \ No newline at end of file diff --git a/packages/cli/src/ui/components/__snapshots__/FooterConfigDialog.test.tsx.snap b/packages/cli/src/ui/components/__snapshots__/FooterConfigDialog.test.tsx.snap index ce310c4ac9..95231d6a61 100644 --- a/packages/cli/src/ui/components/__snapshots__/FooterConfigDialog.test.tsx.snap +++ b/packages/cli/src/ui/components/__snapshots__/FooterConfigDialog.test.tsx.snap @@ -7,6 +7,8 @@ exports[` > highlights the active item in the preview 1`] │ │ │ Select which items to display in the footer. │ │ │ +│ [✓] mode │ +│ Current session state: approval mode, shell mode, markdown mode │ │ [✓] workspace │ │ Current working directory │ │ [✓] git-branch │ @@ -50,7 +52,9 @@ exports[` > renders correctly with default settings 1`] = │ │ │ Select which items to display in the footer. │ │ │ -│ > [✓] workspace │ +│ > [✓] mode │ +│ Current session state: approval mode, shell mode, markdown mode │ +│ [✓] workspace │ │ Current working directory │ │ [✓] git-branch │ │ Current git branch name (not shown when unavailable) │ @@ -94,7 +98,9 @@ exports[` > renders correctly with default settings 2`] = │ │ │ Select which items to display in the footer. │ │ │ -│ > [✓] workspace │ +│ > [✓] mode │ +│ Current session state: approval mode, shell mode, markdown mode │ +│ [✓] workspace │ │ Current working directory │ │ [✓] git-branch │ │ Current git branch name (not shown when unavailable) │ @@ -137,6 +143,8 @@ exports[` > updates the preview when Show footer labels is │ │ │ Select which items to display in the footer. │ │ │ +│ [✓] mode │ +│ Current session state: approval mode, shell mode, markdown mode │ │ [✓] workspace │ │ Current working directory │ │ [✓] git-branch │ diff --git a/packages/cli/src/ui/textConstants.ts b/packages/cli/src/ui/textConstants.ts index eaef8bf0ff..966f074223 100644 --- a/packages/cli/src/ui/textConstants.ts +++ b/packages/cli/src/ui/textConstants.ts @@ -20,3 +20,7 @@ export const getRedirectionWarningTipText = (shiftTabHint: string) => `Toggle auto-edit (${shiftTabHint}) to allow redirection in the future.`; export const GENERIC_WORKING_LABEL = 'Working...'; + +export const MODE_HEADER_SHELL = 'exit shell (!)'; +export const MODE_HEADER_YOLO = 'toggle yolo (Ctrl+Y)'; +export const MODE_HEADER_DEFAULT = 'mode (Shift+Tab)';