From 58a9c3f2a2896fae1dadd2183b0d24c0b496a575 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sat, 28 Feb 2026 06:47:22 +0000 Subject: [PATCH] fix(ui): prevent MCP and TeamInfo test timeouts on CI - Add userEvent.setup({ delay: null }) to all tests using userEvent in both files - Add timeout: 15000 to tests with significant user interaction (typing, multiple clicks) - Fixes: create_mcp_server Bearer Token test, TeamInfo cancel button test Co-authored-by: Ishaan Jaff --- .../mcp_tools/create_mcp_server.test.tsx | 212 +++++++++--------- .../src/components/team/TeamInfo.test.tsx | 24 +- 2 files changed, 124 insertions(+), 112 deletions(-) diff --git a/ui/litellm-dashboard/src/components/mcp_tools/create_mcp_server.test.tsx b/ui/litellm-dashboard/src/components/mcp_tools/create_mcp_server.test.tsx index a52f692b3e7..28c3b75c3a3 100644 --- a/ui/litellm-dashboard/src/components/mcp_tools/create_mcp_server.test.tsx +++ b/ui/litellm-dashboard/src/components/mcp_tools/create_mcp_server.test.tsx @@ -134,91 +134,99 @@ describe("CreateMCPServer", () => { }); }); - it("should not require auth value when creating a server with API Key auth type", async () => { - await selectHttpTransport(); + it( + "should not require auth value when creating a server with API Key auth type", + { timeout: 15000 }, + async () => { + await selectHttpTransport(); - const user = userEvent.setup(); + const user = userEvent.setup({ delay: null }); - // Fill in server name (use id to avoid duplicate placeholder) - const nameInput = getServerNameInput(); - await user.type(nameInput, "Test_Server"); + // Fill in server name (use id to avoid duplicate placeholder) + const nameInput = getServerNameInput(); + await user.type(nameInput, "Test_Server"); - // Fill in URL - const urlInput = screen.getByPlaceholderText("https://your-mcp-server.com"); - await user.type(urlInput, "https://example.com/mcp"); + // Fill in URL + const urlInput = screen.getByPlaceholderText("https://your-mcp-server.com"); + await user.type(urlInput, "https://example.com/mcp"); - // Select API Key auth type - await selectAntOption("Authentication", "API Key"); + // Select API Key auth type + await selectAntOption("Authentication", "API Key"); - await waitFor(() => { - expect(screen.getByText("Authentication Value")).toBeInTheDocument(); - }); + await waitFor(() => { + expect(screen.getByText("Authentication Value")).toBeInTheDocument(); + }); - // Leave auth value empty and submit - vi.mocked(networking.createMCPServer).mockResolvedValue({ - server_id: "new-server-1", - server_name: "Test_Server", - alias: "Test_Server", - url: "https://example.com/mcp", - transport: "http", - auth_type: "api_key", - created_at: "2024-01-01T00:00:00Z", - created_by: "user-1", - updated_at: "2024-01-01T00:00:00Z", - updated_by: "user-1", - }); + // Leave auth value empty and submit + vi.mocked(networking.createMCPServer).mockResolvedValue({ + server_id: "new-server-1", + server_name: "Test_Server", + alias: "Test_Server", + url: "https://example.com/mcp", + transport: "http", + auth_type: "api_key", + created_at: "2024-01-01T00:00:00Z", + created_by: "user-1", + updated_at: "2024-01-01T00:00:00Z", + updated_by: "user-1", + }); - const submitButton = screen.getByRole("button", { name: "Add MCP Server" }); - await act(async () => { - fireEvent.click(submitButton); - }); + const submitButton = screen.getByRole("button", { name: "Add MCP Server" }); + await act(async () => { + fireEvent.click(submitButton); + }); - // The form should submit without validation error on auth_value - await waitFor(() => { - expect(networking.createMCPServer).toHaveBeenCalledTimes(1); - }); - }); + // The form should submit without validation error on auth_value + await waitFor(() => { + expect(networking.createMCPServer).toHaveBeenCalledTimes(1); + }); + }, + ); - it("should not require auth value when creating a server with Bearer Token auth type", async () => { - await selectHttpTransport(); + it( + "should not require auth value when creating a server with Bearer Token auth type", + { timeout: 15000 }, + async () => { + await selectHttpTransport(); - const user = userEvent.setup(); + const user = userEvent.setup({ delay: null }); - const nameInput = getServerNameInput(); - await user.type(nameInput, "Test_Server"); + const nameInput = getServerNameInput(); + await user.type(nameInput, "Test_Server"); - const urlInput = screen.getByPlaceholderText("https://your-mcp-server.com"); - await user.type(urlInput, "https://example.com/mcp"); + const urlInput = screen.getByPlaceholderText("https://your-mcp-server.com"); + await user.type(urlInput, "https://example.com/mcp"); - await selectAntOption("Authentication", "Bearer Token"); + await selectAntOption("Authentication", "Bearer Token"); - await waitFor(() => { - expect(screen.getByText("Authentication Value")).toBeInTheDocument(); - }); + await waitFor(() => { + expect(screen.getByText("Authentication Value")).toBeInTheDocument(); + }); - // Leave auth value empty and submit - vi.mocked(networking.createMCPServer).mockResolvedValue({ - server_id: "new-server-1", - server_name: "Test_Server", - alias: "Test_Server", - url: "https://example.com/mcp", - transport: "http", - auth_type: "bearer_token", - created_at: "2024-01-01T00:00:00Z", - created_by: "user-1", - updated_at: "2024-01-01T00:00:00Z", - updated_by: "user-1", - }); + // Leave auth value empty and submit + vi.mocked(networking.createMCPServer).mockResolvedValue({ + server_id: "new-server-1", + server_name: "Test_Server", + alias: "Test_Server", + url: "https://example.com/mcp", + transport: "http", + auth_type: "bearer_token", + created_at: "2024-01-01T00:00:00Z", + created_by: "user-1", + updated_at: "2024-01-01T00:00:00Z", + updated_by: "user-1", + }); - const submitButton = screen.getByRole("button", { name: "Add MCP Server" }); - await act(async () => { - fireEvent.click(submitButton); - }); + const submitButton = screen.getByRole("button", { name: "Add MCP Server" }); + await act(async () => { + fireEvent.click(submitButton); + }); - await waitFor(() => { - expect(networking.createMCPServer).toHaveBeenCalledTimes(1); - }); - }); + await waitFor(() => { + expect(networking.createMCPServer).toHaveBeenCalledTimes(1); + }); + }, + ); it( "should successfully create a server when auth value is provided", @@ -283,46 +291,50 @@ describe("CreateMCPServer", () => { }); }); - it("should successfully create a server with no auth", async () => { - await selectHttpTransport(); + it( + "should successfully create a server with no auth", + { timeout: 15000 }, + async () => { + await selectHttpTransport(); - const user = userEvent.setup(); + const user = userEvent.setup({ delay: null }); - const nameInput = getServerNameInput(); - await user.type(nameInput, "No_Auth_Server"); + const nameInput = getServerNameInput(); + await user.type(nameInput, "No_Auth_Server"); - const urlInput = screen.getByPlaceholderText("https://your-mcp-server.com"); - await user.type(urlInput, "https://example.com/mcp"); + const urlInput = screen.getByPlaceholderText("https://your-mcp-server.com"); + await user.type(urlInput, "https://example.com/mcp"); - await selectAntOption("Authentication", "None"); + await selectAntOption("Authentication", "None"); - vi.mocked(networking.createMCPServer).mockResolvedValue({ - server_id: "new-server-1", - server_name: "No_Auth_Server", - alias: "No_Auth_Server", - url: "https://example.com/mcp", - transport: "http", - auth_type: "none", - created_at: "2024-01-01T00:00:00Z", - created_by: "user-1", - updated_at: "2024-01-01T00:00:00Z", - updated_by: "user-1", - }); + vi.mocked(networking.createMCPServer).mockResolvedValue({ + server_id: "new-server-1", + server_name: "No_Auth_Server", + alias: "No_Auth_Server", + url: "https://example.com/mcp", + transport: "http", + auth_type: "none", + created_at: "2024-01-01T00:00:00Z", + created_by: "user-1", + updated_at: "2024-01-01T00:00:00Z", + updated_by: "user-1", + }); - const submitButton = screen.getByRole("button", { name: "Add MCP Server" }); - await act(async () => { - fireEvent.click(submitButton); - }); + const submitButton = screen.getByRole("button", { name: "Add MCP Server" }); + await act(async () => { + fireEvent.click(submitButton); + }); - await waitFor(() => { - expect(networking.createMCPServer).toHaveBeenCalledTimes(1); - }); + await waitFor(() => { + expect(networking.createMCPServer).toHaveBeenCalledTimes(1); + }); - const [, payload] = vi.mocked(networking.createMCPServer).mock.calls[0]; - expect(payload.auth_type).toBe("none"); - // No credentials should be sent for "none" auth - expect(payload.credentials).toBeUndefined(); - }); + const [, payload] = vi.mocked(networking.createMCPServer).mock.calls[0]; + expect(payload.auth_type).toBe("none"); + // No credentials should be sent for "none" auth + expect(payload.credentials).toBeUndefined(); + }, + ); }); describe("when modal is cancelled", () => { diff --git a/ui/litellm-dashboard/src/components/team/TeamInfo.test.tsx b/ui/litellm-dashboard/src/components/team/TeamInfo.test.tsx index cc0483aafd6..a5951298557 100644 --- a/ui/litellm-dashboard/src/components/team/TeamInfo.test.tsx +++ b/ui/litellm-dashboard/src/components/team/TeamInfo.test.tsx @@ -309,7 +309,7 @@ describe("TeamInfoView", () => { }); it("should navigate to settings tab when clicked", async () => { - const user = userEvent.setup(); + const user = userEvent.setup({ delay: null }); vi.mocked(networking.teamInfoCall).mockResolvedValue(createMockTeamData()); renderWithProviders(); @@ -328,7 +328,7 @@ describe("TeamInfoView", () => { }); it("should open edit mode when edit button is clicked", async () => { - const user = userEvent.setup(); + const user = userEvent.setup({ delay: null }); vi.mocked(networking.teamInfoCall).mockResolvedValue(createMockTeamData()); renderWithProviders(); @@ -353,8 +353,8 @@ describe("TeamInfoView", () => { }); }); - it("should close edit mode when cancel button is clicked", async () => { - const user = userEvent.setup(); + it("should close edit mode when cancel button is clicked", { timeout: 15000 }, async () => { + const user = userEvent.setup({ delay: null }); vi.mocked(networking.teamInfoCall).mockResolvedValue(createMockTeamData()); renderWithProviders(); @@ -387,7 +387,7 @@ describe("TeamInfoView", () => { }); it("should call onClose when back button is clicked", async () => { - const user = userEvent.setup(); + const user = userEvent.setup({ delay: null }); const onClose = vi.fn(); vi.mocked(networking.teamInfoCall).mockResolvedValue(createMockTeamData()); @@ -405,7 +405,7 @@ describe("TeamInfoView", () => { }); it("should copy team ID to clipboard when copy button is clicked", async () => { - const user = userEvent.setup(); + const user = userEvent.setup({ delay: null }); vi.mocked(networking.teamInfoCall).mockResolvedValue(createMockTeamData()); renderWithProviders(); @@ -425,7 +425,7 @@ describe("TeamInfoView", () => { }); it("should disable secret manager settings for non-premium users", async () => { - const user = userEvent.setup(); + const user = userEvent.setup({ delay: null }); vi.mocked(networking.teamInfoCall).mockResolvedValue( createMockTeamData({ metadata: { @@ -458,7 +458,7 @@ describe("TeamInfoView", () => { }); it("should allow premium users to edit secret manager settings", async () => { - const user = userEvent.setup(); + const user = userEvent.setup({ delay: null }); vi.mocked(networking.teamInfoCall).mockResolvedValue( createMockTeamData({ metadata: { @@ -492,7 +492,7 @@ describe("TeamInfoView", () => { }); it("should add team member when form is submitted", async () => { - const user = userEvent.setup(); + const user = userEvent.setup({ delay: null }); const onUpdate = vi.fn(); const teamData = createMockTeamData(); vi.mocked(networking.teamInfoCall).mockResolvedValue(teamData); @@ -582,7 +582,7 @@ describe("TeamInfoView", () => { }); it("should display soft budget in settings view when present", async () => { - const user = userEvent.setup(); + const user = userEvent.setup({ delay: null }); vi.mocked(networking.teamInfoCall).mockResolvedValue( createMockTeamData({ soft_budget: 500.75, @@ -652,7 +652,7 @@ describe("TeamInfoView", () => { }); it("should display soft budget alerting emails in settings view when present", async () => { - const user = userEvent.setup(); + const user = userEvent.setup({ delay: null }); vi.mocked(networking.teamInfoCall).mockResolvedValue( createMockTeamData({ metadata: { @@ -682,7 +682,7 @@ describe("TeamInfoView", () => { }); it("should pass access_group_ids to teamUpdateCall when saving team settings", async () => { - const user = userEvent.setup(); + const user = userEvent.setup({ delay: null }); const accessGroupIds = ["ag-1", "ag-2"]; vi.mocked(networking.teamInfoCall).mockResolvedValue( createMockTeamData({