Skip to content

Commit d7a0dbc

Browse files
fix(tests): fix flaky SettingsDialog tests (#8396)
Co-authored-by: Christie Warwick (Wilson) <bobcatfish@gmail.com>
1 parent 525ced2 commit d7a0dbc

File tree

1 file changed

+58
-26
lines changed

1 file changed

+58
-26
lines changed

packages/cli/src/ui/components/SettingsDialog.test.tsx

Lines changed: 58 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
*/
2323

2424
import { render } from 'ink-testing-library';
25-
import { waitFor } from '@testing-library/react';
2625
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2726
import { SettingsDialog } from './SettingsDialog.js';
2827
import { LoadedSettings, SettingScope } from '../../config/settings.js';
@@ -152,8 +151,32 @@ vi.mock('../../utils/settingsUtils.js', async () => {
152151
// const originalConsoleError = console.error;
153152

154153
describe('SettingsDialog', () => {
154+
// Simple delay function for remaining tests that need gradual migration
155155
const wait = (ms = 50) => new Promise((resolve) => setTimeout(resolve, ms));
156156

157+
// Custom waitFor utility for ink testing environment (not compatible with @testing-library/react)
158+
const waitFor = async (
159+
predicate: () => void,
160+
options: { timeout?: number; interval?: number } = {},
161+
) => {
162+
const { timeout = 1000, interval = 10 } = options;
163+
const start = Date.now();
164+
let lastError: unknown;
165+
while (Date.now() - start < timeout) {
166+
try {
167+
predicate();
168+
return;
169+
} catch (e) {
170+
lastError = e;
171+
}
172+
await new Promise((resolve) => setTimeout(resolve, interval));
173+
}
174+
if (lastError) {
175+
throw lastError;
176+
}
177+
throw new Error('waitFor timed out');
178+
};
179+
157180
beforeEach(() => {
158181
// Reset keypress mock state (variables are commented out)
159182
// currentKeypressHandler = null;
@@ -337,21 +360,36 @@ describe('SettingsDialog', () => {
337360
</KeypressProvider>
338361
);
339362

340-
const { stdin, unmount } = render(component);
363+
const { stdin, unmount, lastFrame } = render(component);
341364

342-
// Press Enter to toggle current setting
343-
stdin.write(TerminalKeys.DOWN_ARROW as string);
344-
await wait();
345-
stdin.write(TerminalKeys.ENTER as string);
346-
await wait();
365+
// Wait for initial render and verify we're on Vim Mode (first setting)
366+
await waitFor(() => {
367+
expect(lastFrame()).toContain('● Vim Mode');
368+
});
347369

348-
// Wait for the mock to be called with more generous timeout for Windows
349-
await waitFor(
350-
() => {
351-
expect(vi.mocked(saveModifiedSettings)).toHaveBeenCalled();
352-
},
353-
{ timeout: 1000 },
354-
);
370+
// Navigate to Disable Auto Update setting and verify we're there
371+
act(() => {
372+
stdin.write(TerminalKeys.DOWN_ARROW as string);
373+
});
374+
await waitFor(() => {
375+
expect(lastFrame()).toContain('● Disable Auto Update');
376+
});
377+
378+
// Toggle the setting
379+
act(() => {
380+
stdin.write(TerminalKeys.ENTER as string);
381+
});
382+
// Wait for the setting change to be processed
383+
await waitFor(() => {
384+
expect(
385+
vi.mocked(saveModifiedSettings).mock.calls.length,
386+
).toBeGreaterThan(0);
387+
});
388+
389+
// Wait for the mock to be called
390+
await waitFor(() => {
391+
expect(vi.mocked(saveModifiedSettings)).toHaveBeenCalled();
392+
});
355393

356394
expect(vi.mocked(saveModifiedSettings)).toHaveBeenCalledWith(
357395
new Set<string>(['general.disableAutoUpdate']),
@@ -428,12 +466,9 @@ describe('SettingsDialog', () => {
428466
await wait();
429467
stdin.write(TerminalKeys.ENTER as string);
430468
await wait();
431-
await waitFor(
432-
() => {
433-
expect(vi.mocked(saveModifiedSettings)).toHaveBeenCalled();
434-
},
435-
{ timeout: 1000 },
436-
);
469+
await waitFor(() => {
470+
expect(vi.mocked(saveModifiedSettings)).toHaveBeenCalled();
471+
});
437472

438473
expect(vi.mocked(saveModifiedSettings)).toHaveBeenCalledWith(
439474
new Set<string>(['ui.theme']),
@@ -468,12 +503,9 @@ describe('SettingsDialog', () => {
468503
await wait();
469504
stdin.write(TerminalKeys.ENTER as string);
470505
await wait();
471-
await waitFor(
472-
() => {
473-
expect(vi.mocked(saveModifiedSettings)).toHaveBeenCalled();
474-
},
475-
{ timeout: 1000 },
476-
);
506+
await waitFor(() => {
507+
expect(vi.mocked(saveModifiedSettings)).toHaveBeenCalled();
508+
});
477509

478510
expect(vi.mocked(saveModifiedSettings)).toHaveBeenCalledWith(
479511
new Set<string>(['ui.theme']),

0 commit comments

Comments
 (0)