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
@@ -30,38 +30,42 @@ describe('ThemeDialog Snapshots', () => {
vi.restoreAllMocks();
});
it('should render correctly in theme selection mode', () => {
it('should render correctly in theme selection mode', async () => {
const settings = createMockSettings();
const { lastFrame } = renderWithProviders(
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
<ThemeDialog {...baseProps} settings={settings} />,
{ settings },
);
await waitUntilReady();
expect(lastFrame()).toMatchSnapshot();
unmount();
});
it('should render correctly in scope selector mode', async () => {
const settings = createMockSettings();
const { lastFrame, stdin } = renderWithProviders(
const { lastFrame, stdin, waitUntilReady, unmount } = renderWithProviders(
<ThemeDialog {...baseProps} settings={settings} />,
{ settings },
);
await waitUntilReady();
// Press Tab to switch to scope selector mode
act(() => {
await act(async () => {
stdin.write('\t');
});
// Need to wait for the state update to propagate
await new Promise((resolve) => setTimeout(resolve, 100));
await waitUntilReady();
expect(lastFrame()).toMatchSnapshot();
unmount();
});
it('should call onCancel when ESC is pressed', async () => {
const mockOnCancel = vi.fn();
const settings = createMockSettings();
const { stdin } = renderWithProviders(
const { stdin, waitUntilReady, unmount } = renderWithProviders(
<ThemeDialog
{...baseProps}
onCancel={mockOnCancel}
@@ -69,33 +73,43 @@ describe('ThemeDialog Snapshots', () => {
/>,
{ settings },
);
await waitUntilReady();
act(() => {
await act(async () => {
stdin.write('\x1b');
});
// ESC key has a 50ms timeout in KeypressContext, so we need to wrap waitUntilReady in act
await act(async () => {
await waitUntilReady();
});
await waitFor(() => {
expect(mockOnCancel).toHaveBeenCalled();
});
unmount();
});
it('should call onSelect when a theme is selected', async () => {
const settings = createMockSettings();
const { stdin } = renderWithProviders(
const { stdin, waitUntilReady, unmount } = renderWithProviders(
<ThemeDialog {...baseProps} settings={settings} />,
{
settings,
},
);
await waitUntilReady();
// Press Enter to select the theme
act(() => {
await act(async () => {
stdin.write('\r');
});
await waitUntilReady();
await waitFor(() => {
expect(baseProps.onSelect).toHaveBeenCalled();
});
unmount();
});
});
@@ -112,47 +126,53 @@ describe('Initial Theme Selection', () => {
vi.restoreAllMocks();
});
it('should default to a light theme when terminal background is light and no theme is set', () => {
it('should default to a light theme when terminal background is light and no theme is set', async () => {
const settings = createMockSettings(); // No theme set
const { lastFrame } = renderWithProviders(
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
<ThemeDialog {...baseProps} settings={settings} />,
{
settings,
uiState: { terminalBackgroundColor: '#FFFFFF' }, // Light background
},
);
await waitUntilReady();
// The snapshot will show which theme is highlighted.
// We expect 'DefaultLight' to be the one with the '>' indicator.
expect(lastFrame()).toMatchSnapshot();
unmount();
});
it('should default to a dark theme when terminal background is dark and no theme is set', () => {
it('should default to a dark theme when terminal background is dark and no theme is set', async () => {
const settings = createMockSettings(); // No theme set
const { lastFrame } = renderWithProviders(
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
<ThemeDialog {...baseProps} settings={settings} />,
{
settings,
uiState: { terminalBackgroundColor: '#000000' }, // Dark background
},
);
await waitUntilReady();
// We expect 'DefaultDark' to be highlighted.
expect(lastFrame()).toMatchSnapshot();
unmount();
});
it('should use the theme from settings even if terminal background suggests a different theme type', () => {
it('should use the theme from settings even if terminal background suggests a different theme type', async () => {
const settings = createMockSettings({ ui: { theme: 'DefaultLight' } }); // Light theme set
const { lastFrame } = renderWithProviders(
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
<ThemeDialog {...baseProps} settings={settings} />,
{
settings,
uiState: { terminalBackgroundColor: '#000000' }, // Dark background
},
);
await waitUntilReady();
// We expect 'DefaultLight' to be highlighted, respecting the settings.
expect(lastFrame()).toMatchSnapshot();
unmount();
});
});
@@ -165,29 +185,33 @@ describe('Hint Visibility', () => {
terminalWidth: 120,
};
it('should show hint when theme background matches terminal background', () => {
it('should show hint when theme background matches terminal background', async () => {
const settings = createMockSettings({ ui: { theme: 'Default' } });
const { lastFrame } = renderWithProviders(
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
<ThemeDialog {...baseProps} settings={settings} />,
{
settings,
uiState: { terminalBackgroundColor: '#1E1E2E' },
},
);
await waitUntilReady();
expect(lastFrame()).toContain('(Matches terminal)');
unmount();
});
it('should not show hint when theme background does not match terminal background', () => {
it('should not show hint when theme background does not match terminal background', async () => {
const settings = createMockSettings({ ui: { theme: 'Default' } });
const { lastFrame } = renderWithProviders(
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
<ThemeDialog {...baseProps} settings={settings} />,
{
settings,
uiState: { terminalBackgroundColor: '#FFFFFF' },
},
);
await waitUntilReady();
expect(lastFrame()).not.toContain('(Matches terminal)');
unmount();
});
});