Migrate core render util to use xterm.js as part of the rendering loop. (#19044)

This commit is contained in:
Jacob Richman
2026-02-18 16:46:50 -08:00
committed by GitHub
parent 04c52513e7
commit 04f65f3d55
213 changed files with 7065 additions and 3852 deletions

View File

@@ -70,48 +70,58 @@ describe('<ModelDialog />', () => {
});
});
const renderComponent = (configValue = mockConfig as Config) =>
renderWithProviders(<ModelDialog onClose={mockOnClose} />, {
const renderComponent = async (configValue = mockConfig as Config) => {
const result = renderWithProviders(<ModelDialog onClose={mockOnClose} />, {
config: configValue,
});
await result.waitUntilReady();
return result;
};
it('renders the initial "main" view correctly', () => {
const { lastFrame } = renderComponent();
it('renders the initial "main" view correctly', async () => {
const { lastFrame, unmount } = await renderComponent();
expect(lastFrame()).toContain('Select Model');
expect(lastFrame()).toContain('Remember model for future sessions: false');
expect(lastFrame()).toContain('Auto');
expect(lastFrame()).toContain('Manual');
unmount();
});
it('switches to "manual" view when "Manual" is selected', async () => {
const { lastFrame, stdin } = renderComponent();
const { lastFrame, stdin, waitUntilReady, unmount } =
await renderComponent();
// Select "Manual" (index 1)
// Press down arrow to move to "Manual"
await act(async () => {
stdin.write('\u001B[B'); // Arrow Down
});
await waitUntilReady();
// Press enter to select
await act(async () => {
stdin.write('\r');
});
await waitUntilReady();
// Should now show manual options
await waitFor(() => {
expect(lastFrame()).toContain(DEFAULT_GEMINI_MODEL);
expect(lastFrame()).toContain(DEFAULT_GEMINI_FLASH_MODEL);
expect(lastFrame()).toContain(DEFAULT_GEMINI_FLASH_LITE_MODEL);
const output = lastFrame();
expect(output).toContain(DEFAULT_GEMINI_MODEL);
expect(output).toContain(DEFAULT_GEMINI_FLASH_MODEL);
expect(output).toContain(DEFAULT_GEMINI_FLASH_LITE_MODEL);
});
unmount();
});
it('sets model and closes when a model is selected in "main" view', async () => {
const { stdin } = renderComponent();
const { stdin, waitUntilReady, unmount } = await renderComponent();
// Select "Auto" (index 0)
await act(async () => {
stdin.write('\r');
});
await waitUntilReady();
await waitFor(() => {
expect(mockSetModel).toHaveBeenCalledWith(
@@ -120,32 +130,38 @@ describe('<ModelDialog />', () => {
);
expect(mockOnClose).toHaveBeenCalled();
});
unmount();
});
it('sets model and closes when a model is selected in "manual" view', async () => {
const { stdin } = renderComponent();
const { stdin, waitUntilReady, unmount } = await renderComponent();
// Navigate to Manual (index 1) and select
await act(async () => {
stdin.write('\u001B[B');
});
await waitUntilReady();
await act(async () => {
stdin.write('\r');
});
await waitUntilReady();
// Now in manual view. Default selection is first item (DEFAULT_GEMINI_MODEL)
await act(async () => {
stdin.write('\r');
});
await waitUntilReady();
await waitFor(() => {
expect(mockSetModel).toHaveBeenCalledWith(DEFAULT_GEMINI_MODEL, true);
expect(mockOnClose).toHaveBeenCalled();
});
unmount();
});
it('toggles persist mode with Tab key', async () => {
const { lastFrame, stdin } = renderComponent();
const { lastFrame, stdin, waitUntilReady, unmount } =
await renderComponent();
expect(lastFrame()).toContain('Remember model for future sessions: false');
@@ -153,6 +169,7 @@ describe('<ModelDialog />', () => {
await act(async () => {
stdin.write('\t');
});
await waitUntilReady();
await waitFor(() => {
expect(lastFrame()).toContain('Remember model for future sessions: true');
@@ -162,6 +179,7 @@ describe('<ModelDialog />', () => {
await act(async () => {
stdin.write('\r');
});
await waitUntilReady();
await waitFor(() => {
expect(mockSetModel).toHaveBeenCalledWith(
@@ -170,30 +188,39 @@ describe('<ModelDialog />', () => {
);
expect(mockOnClose).toHaveBeenCalled();
});
unmount();
});
it('closes dialog on escape in "main" view', async () => {
const { stdin } = renderComponent();
const { stdin, waitUntilReady, unmount } = await renderComponent();
await act(async () => {
stdin.write('\u001B'); // Escape
});
// Escape key has a 50ms timeout in KeypressContext, so we need to wrap waitUntilReady in act
await act(async () => {
await waitUntilReady();
});
await waitFor(() => {
expect(mockOnClose).toHaveBeenCalled();
});
unmount();
});
it('goes back to "main" view on escape in "manual" view', async () => {
const { lastFrame, stdin } = renderComponent();
const { lastFrame, stdin, waitUntilReady, unmount } =
await renderComponent();
// Go to manual view
await act(async () => {
stdin.write('\u001B[B');
});
await waitUntilReady();
await act(async () => {
stdin.write('\r');
});
await waitUntilReady();
await waitFor(() => {
expect(lastFrame()).toContain(DEFAULT_GEMINI_MODEL);
@@ -203,11 +230,15 @@ describe('<ModelDialog />', () => {
await act(async () => {
stdin.write('\u001B');
});
await act(async () => {
await waitUntilReady();
});
await waitFor(() => {
expect(mockOnClose).not.toHaveBeenCalled();
// Should be back to main view (Manual option visible)
expect(lastFrame()).toContain('Manual');
});
unmount();
});
});