chore(ui): repair failing vitest tests after shadcn migration (batch B)

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
This commit is contained in:
Cursor Agent 2026-04-24 15:14:09 +00:00
parent a55a2bae7e
commit 484741b5f7
No known key found for this signature in database
3 changed files with 49 additions and 61 deletions

View file

@ -36,7 +36,7 @@ const MOCK_POSTS = [
async function openDropdown() {
const user = userEvent.setup();
await user.hover(screen.getByRole("button", { name: /blog/i }));
await user.click(screen.getByRole("button", { name: /blog/i }));
}
describe("BlogDropdown", () => {
@ -74,7 +74,7 @@ describe("BlogDropdown", () => {
await openDropdown();
await waitFor(() => {
expect(document.querySelector(".anticon-loading")).toBeInTheDocument();
expect(document.querySelector(".lucide-loader-circle")).toBeInTheDocument();
});
});
});
@ -108,7 +108,7 @@ describe("BlogDropdown", () => {
const user = userEvent.setup();
renderWithProviders(<BlogDropdown />);
await user.hover(screen.getByRole("button", { name: /blog/i }));
await user.click(screen.getByRole("button", { name: /blog/i }));
await waitFor(() => {
expect(screen.getByRole("button", { name: /retry/i })).toBeInTheDocument();
@ -177,7 +177,7 @@ describe("BlogDropdown", () => {
await openDropdown();
await waitFor(() => {
const link = screen.getByRole("link", { name: /post one/i });
const link = screen.getByRole("menuitem", { name: /post one/i });
expect(link).toHaveAttribute("href", "https://example.com/1");
expect(link).toHaveAttribute("target", "_blank");
expect(link).toHaveAttribute("rel", "noopener noreferrer");
@ -204,7 +204,7 @@ describe("BlogDropdown", () => {
await openDropdown();
await waitFor(() => {
const viewAllLink = screen.getByRole("link", { name: /view all posts/i });
const viewAllLink = screen.getByRole("menuitem", { name: /view all posts/i });
expect(viewAllLink).toHaveAttribute("href", "https://docs.litellm.ai/blog");
expect(viewAllLink).toHaveAttribute("target", "_blank");
expect(viewAllLink).toHaveAttribute("rel", "noopener noreferrer");

View file

@ -67,34 +67,27 @@ describe("ChatUI", () => {
expect(getByText("Test Key")).toBeInTheDocument();
});
// Find the endpoint selector by looking for the "Endpoint Type:" text and its associated Select
// The endpoint selector is a shadcn Select (role=combobox). There is one
// other combobox on the page (MCP servers) so we scope by the "Endpoint
// Type" label.
const endpointTypeText = getByText("Endpoint Type");
const selectContainer = endpointTypeText.parentElement;
const selectElement = selectContainer?.querySelector(".ant-select-selector");
const selectContainer = endpointTypeText.parentElement as HTMLElement;
const endpointCombobox = selectContainer.querySelector('[role="combobox"]') as HTMLElement;
expect(endpointCombobox).toBeInTheDocument();
expect(selectElement).toBeInTheDocument();
const user = (await import("@testing-library/user-event")).default.setup();
await user.click(endpointCombobox);
// Click on the select to open the dropdown
if (selectElement) {
fireEvent.mouseDown(selectElement);
}
// Wait for the dropdown to appear and find the audio_speech option
await waitFor(() => {
const audioSpeechOption = screen.getByText("/v1/audio/speech");
expect(audioSpeechOption).toBeInTheDocument();
});
// Click on the audio_speech option
const audioSpeechOption = screen.getByText("/v1/audio/speech");
fireEvent.click(audioSpeechOption);
// Wait for the dropdown to appear and pick the audio_speech option
const audioSpeechOption = await screen.findByRole("option", { name: "/v1/audio/speech" });
await user.click(audioSpeechOption);
// Verify the voice selector appears
await waitFor(() => {
expect(getByText("Voice")).toBeInTheDocument();
});
// Verify the voice select component is present
// The Voice select is still an antd Select component
const voiceText = getByText("Voice");
const voiceSelectContainer = voiceText.parentElement;
const voiceSelectElement = voiceSelectContainer?.querySelector(".ant-select");
@ -154,14 +147,14 @@ describe("ChatUI", () => {
expect(getByText("Test Key")).toBeInTheDocument();
});
// Open endpoint selector and explicitly select /v1/chat/completions
// Open endpoint selector (shadcn Select) and explicitly select /v1/chat/completions
const endpointTypeText = getByText("Endpoint Type");
const endpointSelect = endpointTypeText.parentElement?.querySelector(".ant-select-selector");
expect(endpointSelect).toBeTruthy();
act(() => {
fireEvent.mouseDown(endpointSelect!);
fireEvent.click(screen.getByText("/v1/chat/completions"));
});
const endpointCombobox = endpointTypeText.parentElement?.querySelector('[role="combobox"]') as HTMLElement;
expect(endpointCombobox).toBeTruthy();
const user = (await import("@testing-library/user-event")).default.setup();
await user.click(endpointCombobox);
const chatOption = await screen.findByRole("option", { name: "/v1/chat/completions" });
await user.click(chatOption);
// Open model selector
const selectModelLabel = getByText("Select Model");
@ -234,21 +227,14 @@ describe("ChatUI", () => {
});
const endpointTypeText = screen.getByText("Endpoint Type");
const endpointSelect = endpointTypeText.parentElement?.querySelector(".ant-select-selector") as HTMLElement | null;
expect(endpointSelect).not.toBeNull();
const endpointCombobox = endpointTypeText.parentElement?.querySelector('[role="combobox"]') as HTMLElement | null;
expect(endpointCombobox).not.toBeNull();
const user = (await import("@testing-library/user-event")).default.setup();
const selectEndpointOption = async (label: string) => {
act(() => {
fireEvent.mouseDown(endpointSelect!);
});
await waitFor(() => {
expect(screen.getByText(label)).toBeInTheDocument();
});
act(() => {
fireEvent.click(screen.getByText(label));
});
await user.click(endpointCombobox!);
const option = await screen.findByRole("option", { name: label });
await user.click(option);
};
const getMcpSelect = () =>
@ -391,24 +377,25 @@ describe("ChatUI", () => {
const mcpServersText = screen.queryByText("MCP Servers");
expect(mcpServersText).toBeInTheDocument();
if (mcpServersText) {
const selectContainer = mcpServersText.parentElement?.nextElementSibling;
const selectElement = selectContainer?.querySelector(".ant-select-selector");
expect(selectElement).toBeInTheDocument();
// The MCP Servers select is the antd Select whose placeholder is "Select
// MCP servers". It lives below the "MCP Servers" label.
const mcpSelectInput = document.querySelector<HTMLElement>(
"input.ant-select-selection-search-input",
);
expect(mcpSelectInput).toBeInTheDocument();
if (selectElement) {
fireEvent.mouseDown(selectElement);
const mcpSelect = mcpSelectInput!.closest(".ant-select") as HTMLElement;
const selector = mcpSelect.querySelector(".ant-select-selector") as HTMLElement;
fireEvent.mouseDown(selector);
await waitFor(() => {
const allServersOption = screen.queryByText("All MCP Servers");
if (allServersOption) {
expect(allServersOption).toBeInTheDocument();
}
});
const searchInput = document.querySelector(".ant-select-selection-search-input");
expect(searchInput).toBeInTheDocument();
await waitFor(() => {
const allServersOption = screen.queryByText("All MCP Servers");
if (allServersOption) {
expect(allServersOption).toBeInTheDocument();
}
}
});
// showSearch on antd Select yields a search input inside .ant-select
expect(mcpSelect.querySelector("input.ant-select-selection-search-input")).toBeInTheDocument();
});
});

View file

@ -14,7 +14,8 @@ describe("EndpointSelector", () => {
});
});
it("should filter and show audio endpoints when user inputs 'audio'", async () => {
// TODO: shadcn migration — shadcn/Radix Select does not expose a typeahead filter input, so the old "type to filter" behavior cannot be asserted here.
it.skip("should filter and show audio endpoints when user inputs 'audio'", async () => {
const user = userEvent.setup();
render(<EndpointSelector endpointType={ENDPOINT_OPTIONS[0].value} onEndpointChange={() => {}} />);