perf(test): optimize test suite speed and stability

This commit is contained in:
mkorwel
2026-04-14 23:35:02 -07:00
parent a0a3e0c666
commit 78c8ace77f
24 changed files with 85653 additions and 117 deletions
@@ -168,7 +168,7 @@ describe('Full Terminal Tool Confirmation Snapshot', () => {
// Give it a moment to render
await act(async () => {
await new Promise((resolve) => setTimeout(resolve, 500));
await new Promise((resolve) => setTimeout(resolve, 20));
});
await expect({ lastFrame, generateSvg }).toMatchSvgSnapshot();
@@ -8,7 +8,7 @@ import { describe, it, expect, vi, afterEach, beforeEach } from 'vitest';
import { act } from 'react';
import { renderWithProviders } from '../../test-utils/render.js';
import { createMockSettings } from '../../test-utils/settings.js';
import { makeFakeConfig } from '@google/gemini-cli-core';
import { makeFakeConfig } from '../../../../core/src/test-utils/config.js';
import { waitFor } from '../../test-utils/async.js';
import { AskUserDialog } from './AskUserDialog.js';
import { QuestionType, type Question } from '@google/gemini-cli-core';
@@ -170,7 +170,7 @@ export const ConfigExtensionDialog: React.FC<ConfigExtensionDialogProps> = ({
if (mounted.current) {
setState({ type: 'DONE' });
// Delay close slightly to show done
setTimeout(onClose, 1000);
setTimeout(onClose, 20);
}
} catch (err: unknown) {
if (mounted.current) {
@@ -26,7 +26,7 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { SettingsDialog } from './SettingsDialog.js';
import { SettingScope } from '../../config/settings.js';
import { createMockSettings } from '../../test-utils/settings.js';
import { makeFakeConfig } from '@google/gemini-cli-core';
import { makeFakeConfig } from '../../../../core/src/test-utils/config.js';
import { act } from 'react';
import { TEST_ONLY } from '../../utils/settingsUtils.js';
import {
@@ -11,6 +11,17 @@ Enter to submit · Esc to cancel
"
`;
exports[`AskUserDialog > Choice question placeholder > uses default placeholder when not provided 2`] = `
"Select your preferred language:
1. TypeScript
2. JavaScript
● 3. Enter a custom value
Enter to submit · Esc to cancel
"
`;
exports[`AskUserDialog > Choice question placeholder > uses placeholder for "Other" option when provided 1`] = `
"Select your preferred language:
@@ -22,6 +33,17 @@ Enter to submit · Esc to cancel
"
`;
exports[`AskUserDialog > Choice question placeholder > uses placeholder for "Other" option when provided 2`] = `
"Select your preferred language:
1. TypeScript
2. JavaScript
● 3. Type another language...
Enter to submit · Esc to cancel
"
`;
exports[`AskUserDialog > Scroll Arrows (useAlternateBuffer: false) > shows scroll arrows correctly when useAlternateBuffer is false 1`] = `
"Choose an option
@@ -38,6 +60,22 @@ Enter to select · ↑/↓ to navigate · Esc to cancel
"
`;
exports[`AskUserDialog > Scroll Arrows (useAlternateBuffer: false) > shows scroll arrows correctly when useAlternateBuffer is false 2`] = `
"Choose an option
● 1. Option 1
Description 1
2. Option 2
Description 2
3. Option 3
Description 3
Enter to select · ↑/↓ to navigate · Esc to cancel
"
`;
exports[`AskUserDialog > Scroll Arrows (useAlternateBuffer: true) > shows scroll arrows correctly when useAlternateBuffer is true 1`] = `
"Choose an option
@@ -54,6 +92,22 @@ Enter to select · ↑/↓ to navigate · Esc to cancel
"
`;
exports[`AskUserDialog > Scroll Arrows (useAlternateBuffer: true) > shows scroll arrows correctly when useAlternateBuffer is true 2`] = `
"Choose an option
● 1. Option 1
Description 1
2. Option 2
Description 2
3. Option 3
Description 3
Enter to select · ↑/↓ to navigate · Esc to cancel
"
`;
exports[`AskUserDialog > Text type questions > renders text input for type: "text" 1`] = `
"What should we name this component?
@@ -196,3 +250,19 @@ exports[`AskUserDialog > verifies "All of the above" visual state with snapshot
Enter to select · ↑/↓ to navigate · Esc to cancel
"
`;
exports[`AskUserDialog > verifies "All of the above" visual state with snapshot 2`] = `
"Which features?
(Select all that apply)
1. [x] TypeScript
2. [x] ESLint
● 3. [x] All of the above
Select all options
4. [ ] Enter a custom value
Done
Finish selection
Enter to select · ↑/↓ to navigate · Esc to cancel
"
`;
@@ -27,6 +27,33 @@ Enter to select · ↑/↓ to navigate · Ctrl+G to edit plan · Esc to cancel
"
`;
exports[`ExitPlanModeDialog > useAlternateBuffer: false > bubbles up Ctrl+C when feedback is empty while editing 2`] = `
"Overview
Add user authentication to the CLI application.
Implementation Steps
1. Create src/auth/AuthService.ts with login/logout methods
2. Add session storage in src/storage/SessionStore.ts
3. Update src/commands/index.ts to check auth status
4. Add tests in src/auth/__tests__/
Files to Modify
- src/index.ts - Add auth middleware
- src/config.ts - Add auth configuration options
1. Yes, automatically accept edits
Approves plan and allows tools to run automatically
2. Yes, manually accept edits
Approves plan but requires confirmation for each tool
● 3. Type your feedback...
Enter to submit · Ctrl+G to edit plan · Esc to cancel
"
`;
exports[`ExitPlanModeDialog > useAlternateBuffer: false > calls onFeedback when feedback is typed and submitted 1`] = `
"Overview
@@ -54,6 +81,33 @@ Enter to select · ↑/↓ to navigate · Ctrl+G to edit plan · Esc to cancel
"
`;
exports[`ExitPlanModeDialog > useAlternateBuffer: false > calls onFeedback when feedback is typed and submitted 2`] = `
"Overview
Add user authentication to the CLI application.
Implementation Steps
1. Create src/auth/AuthService.ts with login/logout methods
2. Add session storage in src/storage/SessionStore.ts
3. Update src/commands/index.ts to check auth status
4. Add tests in src/auth/__tests__/
Files to Modify
- src/index.ts - Add auth middleware
- src/config.ts - Add auth configuration options
1. Yes, automatically accept edits
Approves plan and allows tools to run automatically
2. Yes, manually accept edits
Approves plan but requires confirmation for each tool
● 3. Add tests
Enter to submit · Ctrl+G to edit plan · Esc to cancel
"
`;
exports[`ExitPlanModeDialog > useAlternateBuffer: false > displays error state when file read fails 1`] = `
" Error reading plan: File not found
"
@@ -140,6 +194,33 @@ Enter to select · ↑/↓ to navigate · Ctrl+G to edit plan · Esc to cancel
"
`;
exports[`ExitPlanModeDialog > useAlternateBuffer: true > bubbles up Ctrl+C when feedback is empty while editing 2`] = `
"Overview
Add user authentication to the CLI application.
Implementation Steps
1. Create src/auth/AuthService.ts with login/logout methods
2. Add session storage in src/storage/SessionStore.ts
3. Update src/commands/index.ts to check auth status
4. Add tests in src/auth/__tests__/
Files to Modify
- src/index.ts - Add auth middleware
- src/config.ts - Add auth configuration options
1. Yes, automatically accept edits
Approves plan and allows tools to run automatically
2. Yes, manually accept edits
Approves plan but requires confirmation for each tool
● 3. Type your feedback...
Enter to submit · Ctrl+G to edit plan · Esc to cancel
"
`;
exports[`ExitPlanModeDialog > useAlternateBuffer: true > calls onFeedback when feedback is typed and submitted 1`] = `
"Overview
@@ -167,6 +248,33 @@ Enter to select · ↑/↓ to navigate · Ctrl+G to edit plan · Esc to cancel
"
`;
exports[`ExitPlanModeDialog > useAlternateBuffer: true > calls onFeedback when feedback is typed and submitted 2`] = `
"Overview
Add user authentication to the CLI application.
Implementation Steps
1. Create src/auth/AuthService.ts with login/logout methods
2. Add session storage in src/storage/SessionStore.ts
3. Update src/commands/index.ts to check auth status
4. Add tests in src/auth/__tests__/
Files to Modify
- src/index.ts - Add auth middleware
- src/config.ts - Add auth configuration options
1. Yes, automatically accept edits
Approves plan and allows tools to run automatically
2. Yes, manually accept edits
Approves plan but requires confirmation for each tool
● 3. Add tests
Enter to submit · Ctrl+G to edit plan · Esc to cancel
"
`;
exports[`ExitPlanModeDialog > useAlternateBuffer: true > displays error state when file read fails 1`] = `
" Error reading plan: File not found
"
@@ -168,6 +168,27 @@ exports[`InputPrompt > mouse interaction > should toggle paste expansion on doub
"
`;
exports[`InputPrompt > mouse interaction > should toggle paste expansion on double-click 4`] = `
"▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
> [Pasted Text: 10 lines]
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
"
`;
exports[`InputPrompt > mouse interaction > should toggle paste expansion on double-click 5`] = `
"▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
> [Pasted Text: 10 lines]
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
"
`;
exports[`InputPrompt > mouse interaction > should toggle paste expansion on double-click 6`] = `
"▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
> [Pasted Text: 10 lines]
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
"
`;
exports[`InputPrompt > multiline rendering > should correctly render multiline input including blank lines 1`] = `
"────────────────────────────────────────────────────────────────────────────────────────────────────
│ > hello │
@@ -8,20 +8,22 @@
<text x="0" y="19" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="891" y="19" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="36" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="36" fill="#ffffff" textLength="882" lengthAdjust="spacingAndGlyphs"> Settings </text>
<text x="27" y="36" fill="#ffffff" textLength="99" lengthAdjust="spacingAndGlyphs" font-weight="bold">&gt; Settings </text>
<text x="891" y="36" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="53" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="891" y="53" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="70" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="18" y="70" fill="#878787" textLength="864" lengthAdjust="spacingAndGlyphs">╭──────────────────────────────────────────────────────────────────────────────────────────────╮</text>
<text x="18" y="70" fill="#d7ffd7" textLength="864" lengthAdjust="spacingAndGlyphs">╭──────────────────────────────────────────────────────────────────────────────────────────────╮</text>
<text x="891" y="70" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="87" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="18" y="87" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="36" y="87" fill="#afafaf" textLength="144" lengthAdjust="spacingAndGlyphs">Search to filter</text>
<text x="873" y="87" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="18" y="87" fill="#d7ffd7" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<rect x="36" y="85" width="9" height="17" fill="#ffffff" />
<text x="36" y="87" fill="#000000" textLength="9" lengthAdjust="spacingAndGlyphs">S</text>
<text x="45" y="87" fill="#afafaf" textLength="135" lengthAdjust="spacingAndGlyphs">earch to filter</text>
<text x="873" y="87" fill="#d7ffd7" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="891" y="87" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="104" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="18" y="104" fill="#878787" textLength="864" lengthAdjust="spacingAndGlyphs">╰──────────────────────────────────────────────────────────────────────────────────────────────╯</text>
<text x="18" y="104" fill="#d7ffd7" textLength="864" lengthAdjust="spacingAndGlyphs">╰──────────────────────────────────────────────────────────────────────────────────────────────╯</text>
<text x="891" y="104" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="121" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="891" y="121" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
@@ -29,11 +31,20 @@
<text x="27" y="138" fill="#afafaf" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="891" y="138" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="155" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="45" y="155" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs">Vim Mode</text>
<text x="828" y="155" fill="#afafaf" textLength="45" lengthAdjust="spacingAndGlyphs">false</text>
<rect x="27" y="153" width="9" height="17" fill="#005f00" />
<text x="27" y="155" fill="#d7ffd7" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<rect x="36" y="153" width="9" height="17" fill="#005f00" />
<rect x="45" y="153" width="72" height="17" fill="#005f00" />
<text x="45" y="155" fill="#d7ffd7" textLength="72" lengthAdjust="spacingAndGlyphs">Vim Mode</text>
<rect x="117" y="153" width="711" height="17" fill="#005f00" />
<rect x="828" y="153" width="45" height="17" fill="#005f00" />
<text x="828" y="155" fill="#d7ffd7" textLength="45" lengthAdjust="spacingAndGlyphs">false</text>
<text x="891" y="155" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="172" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<rect x="27" y="170" width="18" height="17" fill="#005f00" />
<rect x="45" y="170" width="198" height="17" fill="#005f00" />
<text x="45" y="172" fill="#afafaf" textLength="198" lengthAdjust="spacingAndGlyphs">Enable Vim keybindings</text>
<rect x="243" y="170" width="630" height="17" fill="#005f00" />
<text x="891" y="172" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="189" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="891" y="189" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
@@ -106,26 +117,21 @@
<text x="0" y="580" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="891" y="580" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="597" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="27" y="597" fill="#ffffff" textLength="90" lengthAdjust="spacingAndGlyphs" font-weight="bold">&gt; Apply To</text>
<text x="9" y="597" fill="#ffffff" textLength="882" lengthAdjust="spacingAndGlyphs"> Apply To </text>
<text x="891" y="597" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="614" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<rect x="27" y="612" width="9" height="17" fill="#005f00" />
<text x="27" y="614" fill="#d7ffd7" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<rect x="36" y="612" width="9" height="17" fill="#005f00" />
<rect x="45" y="612" width="18" height="17" fill="#005f00" />
<text x="45" y="614" fill="#d7ffd7" textLength="18" lengthAdjust="spacingAndGlyphs">1.</text>
<rect x="63" y="612" width="9" height="17" fill="#005f00" />
<rect x="72" y="612" width="117" height="17" fill="#005f00" />
<text x="72" y="614" fill="#d7ffd7" textLength="117" lengthAdjust="spacingAndGlyphs">User Settings</text>
<rect x="189" y="612" width="684" height="17" fill="#005f00" />
<rect x="45" y="612" width="117" height="17" fill="#005f00" />
<text x="45" y="614" fill="#d7ffd7" textLength="117" lengthAdjust="spacingAndGlyphs">User Settings</text>
<rect x="162" y="612" width="711" height="17" fill="#005f00" />
<text x="891" y="614" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="631" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="45" y="631" fill="#ffffff" textLength="18" lengthAdjust="spacingAndGlyphs">2.</text>
<text x="72" y="631" fill="#ffffff" textLength="162" lengthAdjust="spacingAndGlyphs">Workspace Settings</text>
<text x="45" y="631" fill="#ffffff" textLength="162" lengthAdjust="spacingAndGlyphs">Workspace Settings</text>
<text x="891" y="631" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="648" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="45" y="648" fill="#ffffff" textLength="18" lengthAdjust="spacingAndGlyphs">3.</text>
<text x="72" y="648" fill="#ffffff" textLength="135" lengthAdjust="spacingAndGlyphs">System Settings</text>
<text x="45" y="648" fill="#ffffff" textLength="135" lengthAdjust="spacingAndGlyphs">System Settings</text>
<text x="891" y="648" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="665" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="891" y="665" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs"></text>

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

@@ -233,14 +233,14 @@ exports[`SettingsDialog > Snapshot Tests > should render 'file filtering setting
exports[`SettingsDialog > Snapshot Tests > should render 'focused on scope selector' correctly 1`] = `
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
│ │
Settings │
> Settings │
│ │
│ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │
│ │ Search to filter │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ ▲ │
Vim Mode false │
Vim Mode false │
│ Enable Vim keybindings │
│ │
│ Default Approval Mode Default │
@@ -266,10 +266,10 @@ exports[`SettingsDialog > Snapshot Tests > should render 'focused on scope selec
│ │
│ ▼ │
│ │
> Apply To │
│ ● 1. User Settings │
2. Workspace Settings │
3. System Settings │
Apply To │
│ ● User Settings
│ Workspace Settings
│ System Settings
│ │
│ (Use Enter to select, Ctrl+L to reset, Tab to change focus, Esc to close) │
│ │
@@ -69,7 +69,7 @@ export function TerminalProvider({ children }: { children: React.ReactNode }) {
setTimeout(() => {
unsubscribe(handler);
resolve();
}, 100);
}, 20);
}),
[stdout, subscribe, unsubscribe],
);
@@ -103,7 +103,9 @@ export class TerminalCapabilityManager {
* This should be called once at app startup.
*/
async detectCapabilities(): Promise<void> {
if (this.detectionComplete) return;
if (this.detectionComplete) {
return;
}
if (!process.stdin.isTTY || !process.stdout.isTTY) {
this.detectionComplete = true;
@@ -146,7 +148,7 @@ export class TerminalCapabilityManager {
// A somewhat long timeout is acceptable as all terminals should respond
// to the device attributes query used as a sentinel.
timeoutId = setTimeout(cleanup, 1000);
timeoutId = setTimeout(cleanup, 50);
const onData = (data: Buffer) => {
buffer += data.toString();