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

@@ -67,10 +67,11 @@ describe('ValidationDialog', () => {
});
describe('initial render (choosing state)', () => {
it('should render the main message and two options', () => {
const { lastFrame, unmount } = render(
it('should render the main message and two options', async () => {
const { lastFrame, waitUntilReady, unmount } = render(
<ValidationDialog onChoice={mockOnChoice} />,
);
await waitUntilReady();
expect(lastFrame()).toContain(
'Further action is required to use this service.',
@@ -95,27 +96,31 @@ describe('ValidationDialog', () => {
unmount();
});
it('should render learn more URL when provided', () => {
const { lastFrame, unmount } = render(
it('should render learn more URL when provided', async () => {
const { lastFrame, waitUntilReady, unmount } = render(
<ValidationDialog
learnMoreUrl="https://example.com/help"
onChoice={mockOnChoice}
/>,
);
await waitUntilReady();
expect(lastFrame()).toContain('Learn more:');
expect(lastFrame()).toContain('https://example.com/help');
unmount();
});
it('should call onChoice with cancel when ESCAPE is pressed', () => {
const { unmount } = render(<ValidationDialog onChoice={mockOnChoice} />);
it('should call onChoice with cancel when ESCAPE is pressed', async () => {
const { waitUntilReady, unmount } = render(
<ValidationDialog onChoice={mockOnChoice} />,
);
await waitUntilReady();
// Verify the keypress hook is active
expect(mockKeypressOptions.isActive).toBe(true);
// Simulate ESCAPE key press
act(() => {
await act(async () => {
mockKeypressHandler({
name: 'escape',
ctrl: false,
@@ -126,6 +131,10 @@ describe('ValidationDialog', () => {
sequence: '\x1b',
});
});
// Escape key has a 50ms timeout in KeypressContext, so we need to wrap waitUntilReady in act
await act(async () => {
await waitUntilReady();
});
expect(mockOnChoice).toHaveBeenCalledWith('cancel');
unmount();
@@ -133,42 +142,52 @@ describe('ValidationDialog', () => {
});
describe('onChoice handling', () => {
it('should call onChoice with change_auth when that option is selected', () => {
const { unmount } = render(<ValidationDialog onChoice={mockOnChoice} />);
it('should call onChoice with change_auth when that option is selected', async () => {
const { waitUntilReady, unmount } = render(
<ValidationDialog onChoice={mockOnChoice} />,
);
await waitUntilReady();
const onSelect = (RadioButtonSelect as Mock).mock.calls[0][0].onSelect;
act(() => {
await act(async () => {
onSelect('change_auth');
});
await waitUntilReady();
expect(mockOnChoice).toHaveBeenCalledWith('change_auth');
unmount();
});
it('should call onChoice with verify when no validation link is provided', () => {
const { unmount } = render(<ValidationDialog onChoice={mockOnChoice} />);
it('should call onChoice with verify when no validation link is provided', async () => {
const { waitUntilReady, unmount } = render(
<ValidationDialog onChoice={mockOnChoice} />,
);
await waitUntilReady();
const onSelect = (RadioButtonSelect as Mock).mock.calls[0][0].onSelect;
act(() => {
await act(async () => {
onSelect('verify');
});
await waitUntilReady();
expect(mockOnChoice).toHaveBeenCalledWith('verify');
unmount();
});
it('should open browser and transition to waiting state when verify is selected with a link', async () => {
const { lastFrame, unmount } = render(
const { lastFrame, waitUntilReady, unmount } = render(
<ValidationDialog
validationLink="https://accounts.google.com/verify"
onChoice={mockOnChoice}
/>,
);
await waitUntilReady();
const onSelect = (RadioButtonSelect as Mock).mock.calls[0][0].onSelect;
await act(async () => {
await onSelect('verify');
});
await waitUntilReady();
expect(mockOpenBrowserSecurely).toHaveBeenCalledWith(
'https://accounts.google.com/verify',
@@ -182,17 +201,19 @@ describe('ValidationDialog', () => {
it('should show URL in message when browser cannot be launched', async () => {
mockShouldLaunchBrowser.mockReturnValue(false);
const { lastFrame, unmount } = render(
const { lastFrame, waitUntilReady, unmount } = render(
<ValidationDialog
validationLink="https://accounts.google.com/verify"
onChoice={mockOnChoice}
/>,
);
await waitUntilReady();
const onSelect = (RadioButtonSelect as Mock).mock.calls[0][0].onSelect;
await act(async () => {
await onSelect('verify');
});
await waitUntilReady();
expect(mockOpenBrowserSecurely).not.toHaveBeenCalled();
expect(lastFrame()).toContain('Please open this URL in a browser:');
@@ -205,17 +226,19 @@ describe('ValidationDialog', () => {
it('should show error and options when browser fails to open', async () => {
mockOpenBrowserSecurely.mockRejectedValue(new Error('Browser not found'));
const { lastFrame, unmount } = render(
const { lastFrame, waitUntilReady, unmount } = render(
<ValidationDialog
validationLink="https://accounts.google.com/verify"
onChoice={mockOnChoice}
/>,
);
await waitUntilReady();
const onSelect = (RadioButtonSelect as Mock).mock.calls[0][0].onSelect;
await act(async () => {
await onSelect('verify');
});
await waitUntilReady();
expect(lastFrame()).toContain('Browser not found');
// RadioButtonSelect should be rendered again with options in error state