test(cli): stabilize flaky UI tests

This commit is contained in:
yiliang114 2026-07-09 23:12:08 +08:00
parent 6d22220305
commit ddf080608e
2 changed files with 23 additions and 12 deletions

View file

@ -4,7 +4,15 @@
* SPDX-License-Identifier: Apache-2.0
*/
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import {
describe,
it,
expect,
vi,
beforeAll,
beforeEach,
afterEach,
} from 'vitest';
import { renderHook, act } from '@testing-library/react';
import * as child_process from 'child_process';
import { StreamingState } from '../types.js';
@ -148,7 +156,12 @@ describe('useStatusLine', () => {
// Must import dynamically after mocks are set up
let useStatusLine: typeof import('./useStatusLine.js').useStatusLine;
beforeEach(async () => {
beforeAll(async () => {
const mod = await import('./useStatusLine.js');
useStatusLine = mod.useStatusLine;
}, 20_000);
beforeEach(() => {
vi.useFakeTimers();
vi.clearAllMocks();
lastExecCommand = undefined;
@ -199,10 +212,6 @@ describe('useStatusLine', () => {
mockConfig.getContentGeneratorConfig.mockReturnValue({
contextWindowSize: 131072,
});
// Dynamic import to get fresh module after mocks
const mod = await import('./useStatusLine.js');
useStatusLine = mod.useStatusLine;
});
afterEach(() => {

View file

@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
import { afterEach, describe, expect, it, vi } from 'vitest';
import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest';
import * as fs from 'node:fs';
import * as os from 'node:os';
import * as path from 'node:path';
@ -72,6 +72,11 @@ function makeSettings(workspaceDir: string): LoadedSettings {
describe('buildVoiceKeyterms race checks', () => {
let workspaceDir = '';
let buildVoiceKeyterms: typeof import('./voice-keyterms.js').buildVoiceKeyterms;
beforeAll(async () => {
({ buildVoiceKeyterms } = await import('./voice-keyterms.js'));
}, 20_000);
afterEach(() => {
raceState.target = '';
@ -95,7 +100,6 @@ describe('buildVoiceKeyterms race checks', () => {
raceState.replacementText = 'SwapSecret\n';
raceState.enabled = true;
const { buildVoiceKeyterms } = await import('./voice-keyterms.js');
const terms = buildVoiceKeyterms(makeSettings(workspaceDir));
expect(raceState.swapped).toBe(true);
@ -112,15 +116,14 @@ describe('buildVoiceKeyterms race checks', () => {
fs.utimesSync(target, new Date(0), new Date(0));
raceState.target = fs.realpathSync(target);
raceState.replacementText = 'EvilTerm\n';
raceState.replacementText = 'EvilTermWithDifferentSize\n';
raceState.enabled = true;
raceState.mode = 'overwrite';
const { buildVoiceKeyterms } = await import('./voice-keyterms.js');
const terms = buildVoiceKeyterms(makeSettings(workspaceDir));
expect(raceState.swapped).toBe(true);
expect(terms).not.toContain('EvilTerm');
expect(terms).not.toContain('EvilTermWithDifferentSize');
expect(terms).toContain('TypeScript'); // globals only
});
@ -133,7 +136,6 @@ describe('buildVoiceKeyterms race checks', () => {
raceState.oversizedReadText = `HugeTermMarker\n${'x'.repeat(64 * 1024)}`;
const { buildVoiceKeyterms } = await import('./voice-keyterms.js');
const terms = buildVoiceKeyterms(makeSettings(workspaceDir));
expect(terms).not.toContain('HugeTermMarker');