test(cli): refactor tests for async render utilities (#23252)

This commit is contained in:
Tommaso Sciortino
2026-03-20 20:08:29 +00:00
committed by GitHub
parent 86a3a913b5
commit 6c78eb7a39
198 changed files with 3592 additions and 4802 deletions
@@ -22,19 +22,13 @@ const mockChats: ChatDetail[] = [
describe('<ChatList />', () => {
it('renders correctly with a list of chats', async () => {
const { lastFrame, unmount, waitUntilReady } = render(
<ChatList chats={mockChats} />,
);
await waitUntilReady();
const { lastFrame, unmount } = await render(<ChatList chats={mockChats} />);
expect(lastFrame()).toMatchSnapshot();
unmount();
});
it('renders correctly with no chats', async () => {
const { lastFrame, unmount, waitUntilReady } = render(
<ChatList chats={[]} />,
);
await waitUntilReady();
const { lastFrame, unmount } = await render(<ChatList chats={[]} />);
expect(lastFrame()).toContain('No saved conversation checkpoints found.');
expect(lastFrame()).toMatchSnapshot();
unmount();
@@ -47,10 +41,9 @@ describe('<ChatList />', () => {
mtime: 'an-invalid-date-string',
},
];
const { lastFrame, unmount, waitUntilReady } = render(
const { lastFrame, unmount } = await render(
<ChatList chats={mockChatsWithInvalidDate} />,
);
await waitUntilReady();
expect(lastFrame()).toContain('(Invalid Date)');
expect(lastFrame()).toMatchSnapshot();
unmount();
@@ -127,7 +127,7 @@ describe('ExtensionDetails', () => {
});
it('should call onLink when "l" is pressed and is linkable', async () => {
const { stdin, waitUntilReady } = await renderWithProviders(
const { stdin } = await renderWithProviders(
<ExtensionDetails
extension={linkableExtension}
onBack={mockOnBack}
@@ -136,7 +136,6 @@ describe('ExtensionDetails', () => {
isInstalled={false}
/>,
);
await waitUntilReady();
await React.act(async () => {
stdin.write('l');
});
@@ -146,15 +145,14 @@ describe('ExtensionDetails', () => {
});
it('should NOT show "Link" button for GitHub extensions', async () => {
const { lastFrame, waitUntilReady } = await renderDetails(false);
await waitUntilReady();
const { lastFrame } = await renderDetails(true);
await waitFor(() => {
expect(lastFrame()).not.toContain('[L] Link');
});
});
it('should show "Link" button for local extensions', async () => {
const { lastFrame, waitUntilReady } = await renderWithProviders(
const { lastFrame } = await renderWithProviders(
<ExtensionDetails
extension={linkableExtension}
onBack={mockOnBack}
@@ -163,7 +161,6 @@ describe('ExtensionDetails', () => {
isInstalled={false}
/>,
);
await waitUntilReady();
await waitFor(() => {
expect(lastFrame()).toContain('[L] Link');
});
@@ -139,8 +139,7 @@ describe('ExtensionRegistryView', () => {
);
it('should render extensions', async () => {
const { lastFrame, waitUntilReady } = await renderView();
await waitUntilReady();
const { lastFrame } = await renderView();
await waitFor(() => {
expect(lastFrame()).toContain('Test Extension 1');
@@ -57,20 +57,18 @@ describe('<ExtensionsList />', () => {
it('should render "No extensions installed." if there are no extensions', async () => {
mockUIState(new Map());
const { lastFrame, waitUntilReady, unmount } = render(
const { lastFrame, unmount } = await render(
<ExtensionsList extensions={[]} />,
);
await waitUntilReady();
expect(lastFrame()).toContain('No extensions installed.');
unmount();
});
it('should render a list of extensions with their version and status', async () => {
mockUIState(new Map());
const { lastFrame, waitUntilReady, unmount } = render(
const { lastFrame, unmount } = await render(
<ExtensionsList extensions={mockExtensions} />,
);
await waitUntilReady();
const output = lastFrame();
expect(output).toContain('ext-one (v1.0.0) - active');
expect(output).toContain('ext-two (v2.1.0) - active');
@@ -80,10 +78,9 @@ describe('<ExtensionsList />', () => {
it('should display "unknown state" if an extension has no update state', async () => {
mockUIState(new Map());
const { lastFrame, waitUntilReady, unmount } = render(
const { lastFrame, unmount } = await render(
<ExtensionsList extensions={[mockExtensions[0]]} />,
);
await waitUntilReady();
expect(lastFrame()).toContain('(unknown state)');
unmount();
});
@@ -122,10 +119,9 @@ describe('<ExtensionsList />', () => {
async ({ state, expectedText }) => {
const updateState = new Map([[mockExtensions[0].name, state]]);
mockUIState(updateState);
const { lastFrame, waitUntilReady, unmount } = render(
const { lastFrame, unmount } = await render(
<ExtensionsList extensions={[mockExtensions[0]]} />,
);
await waitUntilReady();
expect(lastFrame()).toContain(expectedText);
unmount();
},
@@ -160,10 +156,9 @@ describe('<ExtensionsList />', () => {
},
],
};
const { lastFrame, waitUntilReady, unmount } = render(
const { lastFrame, unmount } = await render(
<ExtensionsList extensions={[extensionWithSettings]} />,
);
await waitUntilReady();
const output = lastFrame();
expect(output).toContain('settings:');
expect(output).toContain('- sensitiveApiKey: ***');
@@ -54,40 +54,34 @@ describe('McpStatus', () => {
};
it('renders correctly with a connected server', async () => {
const { lastFrame, unmount, waitUntilReady } = render(
<McpStatus {...baseProps} />,
);
await waitUntilReady();
const { lastFrame, unmount } = await render(<McpStatus {...baseProps} />);
expect(lastFrame()).toMatchSnapshot();
unmount();
});
it('renders correctly with authenticated OAuth status', async () => {
const { lastFrame, unmount, waitUntilReady } = render(
const { lastFrame, unmount } = await render(
<McpStatus {...baseProps} authStatus={{ 'server-1': 'authenticated' }} />,
);
await waitUntilReady();
expect(lastFrame()).toMatchSnapshot();
unmount();
});
it('renders correctly with expired OAuth status', async () => {
const { lastFrame, unmount, waitUntilReady } = render(
const { lastFrame, unmount } = await render(
<McpStatus {...baseProps} authStatus={{ 'server-1': 'expired' }} />,
);
await waitUntilReady();
expect(lastFrame()).toMatchSnapshot();
unmount();
});
it('renders correctly with unauthenticated OAuth status', async () => {
const { lastFrame, unmount, waitUntilReady } = render(
const { lastFrame, unmount } = await render(
<McpStatus
{...baseProps}
authStatus={{ 'server-1': 'unauthenticated' }}
/>,
);
await waitUntilReady();
expect(lastFrame()).toMatchSnapshot();
unmount();
});
@@ -97,34 +91,29 @@ describe('McpStatus', () => {
await import('@google/gemini-cli-core'),
'getMCPServerStatus',
).mockReturnValue(MCPServerStatus.DISCONNECTED);
const { lastFrame, unmount, waitUntilReady } = render(
<McpStatus {...baseProps} />,
);
await waitUntilReady();
const { lastFrame, unmount } = await render(<McpStatus {...baseProps} />);
expect(lastFrame()).toMatchSnapshot();
unmount();
});
it('renders correctly when discovery is in progress', async () => {
const { lastFrame, unmount, waitUntilReady } = render(
const { lastFrame, unmount } = await render(
<McpStatus {...baseProps} discoveryInProgress={true} />,
);
await waitUntilReady();
expect(lastFrame()).toMatchSnapshot();
unmount();
});
it('renders correctly with schema enabled', async () => {
const { lastFrame, unmount, waitUntilReady } = render(
const { lastFrame, unmount } = await render(
<McpStatus {...baseProps} showSchema={true} />,
);
await waitUntilReady();
expect(lastFrame()).toMatchSnapshot();
unmount();
});
it('renders correctly with parametersJsonSchema', async () => {
const { lastFrame, unmount, waitUntilReady } = render(
const { lastFrame, unmount } = await render(
<McpStatus
{...baseProps}
tools={[
@@ -145,13 +134,12 @@ describe('McpStatus', () => {
showSchema={true}
/>,
);
await waitUntilReady();
expect(lastFrame()).toMatchSnapshot();
unmount();
});
it('renders correctly with prompts', async () => {
const { lastFrame, unmount, waitUntilReady } = render(
const { lastFrame, unmount } = await render(
<McpStatus
{...baseProps}
prompts={[
@@ -163,13 +151,12 @@ describe('McpStatus', () => {
]}
/>,
);
await waitUntilReady();
expect(lastFrame()).toMatchSnapshot();
unmount();
});
it('renders correctly with resources', async () => {
const { lastFrame, unmount, waitUntilReady } = render(
const { lastFrame, unmount } = await render(
<McpStatus
{...baseProps}
resources={[
@@ -182,25 +169,23 @@ describe('McpStatus', () => {
]}
/>,
);
await waitUntilReady();
expect(lastFrame()).toMatchSnapshot();
unmount();
});
it('renders correctly with a blocked server', async () => {
const { lastFrame, unmount, waitUntilReady } = render(
const { lastFrame, unmount } = await render(
<McpStatus
{...baseProps}
blockedServers={[{ name: 'server-1', extensionName: 'test-extension' }]}
/>,
);
await waitUntilReady();
expect(lastFrame()).toMatchSnapshot();
unmount();
});
it('renders correctly with both blocked and unblocked servers', async () => {
const { lastFrame, unmount, waitUntilReady } = render(
const { lastFrame, unmount } = await render(
<McpStatus
{...baseProps}
servers={{
@@ -213,41 +198,37 @@ describe('McpStatus', () => {
blockedServers={[{ name: 'server-2', extensionName: 'test-extension' }]}
/>,
);
await waitUntilReady();
expect(lastFrame()).toMatchSnapshot();
unmount();
});
it('renders only blocked servers when no configured servers exist', async () => {
const { lastFrame, unmount, waitUntilReady } = render(
const { lastFrame, unmount } = await render(
<McpStatus
{...baseProps}
servers={{}}
blockedServers={[{ name: 'server-1', extensionName: 'test-extension' }]}
/>,
);
await waitUntilReady();
expect(lastFrame()).toMatchSnapshot();
unmount();
});
it('renders correctly with a connecting server', async () => {
const { lastFrame, unmount, waitUntilReady } = render(
const { lastFrame, unmount } = await render(
<McpStatus {...baseProps} connectingServers={['server-1']} />,
);
await waitUntilReady();
expect(lastFrame()).toMatchSnapshot();
unmount();
});
it('renders correctly with a server error', async () => {
const { lastFrame, unmount, waitUntilReady } = render(
const { lastFrame, unmount } = await render(
<McpStatus
{...baseProps}
errors={{ 'server-1': 'Failed to connect to server' }}
/>,
);
await waitUntilReady();
expect(lastFrame()).toMatchSnapshot();
unmount();
});
@@ -259,10 +240,9 @@ describe('McpStatus', () => {
uri: `file:///tmp/resource-${i + 1}.txt`,
}));
const { lastFrame, unmount, waitUntilReady } = render(
const { lastFrame, unmount } = await render(
<McpStatus {...baseProps} resources={manyResources} />,
);
await waitUntilReady();
expect(lastFrame()).toContain('15 resources hidden');
unmount();
});
@@ -35,10 +35,9 @@ describe('SkillsList Component', () => {
];
it('should render enabled and disabled skills separately', async () => {
const { lastFrame, unmount, waitUntilReady } = render(
const { lastFrame, unmount } = await render(
<SkillsList skills={mockSkills} showDescriptions={true} />,
);
await waitUntilReady();
const output = lastFrame();
expect(output).toContain('Available Agent Skills:');
@@ -55,10 +54,9 @@ describe('SkillsList Component', () => {
});
it('should not render descriptions when showDescriptions is false', async () => {
const { lastFrame, unmount, waitUntilReady } = render(
const { lastFrame, unmount } = await render(
<SkillsList skills={mockSkills} showDescriptions={false} />,
);
await waitUntilReady();
const output = lastFrame();
expect(output).toContain('skill1');
@@ -72,10 +70,9 @@ describe('SkillsList Component', () => {
});
it('should render "No skills available" when skills list is empty', async () => {
const { lastFrame, unmount, waitUntilReady } = render(
const { lastFrame, unmount } = await render(
<SkillsList skills={[]} showDescriptions={true} />,
);
await waitUntilReady();
const output = lastFrame();
expect(output).toContain('No skills available');
@@ -85,10 +82,9 @@ describe('SkillsList Component', () => {
it('should only render Available Agent Skills section when all skills are enabled', async () => {
const enabledOnly = mockSkills.filter((s) => !s.disabled);
const { lastFrame, unmount, waitUntilReady } = render(
const { lastFrame, unmount } = await render(
<SkillsList skills={enabledOnly} showDescriptions={true} />,
);
await waitUntilReady();
const output = lastFrame();
expect(output).toContain('Available Agent Skills:');
@@ -99,10 +95,9 @@ describe('SkillsList Component', () => {
it('should only render Disabled Skills section when all skills are disabled', async () => {
const disabledOnly = mockSkills.filter((s) => s.disabled);
const { lastFrame, unmount, waitUntilReady } = render(
const { lastFrame, unmount } = await render(
<SkillsList skills={disabledOnly} showDescriptions={true} />,
);
await waitUntilReady();
const output = lastFrame();
expect(output).not.toContain('Available Agent Skills:');
@@ -121,10 +116,9 @@ describe('SkillsList Component', () => {
isBuiltin: true,
};
const { lastFrame, unmount, waitUntilReady } = render(
const { lastFrame, unmount } = await render(
<SkillsList skills={[builtinSkill]} showDescriptions={true} />,
);
await waitUntilReady();
const output = lastFrame();
expect(output).toContain('builtin-skill');
@@ -32,34 +32,31 @@ const mockTools: ToolDefinition[] = [
describe('<ToolsList />', () => {
it('renders correctly with descriptions', async () => {
const { lastFrame, waitUntilReady } = await renderWithProviders(
const { lastFrame } = await renderWithProviders(
<ToolsList
tools={mockTools}
showDescriptions={true}
terminalWidth={40}
/>,
);
await waitUntilReady();
expect(lastFrame()).toMatchSnapshot();
});
it('renders correctly without descriptions', async () => {
const { lastFrame, waitUntilReady } = await renderWithProviders(
const { lastFrame } = await renderWithProviders(
<ToolsList
tools={mockTools}
showDescriptions={false}
terminalWidth={40}
/>,
);
await waitUntilReady();
expect(lastFrame()).toMatchSnapshot();
});
it('renders correctly with no tools', async () => {
const { lastFrame, waitUntilReady } = await renderWithProviders(
const { lastFrame } = await renderWithProviders(
<ToolsList tools={[]} showDescriptions={true} terminalWidth={40} />,
);
await waitUntilReady();
expect(lastFrame()).toMatchSnapshot();
});
});