test(cli): fix AppContainer act() warnings and improve waitFor resilience (#18676)

This commit is contained in:
N. Taylor Mullen
2026-02-09 20:44:22 -08:00
committed by GitHub
parent ece001f264
commit 4494f9e062
2 changed files with 36 additions and 3 deletions

View File

@@ -5,6 +5,7 @@
*/
import { act } from 'react';
import { vi } from 'vitest';
// The waitFor from vitest doesn't properly wrap in act(), so we have to
// implement our own like the one in @testing-library/react
@@ -13,7 +14,7 @@ import { act } from 'react';
// for React state updates.
export async function waitFor(
assertion: () => void,
{ timeout = 1000, interval = 50 } = {},
{ timeout = 2000, interval = 50 } = {},
): Promise<void> {
const startTime = Date.now();
@@ -27,7 +28,11 @@ export async function waitFor(
}
await act(async () => {
await new Promise((resolve) => setTimeout(resolve, interval));
if (vi.isFakeTimers()) {
await vi.advanceTimersByTimeAsync(interval);
} else {
await new Promise((resolve) => setTimeout(resolve, interval));
}
});
}
}

View File

@@ -147,12 +147,28 @@ vi.mock('./hooks/useLogger.js');
vi.mock('./hooks/useInputHistoryStore.js');
vi.mock('./hooks/atCommandProcessor.js');
vi.mock('./hooks/useHookDisplayState.js');
vi.mock('./hooks/useBanner.js', () => ({
useBanner: vi.fn((bannerData) => ({
bannerText: (
bannerData.warningText ||
bannerData.defaultText ||
''
).replace(/\\n/g, '\n'),
})),
}));
vi.mock('./hooks/useShellInactivityStatus.js', () => ({
useShellInactivityStatus: vi.fn(() => ({
shouldShowFocusHint: false,
inactivityStatus: 'none',
})),
}));
vi.mock('./hooks/useTerminalTheme.js', () => ({
useTerminalTheme: vi.fn(),
}));
import { useHookDisplayState } from './hooks/useHookDisplayState.js';
import { useTerminalTheme } from './hooks/useTerminalTheme.js';
import { useShellInactivityStatus } from './hooks/useShellInactivityStatus.js';
// Mock external utilities
vi.mock('../utils/events.js');
@@ -256,6 +272,7 @@ describe('AppContainer State Management', () => {
const mockedUseInputHistoryStore = useInputHistoryStore as Mock;
const mockedUseHookDisplayState = useHookDisplayState as Mock;
const mockedUseTerminalTheme = useTerminalTheme as Mock;
const mockedUseShellInactivityStatus = useShellInactivityStatus as Mock;
const DEFAULT_GEMINI_STREAM_MOCK = {
streamingState: 'idle',
@@ -385,6 +402,10 @@ describe('AppContainer State Management', () => {
});
mockedUseHookDisplayState.mockReturnValue([]);
mockedUseTerminalTheme.mockReturnValue(undefined);
mockedUseShellInactivityStatus.mockReturnValue({
shouldShowFocusHint: false,
inactivityStatus: 'none',
});
// Mock Config
mockConfig = makeFakeConfig();
@@ -1247,8 +1268,15 @@ describe('AppContainer State Management', () => {
});
describe('Shell Focus Action Required', () => {
beforeEach(() => {
beforeEach(async () => {
vi.useFakeTimers();
// Use real implementation for these tests to verify title updates
const actual = await vi.importActual<
typeof import('./hooks/useShellInactivityStatus.js')
>('./hooks/useShellInactivityStatus.js');
mockedUseShellInactivityStatus.mockImplementation(
actual.useShellInactivityStatus,
);
});
afterEach(() => {