diff --git a/ui/litellm-dashboard/src/app/(dashboard)/agentControlPlaneView.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/agentControlPlaneView.test.tsx
index 26de1eed7b8..3e3b3d2b8bf 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/agentControlPlaneView.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/agentControlPlaneView.test.tsx
@@ -33,7 +33,7 @@ describe("AgentControlPlaneView iframe", () => {
expect(src).toBe("http://localhost:3300/");
expect(src).not.toContain("/sessions");
// title comes from the plugin's display_name, not a hardcoded label
- expect(iframe!.getAttribute("title")).toBe("Chat UI");
+ expect(iframe!).toHaveAttribute("title", "Chat UI");
});
it("does not double the slash when the plugin url has a trailing slash", () => {
@@ -43,7 +43,7 @@ describe("AgentControlPlaneView iframe", () => {
url: "http://localhost:3300/",
};
const { container } = render();
- expect(container.querySelector("iframe")!.getAttribute("src")).toBe("http://localhost:3300/");
+ expect(container.querySelector("iframe")!).toHaveAttribute("src", "http://localhost:3300/");
pluginModeValue.activePlugin = {
name: "litellm-platform-plugin",
display_name: "Chat UI",
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/AgentsTable.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/AgentsTable.test.tsx
index f86ef16e836..06099a9fc22 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/AgentsTable.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/AgentsTable.test.tsx
@@ -101,8 +101,8 @@ describe("AgentsTable", () => {
);
const bodyRows = screen.getAllByRole("row").slice(1);
- expect(bodyRows[0].textContent).toContain("Beta Agent");
- expect(bodyRows[1].textContent).toContain("Alpha Agent");
+ expect(bodyRows[0]).toHaveTextContent(/Beta Agent/);
+ expect(bodyRows[1]).toHaveTextContent(/Alpha Agent/);
});
it("sorts agents with no created_at last, never ahead of dated ones", () => {
@@ -118,9 +118,9 @@ describe("AgentsTable", () => {
);
const bodyRows = screen.getAllByRole("row").slice(1);
- expect(bodyRows[0].textContent).toContain("Beta Agent");
- expect(bodyRows[1].textContent).toContain("Alpha Agent");
- expect(bodyRows[2].textContent).toContain("Undated Agent");
+ expect(bodyRows[0]).toHaveTextContent(/Beta Agent/);
+ expect(bodyRows[1]).toHaveTextContent(/Alpha Agent/);
+ expect(bodyRows[2]).toHaveTextContent(/Undated Agent/);
});
it("shows a rich empty state when there are no agents", () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_card_discovery.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_card_discovery.test.tsx
index 7858bdb1cd4..e3c5e1dd94f 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_card_discovery.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_card_discovery.test.tsx
@@ -196,12 +196,10 @@ describe("AgentCardDiscovery", () => {
);
expect(
- (
- screen.getByRole("button", {
- name: /discover/i,
- }) as HTMLButtonElement
- ).disabled,
- ).toBe(true);
+ screen.getByRole("button", {
+ name: /discover/i,
+ }),
+ ).toBeDisabled();
expect(mockDiscover).not.toHaveBeenCalled();
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/api-reference/_components/APIReferenceView.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/api-reference/_components/APIReferenceView.test.tsx
index ad1cf28dc54..b2e0a42eecb 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/api-reference/_components/APIReferenceView.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/api-reference/_components/APIReferenceView.test.tsx
@@ -16,7 +16,7 @@ describe("APIReferenceView", () => {
const { getAllByTestId } = render();
const codeBlocks = getAllByTestId(codeBlockTestId);
- expect(codeBlocks[0].textContent).toContain(apiDocUrl);
+ expect(codeBlocks[0]).toHaveTextContent(new RegExp(apiDocUrl));
});
it("falls back to the proxy base url when the docs url is missing", () => {
@@ -24,7 +24,7 @@ describe("APIReferenceView", () => {
const { getAllByTestId } = render();
const codeBlocks = getAllByTestId(codeBlockTestId);
- expect(codeBlocks[0].textContent).toContain(proxyUrl);
+ expect(codeBlocks[0]).toHaveTextContent(new RegExp(proxyUrl));
});
it("prefers the docs url when both urls are provided", () => {
@@ -49,12 +49,12 @@ describe("APIReferenceView", () => {
it("renders the page title, blurb and docs link", () => {
render();
- expect(screen.getByText("OpenAI Compatible Proxy: API Reference")).toBeTruthy();
- expect(screen.getByText(/LiteLLM is OpenAI Compatible/)).toBeTruthy();
+ expect(screen.getByText("OpenAI Compatible Proxy: API Reference")).toBeInTheDocument();
+ expect(screen.getByText(/LiteLLM is OpenAI Compatible/)).toBeInTheDocument();
const docsLink = screen.getByRole("link", { name: /API Reference Docs/ });
- expect(docsLink.getAttribute("href")).toBe("https://docs.litellm.ai/docs/proxy/user_keys");
- expect(docsLink.getAttribute("target")).toBe("_blank");
+ expect(docsLink).toHaveAttribute("href", "https://docs.litellm.ai/docs/proxy/user_keys");
+ expect(docsLink).toHaveAttribute("target", "_blank");
});
it("exposes the three SDK tabs with the first selected by default", () => {
@@ -83,10 +83,10 @@ describe("APIReferenceView", () => {
await user.click(screen.getByRole("tab", { name: tabName }));
- expect(screen.getByRole("tab", { name: tabName }).getAttribute("aria-selected")).toBe("true");
+ expect(screen.getByRole("tab", { name: tabName })).toHaveAttribute("aria-selected", "true");
const selectedPanel = screen.getByRole("tabpanel");
- expect(selectedPanel.textContent).toContain(marker);
- expect(selectedPanel.textContent).toContain(proxyUrl);
+ expect(selectedPanel).toHaveTextContent(new RegExp(marker));
+ expect(selectedPanel).toHaveTextContent(new RegExp(proxyUrl));
});
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/budgets/_components/BudgetTable.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/budgets/_components/BudgetTable.test.tsx
index f78ba34770d..c425e766f2d 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/budgets/_components/BudgetTable.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/budgets/_components/BudgetTable.test.tsx
@@ -105,7 +105,7 @@ describe("BudgetTable", () => {
const list = makeList({ rows: [makeBudget({ budget_id: budgetId })] });
renderWithProviders();
const idCell = screen.getByText(budgetId);
- expect(idCell.className).not.toContain("truncate");
+ expect(idCell).not.toHaveClass("truncate");
expect(idCell.className).not.toMatch(/max-w-\[\d+(ch|rem|px)\]/);
});
@@ -113,7 +113,7 @@ describe("BudgetTable", () => {
const budgetId = "ecc1869c-6231-4380-a56d-1a0be457477d";
const list = makeList({ rows: [makeBudget({ budget_id: budgetId })] });
renderWithProviders();
- expect(screen.getByText(budgetId).className).toContain("whitespace-nowrap");
+ expect(screen.getByText(budgetId)).toHaveClass("whitespace-nowrap");
});
it("should copy the budget id from the cell's copy button", async () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/CostOptimizationView.activity.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/CostOptimizationView.activity.test.tsx
index 96502cac953..70d7dade97a 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/CostOptimizationView.activity.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/CostOptimizationView.activity.test.tsx
@@ -52,7 +52,7 @@ describe("CostOptimizationView daily activity", () => {
useAuthorizedMock.mockReturnValue({ accessToken: "test-token", userId: "u1", userRole: "proxy_admin" });
const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } } });
- const { getByRole, getByTestId } = render(
+ const { getByRole, getByTestId, findByTestId } = render(
,
@@ -61,7 +61,7 @@ describe("CostOptimizationView daily activity", () => {
await waitFor(() => expect(mockUserDailyActivityCall).toHaveBeenCalledTimes(1));
fireEvent.click(getByRole("tab", { name: "Prompt Caching" }));
- await waitFor(() => expect(getByTestId("caching-settings")).toBeInTheDocument());
+ await findByTestId("caching-settings");
expect(mockUserDailyActivityCall).toHaveBeenCalledTimes(1);
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/UsageTab.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/UsageTab.test.tsx
index 25be956f18b..20d57754857 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/UsageTab.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/UsageTab.test.tsx
@@ -218,7 +218,7 @@ describe("UsageTab", () => {
// Per day switches to a bar chart of the unaccumulated daily savings, with no
// synthetic anchor prepended.
- expect(queryByTestId("area-chart")).toBeNull();
+ expect(queryByTestId("area-chart")).not.toBeInTheDocument();
const series = readSeries(getByTestId("bar-chart"));
expect(series).toHaveLength(2);
expect(series[0]).toMatchObject({ Compression: 0.04, "Prompt caching": 0.006 });
@@ -264,7 +264,7 @@ describe("UsageTab", () => {
await userEvent.click(getByRole("tab", { name: "Per day" }));
const bars = getByTestId("bar-chart");
- expect(bars.getAttribute("data-stack")).toBe("false");
+ expect(bars).toHaveAttribute("data-stack", "false");
expect(readSeries(bars)[0]).toMatchObject({ "Auto-router": -0.05 });
});
@@ -290,7 +290,7 @@ describe("UsageTab", () => {
expect(before.action.contains(getByRole("tablist"))).toBe(true);
// the subtitle lives outside that slot, so its length cannot reposition the controls
expect(before.action.contains(before.description)).toBe(false);
- expect(before.description.textContent).toContain("Running total saved");
+ expect(before.description).toHaveTextContent(/Running total saved/);
await userEvent.click(getByRole("tab", { name: "Per day" }));
@@ -298,8 +298,8 @@ describe("UsageTab", () => {
expect(after.action).toBe(before.action);
expect(after.cardHeader).toBe(before.cardHeader);
expect(after.action.contains(after.description)).toBe(false);
- expect(after.description.textContent).toContain("Saved per day");
- expect(container.textContent).toContain("Savings");
+ expect(after.description).toHaveTextContent(/Saved per day/);
+ expect(container).toHaveTextContent(/Savings/);
});
it("subtracts a losing auto-router route from the total and keeps it out of the donut", () => {
@@ -319,7 +319,7 @@ describe("UsageTab", () => {
const slices = JSON.parse(getByTestId("donut-chart").getAttribute("data-slices") ?? "[]");
expect(slices.map((d: { driver: string }) => d.driver)).toEqual(["Compression", "Prompt caching"]);
- expect(getByTestId("donut-chart").getAttribute("data-label")).toBe("$0.1200");
+ expect(getByTestId("donut-chart")).toHaveAttribute("data-label", "$0.1200");
});
it("carries auto-router savings into the summary card, donut slice, and cumulative series", () => {
@@ -370,7 +370,7 @@ describe("UsageTab", () => {
expect(series[0]).toMatchObject({ tool_name: "search", spend: 4.0 });
// The 64px bar cap is this card's opt-in; the shared BarChart must not cap
// by default (other consumers keep their pre-existing geometry).
- expect(bars[0].getAttribute("data-max-bar-size")).toBe("64");
+ expect(bars[0]).toHaveAttribute("data-max-bar-size", "64");
});
it("renders the tool legend once outside the charts, with both charts sharing the tool colors", async () => {
@@ -387,8 +387,8 @@ describe("UsageTab", () => {
const bars = await findAllByTestId("bar-chart");
const [totalByTool, dailyByTool] = bars.slice(-2);
- expect(dailyByTool.getAttribute("data-show-legend")).toBe("false");
- expect(totalByTool.getAttribute("data-colors")).toBe(dailyByTool.getAttribute("data-colors"));
+ expect(dailyByTool).toHaveAttribute("data-show-legend", "false");
+ expect(totalByTool).toHaveAttribute("data-colors", dailyByTool.getAttribute("data-colors"));
const toolLegends = getAllByTestId("chart-legend").filter((legend) => legend.textContent === "search,read_file");
expect(toolLegends).toHaveLength(1);
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/add_margin_form.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/add_margin_form.test.tsx
index 1ededd9e4b1..63a0b3c355f 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/add_margin_form.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/add_margin_form.test.tsx
@@ -67,7 +67,7 @@ describe("AddMarginForm", () => {
it("should enable the submit button when provider and percentage value are both provided", () => {
renderWithProviders();
- expect(screen.getByRole("button", { name: /add provider margin/i })).not.toBeDisabled();
+ expect(screen.getByRole("button", { name: /add provider margin/i })).toBeEnabled();
});
it("should disable the submit button in fixed mode when no fixed amount is provided", () => {
@@ -81,7 +81,7 @@ describe("AddMarginForm", () => {
renderWithProviders(
,
);
- expect(screen.getByRole("button", { name: /add provider margin/i })).not.toBeDisabled();
+ expect(screen.getByRole("button", { name: /add provider margin/i })).toBeEnabled();
});
it("should call onAddProvider when the enabled submit button is clicked", async () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/add_provider_form.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/add_provider_form.test.tsx
index 08fb63c32b9..084233b3670 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/add_provider_form.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/add_provider_form.test.tsx
@@ -48,7 +48,7 @@ describe("AddProviderForm", () => {
it("should enable the submit button when both a provider and a discount value are provided", () => {
renderWithProviders();
- expect(screen.getByRole("button", { name: /add provider discount/i })).not.toBeDisabled();
+ expect(screen.getByRole("button", { name: /add provider discount/i })).toBeEnabled();
});
it("should call onAddProvider when the enabled submit button is clicked", async () => {
@@ -71,7 +71,7 @@ describe("AddProviderForm", () => {
renderWithProviders();
const logo = await screen.findByRole("img", { name: `${Providers.OpenAI} logo` });
- expect(logo.getAttribute("src")).toBe(providerLogoMap[Providers.OpenAI]);
+ expect(logo).toHaveAttribute("src", providerLogoMap[Providers.OpenAI]);
});
it("falls back to a letter avatar for a selected provider that has no bundled logo", () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/cost_tracking_settings.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/cost_tracking_settings.test.tsx
index 03cef2a66b8..9cdc8509fbf 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/cost_tracking_settings.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/cost_tracking_settings.test.tsx
@@ -73,7 +73,7 @@ describe("CostTrackingSettings", () => {
const { container } = renderWithProviders(
,
);
- expect(container.firstChild).toBeNull();
+ expect(container).toBeEmptyDOMElement();
});
it("should render the page title", () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/how_it_works.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/how_it_works.test.tsx
index a574f4b628e..6739beb81d9 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/how_it_works.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/how_it_works.test.tsx
@@ -32,7 +32,7 @@ describe("HowItWorks", () => {
it("should render the code block with a curl example", () => {
renderWithProviders();
expect(screen.getByTestId("code-block")).toBeInTheDocument();
- expect(screen.getByTestId("code-block").textContent).toContain("curl");
+ expect(screen.getByTestId("code-block")).toHaveTextContent(/curl/);
});
it("should show the response header names for discount verification", () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/pricing_calculator/multi_export_dropdown.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/pricing_calculator/multi_export_dropdown.test.tsx
index 1c6800de7d2..52d5a3f9007 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/pricing_calculator/multi_export_dropdown.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/pricing_calculator/multi_export_dropdown.test.tsx
@@ -63,7 +63,7 @@ describe("MultiExportDropdown", () => {
it("should not render anything when no entries have results", () => {
const { container } = renderWithProviders();
- expect(container.firstChild).toBeNull();
+ expect(container).toBeEmptyDOMElement();
});
it("should render the Export button when at least one entry has a result", () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/provider_margin_table.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/provider_margin_table.test.tsx
index dd478571568..3663783347d 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/provider_margin_table.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/cost-tracking/_components/provider_margin_table.test.tsx
@@ -68,7 +68,7 @@ describe("ProviderMarginTable", () => {
/>,
);
const logo = screen.getByRole("img", { name: `${Providers.OpenAI} logo` });
- expect(logo.getAttribute("src")).toBe(providerLogoMap[Providers.OpenAI]);
+ expect(logo).toHaveAttribute("src", providerLogoMap[Providers.OpenAI]);
});
it("should fall back to a letter avatar for a provider with no bundled logo", () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsMonitorView.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsMonitorView.test.tsx
index b946749bf65..9f27daab6b3 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsMonitorView.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsMonitorView.test.tsx
@@ -32,7 +32,7 @@ describe("GuardrailsMonitorView", () => {
render(, { wrapper });
- expect(await screen.findByRole("heading", { name: /Guardrails Monitor/i })).toBeDefined();
+ expect(await screen.findByRole("heading", { name: /Guardrails Monitor/i })).toBeInTheDocument();
await waitFor(() => {
expect(mockGetGuardrailsUsageOverview).toHaveBeenCalled();
});
@@ -40,6 +40,6 @@ describe("GuardrailsMonitorView", () => {
it("should render without crashing when accessToken is null", async () => {
render(, { wrapper });
- expect(await screen.findByRole("heading", { name: /Guardrails Monitor/i })).toBeDefined();
+ expect(await screen.findByRole("heading", { name: /Guardrails Monitor/i })).toBeInTheDocument();
});
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/add_guardrail_form.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/add_guardrail_form.test.tsx
index a386fca598e..e8463025e31 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/add_guardrail_form.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/add_guardrail_form.test.tsx
@@ -53,6 +53,6 @@ describe("AddGuardrailForm provider options", () => {
fireEvent.mouseDown(screen.getByLabelText("Guardrail Provider"));
const logo = await screen.findByAltText("Presidio PII logo");
- expect(logo.getAttribute("src")).toContain("microsoft_azure.svg");
+ expect(logo).toHaveAttribute("src", expect.stringContaining("microsoft_azure.svg"));
});
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/ContentFilterManager.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/ContentFilterManager.test.tsx
index c3fd2e3eb59..83ed695f34a 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/ContentFilterManager.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/ContentFilterManager.test.tsx
@@ -124,7 +124,7 @@ describe("ContentFilterManager", () => {
expect(screen.queryByTestId("content-filter-config")).not.toBeInTheDocument();
expect(screen.queryByTestId("content-filter-display")).not.toBeInTheDocument();
- expect(container.firstChild).toBeNull();
+ expect(container).toBeEmptyDOMElement();
});
it("should render read-only display when isEditing is false", async () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/guardrail_garden_card.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/guardrail_garden_card.test.tsx
index 2d1f35e456c..d81eaa5a4fc 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/guardrail_garden_card.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/guardrail_garden_card.test.tsx
@@ -56,7 +56,7 @@ describe("GuardrailCard", () => {
it("should render the logo through the shared Logo component with the card src", () => {
render();
const img = screen.getByAltText("Test Guardrail logo");
- expect(img.getAttribute("src")).toContain("/logos/test.svg");
+ expect(img).toHaveAttribute("src", expect.stringContaining("/logos/test.svg"));
});
it("should pass a bundled static-import src through unchanged", () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/guardrail_info.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/guardrail_info.test.tsx
index aae1998644a..eca1cf4df8a 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/guardrail_info.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/guardrail_info.test.tsx
@@ -109,7 +109,7 @@ describe("Guardrail Info", () => {
);
const logo = await findByAltText("Presidio PII logo");
- expect(logo.getAttribute("src")).toContain("microsoft_azure.svg");
+ expect(logo).toHaveAttribute("src", expect.stringContaining("microsoft_azure.svg"));
});
it("should not render the edit button for config guardrails", async () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/guardrail_table.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/guardrail_table.test.tsx
index 7612b702391..ee619dc7468 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/guardrail_table.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/guardrail_table.test.tsx
@@ -33,7 +33,7 @@ describe("GuardrailTable", () => {
it("renders the provider logo from the bundled guardrail logo map", () => {
render();
const logo = screen.getByAltText("Presidio PII logo");
- expect(logo.getAttribute("src")).toContain("microsoft_azure.svg");
+ expect(logo).toHaveAttribute("src", expect.stringContaining("microsoft_azure.svg"));
});
it("falls back to a letter avatar for an unknown provider slug", () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/layout.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/layout.test.tsx
index 340077e9569..7f1f4cc4bd5 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/layout.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/layout.test.tsx
@@ -82,15 +82,15 @@ describe("(dashboard) Layout", () => {
,
);
- await waitFor(() => expect(screen.getByTestId("loading-screen")).toBeTruthy());
- expect(screen.queryByTestId("page-content")).toBeNull();
- expect(screen.queryByTestId("dashboard-header")).toBeNull();
+ expect(await screen.findByTestId("loading-screen")).toBeInTheDocument();
+ expect(screen.queryByTestId("page-content")).not.toBeInTheDocument();
+ expect(screen.queryByTestId("dashboard-header")).not.toBeInTheDocument();
pendingUiConfig.resolve();
- await waitFor(() => expect(screen.getByTestId("page-content")).toBeTruthy());
- expect(screen.getByTestId("dashboard-header")).toBeTruthy();
- expect(screen.queryByTestId("loading-screen")).toBeNull();
+ expect(await screen.findByTestId("page-content")).toBeInTheDocument();
+ expect(screen.getByTestId("dashboard-header")).toBeInTheDocument();
+ expect(screen.queryByTestId("loading-screen")).not.toBeInTheDocument();
});
it("redirects an invitation link to the onboarding route instead of rendering the dashboard shell", async () => {
@@ -109,8 +109,8 @@ describe("(dashboard) Layout", () => {
await waitFor(() =>
expect(replaceMock).toHaveBeenCalledWith(expect.stringContaining("/onboarding?invitation_id=abc123")),
);
- expect(screen.queryByTestId("page-content")).toBeNull();
- expect(screen.queryByTestId("dashboard-header")).toBeNull();
- expect(screen.queryByTestId("sidebar")).toBeNull();
+ expect(screen.queryByTestId("page-content")).not.toBeInTheDocument();
+ expect(screen.queryByTestId("dashboard-header")).not.toBeInTheDocument();
+ expect(screen.queryByTestId("sidebar")).not.toBeInTheDocument();
});
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/CreateMCPServer.integration.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/CreateMCPServer.integration.test.tsx
index c9007e29c3e..f08aacb5522 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/CreateMCPServer.integration.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/CreateMCPServer.integration.test.tsx
@@ -676,7 +676,7 @@ describe("CreateMCPServer", () => {
it("clears the DCR ref and the upstream warning when the modal closes so nothing leaks to the next session", async () => {
const { rerender } = render();
await selectAntOption("Transport Type", "Streamable HTTP");
- await waitFor(() => expect(screen.getByPlaceholderText("https://your-mcp-server.com")).toBeInTheDocument());
+ expect(await screen.findByPlaceholderText("https://your-mcp-server.com")).toBeInTheDocument();
const user = userEvent.setup({ delay: null });
await user.type(getServerNameInput(), "Leak_Server");
await user.type(screen.getByPlaceholderText("https://your-mcp-server.com"), "https://example.com/mcp");
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/MCPLogoSelector.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/MCPLogoSelector.test.tsx
index f126a030b9f..0f75f32dda5 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/MCPLogoSelector.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/MCPLogoSelector.test.tsx
@@ -69,6 +69,6 @@ describe("MCPLogoSelector", () => {
it("should preview a custom external URL untouched", () => {
render();
- expect(screen.getByAltText("Selected logo").getAttribute("src")).toBe("https://cdn.example.com/logo.png");
+ expect(screen.getByAltText("Selected logo")).toHaveAttribute("src", "https://cdn.example.com/logo.png");
});
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/MCPPermissionManagement.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/MCPPermissionManagement.test.tsx
index a53681f6cd8..ee6aee86a4d 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/MCPPermissionManagement.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/MCPPermissionManagement.test.tsx
@@ -48,7 +48,7 @@ describe("MCPPermissionManagement", () => {
// The first switch in the component is for allow_all_keys
const switches = screen.getAllByRole("switch");
const toggle = switches[0];
- expect(toggle).toHaveAttribute("aria-checked", "false");
+ expect(toggle).not.toBeChecked();
});
const renderWithInitialValues = (initialValues: Record, props = {}) => {
@@ -122,9 +122,9 @@ describe("MCPPermissionManagement", () => {
// The first switch in the component is for allow_all_keys
const switches = screen.getAllByRole("switch");
const toggle = switches[0];
- expect(toggle).toHaveAttribute("aria-checked", "true");
+ expect(toggle).toBeChecked();
await user.click(toggle);
- expect(toggle).toHaveAttribute("aria-checked", "false");
+ expect(toggle).not.toBeChecked();
});
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/MCPServerCard.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/MCPServerCard.test.tsx
index d6343afe219..8c7fe46a1a2 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/MCPServerCard.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/MCPServerCard.test.tsx
@@ -52,13 +52,13 @@ describe("MCPServerCard logo", () => {
it("passes an external logo_url through untouched", () => {
renderCard({ mcp_info: { server_name: "demo_server", logo_url: "https://cdn.example.com/logo.png" } });
- expect(screen.getByAltText("demo_server logo").getAttribute("src")).toBe("https://cdn.example.com/logo.png");
+ expect(screen.getByAltText("demo_server logo")).toHaveAttribute("src", "https://cdn.example.com/logo.png");
});
it("prefixes a stored asset path with the server root path under a non-root mount", () => {
setServerRootPath("/litellm");
renderCard({ mcp_info: { server_name: "demo_server", logo_url: "/ui/assets/logos/github.svg" } });
- expect(screen.getByAltText("demo_server logo").getAttribute("src")).toBe("/litellm/ui/assets/logos/github.svg");
+ expect(screen.getByAltText("demo_server logo")).toHaveAttribute("src", "/litellm/ui/assets/logos/github.svg");
});
it("renders a letter avatar when no logo_url is set", () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/mcp_connection_status.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/mcp_connection_status.test.tsx
index 15e5d886d37..7511b8684a4 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/mcp_connection_status.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/mcp_connection_status.test.tsx
@@ -21,7 +21,7 @@ describe("MCPConnectionStatus", () => {
it("should render nothing when canFetchTools is false and no URL is set", () => {
const { container } = render();
- expect(container.firstChild).toBeNull();
+ expect(container).toBeEmptyDOMElement();
});
it("should show 'Complete required fields' message when URL is set but canFetchTools is false", () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/mcp_server_edit.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/mcp_server_edit.test.tsx
index b660c4bdb76..6972c33ea1b 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/mcp_server_edit.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/mcp_server_edit.test.tsx
@@ -1214,8 +1214,9 @@ describe("MCPServerEdit (tool list fetch)", () => {
);
await waitFor(() => {
- expect(screen.getByTestId("mcp-tool-config").getAttribute("data-external-error")).toContain(
- "Authorize with the upstream (browser-only",
+ expect(screen.getByTestId("mcp-tool-config")).toHaveAttribute(
+ "data-external-error",
+ expect.stringContaining("Authorize with the upstream (browser-only"),
);
});
expect(networking.listMCPTools).not.toHaveBeenCalled();
@@ -1242,8 +1243,9 @@ describe("MCPServerEdit (tool list fetch)", () => {
const { rerender } = render();
await waitFor(() => {
- expect(screen.getByTestId("mcp-tool-config").getAttribute("data-external-error")).toContain(
- "Authenticate with this server in the Tools tab",
+ expect(screen.getByTestId("mcp-tool-config")).toHaveAttribute(
+ "data-external-error",
+ expect.stringContaining("Authenticate with this server in the Tools tab"),
);
});
expect(networking.listMCPTools).not.toHaveBeenCalled();
@@ -1277,8 +1279,9 @@ describe("MCPServerEdit (tool list fetch)", () => {
);
await waitFor(() => {
- expect(screen.getByTestId("mcp-tool-config").getAttribute("data-external-error")).toContain(
- "Authenticate with this server in the Tools tab",
+ expect(screen.getByTestId("mcp-tool-config")).toHaveAttribute(
+ "data-external-error",
+ expect.stringContaining("Authenticate with this server in the Tools tab"),
);
});
expect(networking.listMCPTools).not.toHaveBeenCalled();
@@ -1657,9 +1660,7 @@ describe("MCPServerEdit (OAuth token persistence on save)", () => {
// Check "remove saved app" on server A.
fireEvent.click(screen.getByRole("checkbox", { name: /Remove the saved OAuth app on save/ }));
- expect(
- (screen.getByRole("checkbox", { name: /Remove the saved OAuth app on save/ }) as HTMLInputElement).checked,
- ).toBe(true);
+ expect(screen.getByRole("checkbox", { name: /Remove the saved OAuth app on save/ })).toBeChecked();
// Switch the panel to server B without unmounting.
rerender(
@@ -1674,9 +1675,7 @@ describe("MCPServerEdit (OAuth token persistence on save)", () => {
);
// The checkbox must have reset, so saving server B does not send the explicit-null delete write.
- expect(
- (screen.getByRole("checkbox", { name: /Remove the saved OAuth app on save/ }) as HTMLInputElement).checked,
- ).toBe(false);
+ expect(screen.getByRole("checkbox", { name: /Remove the saved OAuth app on save/ })).not.toBeChecked();
await act(async () => {
fireEvent.click(screen.getAllByRole("button", { name: "Save Changes" })[0]);
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/page.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/page.test.tsx
index 222a2e04117..521f89a39f2 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/page.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/page.test.tsx
@@ -76,14 +76,14 @@ describe("ModelsAndEndpointsPage", () => {
const { getByRole, getByTestId, queryByTestId } = renderPage();
await user.click(getByRole("tab", { name: "Health Status" }));
expect(getByTestId("panel-health")).toBeInTheDocument();
- expect(queryByTestId("panel-all-models")).toBeNull();
+ expect(queryByTestId("panel-all-models")).not.toBeInTheDocument();
});
it("renders the model detail overlay from the ?model drill-in and hides the tabs", () => {
detailState.modelId = "abc-123";
const { getByTestId, queryByRole } = renderPage();
expect(getByTestId("model-info")).toHaveTextContent("model:abc-123");
- expect(queryByRole("tab", { name: "All Models" })).toBeNull();
+ expect(queryByRole("tab", { name: "All Models" })).not.toBeInTheDocument();
});
it("renders the team detail overlay from the ?team drill-in", () => {
@@ -95,8 +95,8 @@ describe("ModelsAndEndpointsPage", () => {
it("hides admin-only tabs for a non-admin user", () => {
mockUseAuthorized.mockReturnValue(NON_ADMIN);
const { queryByRole } = renderPage();
- expect(queryByRole("tab", { name: "LLM Credentials" })).toBeNull();
- expect(queryByRole("tab", { name: "Health Status" })).toBeNull();
+ expect(queryByRole("tab", { name: "LLM Credentials" })).not.toBeInTheDocument();
+ expect(queryByRole("tab", { name: "Health Status" })).not.toBeInTheDocument();
});
// Auto-routers are excluded from the All Models table, so this tab is their home: the only
@@ -125,7 +125,7 @@ describe("ModelsAndEndpointsPage", () => {
mockUseAuthorized.mockReturnValue(NON_ADMIN);
const { queryByRole } = renderPage();
- expect(queryByRole("tab", { name: /Auto-Routers/ })).toBeNull();
+ expect(queryByRole("tab", { name: /Auto-Routers/ })).not.toBeInTheDocument();
});
});
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/AdditionalModelSettings.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/AdditionalModelSettings.test.tsx
index 1c2cb426f23..4c0f2831c6e 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/AdditionalModelSettings.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/AdditionalModelSettings.test.tsx
@@ -39,13 +39,13 @@ describe("AdditionalModelSettings", () => {
await waitFor(() => {
const sliders = screen.getAllByRole("slider");
expect(sliders.length).toBeGreaterThan(0);
- expect(sliders[0]).not.toBeDisabled();
+ expect(sliders[0]).toBeEnabled();
});
const temperatureSlider = screen.getAllByRole("slider")[0];
const maxTokensSlider = screen.getAllByRole("slider")[1];
- expect(temperatureSlider).not.toBeDisabled();
- expect(maxTokensSlider).not.toBeDisabled();
+ expect(temperatureSlider).toBeEnabled();
+ expect(maxTokensSlider).toBeEnabled();
});
it("should not show Stream responses when onStreamingChange is not provided", () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/AgentBuilderView.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/AgentBuilderView.test.tsx
index e30f87115cf..f2c2c3d2c8c 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/AgentBuilderView.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/AgentBuilderView.test.tsx
@@ -132,7 +132,7 @@ describe("AgentBuilderView", () => {
expect(screen.getByRole("button", { name: "research-agent litellm_agent" })).toBeInTheDocument();
expect(screen.getByText("Agent Builder")).toBeInTheDocument();
- await waitFor(() => expect(screen.getByDisplayValue("support-agent")).toBeInTheDocument());
+ expect(await screen.findByDisplayValue("support-agent")).toBeInTheDocument();
expect(screen.getByDisplayValue("Be helpful.")).toBeInTheDocument();
expect(screen.getByDisplayValue("0.3")).toBeInTheDocument();
});
@@ -144,7 +144,7 @@ describe("AgentBuilderView", () => {
await user.click(screen.getByRole("button", { name: "research-agent litellm_agent" }));
- await waitFor(() => expect(screen.getByDisplayValue("research-agent")).toBeInTheDocument());
+ expect(await screen.findByDisplayValue("research-agent")).toBeInTheDocument();
});
it("offers a blank draft and a save control for a new agent", async () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/ChatComposer.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/ChatComposer.test.tsx
index f3efb0a9b0f..da2e4debb3c 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/ChatComposer.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/ChatComposer.test.tsx
@@ -109,6 +109,6 @@ describe("ChatComposer", () => {
fireEvent.click(addonOf(container));
- expect(document.activeElement).toBe(screen.getByTestId("chat-composer-input"));
+ expect(screen.getByTestId("chat-composer-input")).toHaveFocus();
});
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/ChatUI.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/ChatUI.test.tsx
index de079cdebc9..24c56b276af 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/ChatUI.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/ChatUI.test.tsx
@@ -148,10 +148,10 @@ describe("ChatUI", () => {
await waitFor(() => {
expect(screen.getAllByText("ChatModel").length).toBeGreaterThan(0);
expect(screen.getAllByText("NoModeModel").length).toBeGreaterThan(0);
- expect(screen.queryByText("SpeechModel")).toBeNull();
- expect(screen.queryByText("ImageModel")).toBeNull();
- expect(screen.queryByText("ResponsesModel")).toBeNull();
- expect(screen.queryByText("RealtimeModel")).toBeNull();
+ expect(screen.queryByText("SpeechModel")).not.toBeInTheDocument();
+ expect(screen.queryByText("ImageModel")).not.toBeInTheDocument();
+ expect(screen.queryByText("ResponsesModel")).not.toBeInTheDocument();
+ expect(screen.queryByText("RealtimeModel")).not.toBeInTheDocument();
});
});
@@ -182,7 +182,7 @@ describe("ChatUI", () => {
await waitFor(() => {
expect(screen.getAllByText("RealtimeModel").length).toBeGreaterThan(0);
expect(screen.getAllByText("NoModeModel").length).toBeGreaterThan(0);
- expect(screen.queryByText("ChatModel")).toBeNull();
+ expect(screen.queryByText("ChatModel")).not.toBeInTheDocument();
});
});
@@ -234,7 +234,7 @@ describe("ChatUI", () => {
await selectComboboxOption("Select an endpoint", "/v1/chat/completions");
await waitFor(() => {
- expect(mcpInput()).not.toBeDisabled();
+ expect(mcpInput()).toBeEnabled();
});
});
@@ -432,7 +432,7 @@ describe("ChatUI", () => {
});
await waitFor(() => {
- expect(screen.queryByText("Fill")).toBeNull();
+ expect(screen.queryByText("Fill")).not.toBeInTheDocument();
});
const customProxyInput = screen.getByPlaceholderText(
@@ -461,7 +461,7 @@ describe("ChatUI", () => {
const mcpInput = screen.getByLabelText("Select MCP servers");
expect(mcpInput).toBeInTheDocument();
- expect(mcpInput).not.toBeDisabled();
+ expect(mcpInput).toBeEnabled();
await user.click(mcpInput);
@@ -521,7 +521,7 @@ describe("ChatUI", () => {
await waitFor(() => {
expect(screen.getAllByText("ChatModel").length).toBeGreaterThan(0);
});
- expect(screen.queryByText("SpeechModel")).toBeNull();
+ expect(screen.queryByText("SpeechModel")).not.toBeInTheDocument();
});
it("should attach an audio file dropped on the transcription upload area", async () => {
@@ -611,7 +611,7 @@ describe("ChatUI", () => {
await user.clear(keyField);
await waitFor(() => {
- expect(screen.getByPlaceholderText("Select a Model")).not.toBeDisabled();
+ expect(screen.getByPlaceholderText("Select a Model")).toBeEnabled();
});
});
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/CodeInterpreterOutput.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/CodeInterpreterOutput.test.tsx
index a42bd42ed81..c9cfc3ac833 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/CodeInterpreterOutput.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/CodeInterpreterOutput.test.tsx
@@ -235,7 +235,7 @@ describe("CodeInterpreterOutput", () => {
it("should return null when no code and no annotations", () => {
const { container } = render();
- expect(container.firstChild).toBeNull();
+ expect(container).toBeEmptyDOMElement();
});
it("should handle multiple image formats", async () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/RealtimePlayground.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/RealtimePlayground.test.tsx
index a72a02a59e9..f374582fb41 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/RealtimePlayground.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/playground/components/chat_ui/RealtimePlayground.test.tsx
@@ -1,4 +1,4 @@
-import { act, render, screen, waitFor } from "@testing-library/react";
+import { act, render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import RealtimePlayground from "./RealtimePlayground";
@@ -261,7 +261,7 @@ describe("RealtimePlayground", () => {
await user.click(screen.getByRole("button", { name: /Disconnect/i }));
expect(socket.close).toHaveBeenCalled();
- await waitFor(() => expect(screen.getByRole("button", { name: /Connect/i })).toBeInTheDocument());
+ expect(await screen.findByRole("button", { name: /Connect/i })).toBeInTheDocument();
expect(screen.queryByPlaceholderText("Type a message or use the mic...")).not.toBeInTheDocument();
});
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/playground/components/compareUI/CompareUI.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/playground/components/compareUI/CompareUI.test.tsx
index a68513b5204..cb8a5c16d3b 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/playground/components/compareUI/CompareUI.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/playground/components/compareUI/CompareUI.test.tsx
@@ -138,14 +138,14 @@ describe("CompareUI", () => {
}
await waitFor(() => {
- expect(queryByTestId("has-attachment")).toBeInTheDocument();
+ expect(getByTestId("has-attachment")).toBeInTheDocument();
});
const textarea = getByTestId("message-textarea");
await user.type(textarea, "Describe this image");
const sendButton = getByTestId("send-button");
- expect(sendButton).not.toBeDisabled();
+ expect(sendButton).toBeEnabled();
await user.click(sendButton);
await waitFor(() => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/playground/components/compareUI/components/MessageInput.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/playground/components/compareUI/components/MessageInput.test.tsx
index 049b70b982c..f1db0e863fa 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/playground/components/compareUI/components/MessageInput.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/playground/components/compareUI/components/MessageInput.test.tsx
@@ -41,7 +41,7 @@ describe("MessageInput", () => {
render();
const send = screen.getByRole("button");
- expect(send).not.toBeDisabled();
+ expect(send).toBeEnabled();
await user.click(send);
expect(onSend).toHaveBeenCalledTimes(1);
@@ -63,7 +63,7 @@ describe("MessageInput", () => {
expect(screen.getByTestId("upload-component")).toBeInTheDocument();
const send = screen.getByRole("button");
- expect(send).not.toBeDisabled();
+ expect(send).toBeEnabled();
await user.click(send);
expect(onSend).toHaveBeenCalledTimes(1);
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/AttachmentTable.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/AttachmentTable.test.tsx
index b544c44d190..e746effd634 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/AttachmentTable.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/AttachmentTable.test.tsx
@@ -135,9 +135,9 @@ describe("AttachmentTable", () => {
const attachment = makeAttachment({ attachment_id: "att-abcdef1234567" });
renderWithProviders();
const idElement = screen.getByText("att-abcdef1234567");
- expect(idElement.className).toContain("font-mono");
- expect(idElement.className).toContain("truncate");
- expect(idElement.className).not.toContain("bg-blue-50");
+ expect(idElement).toHaveClass("font-mono");
+ expect(idElement).toHaveClass("truncate");
+ expect(idElement).not.toHaveClass("bg-blue-50");
});
it("should render model chips when the attachment has models", () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/ai_suggestion_modal.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/ai_suggestion_modal.test.tsx
index 4db75fb1ced..c504d0759ae 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/ai_suggestion_modal.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/ai_suggestion_modal.test.tsx
@@ -96,7 +96,7 @@ describe("AiSuggestionModal", () => {
expect(screen.getByRole("button", { name: "Suggest Policies" })).toBeDisabled();
await pickModel(user);
- expect(screen.getByRole("button", { name: "Suggest Policies" })).not.toBeDisabled();
+ expect(screen.getByRole("button", { name: "Suggest Policies" })).toBeEnabled();
});
it("sends the examples, description and model to the suggest API", async () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/index.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/index.test.tsx
index 3b6534ab0f0..f508f6866d6 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/index.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/index.test.tsx
@@ -156,8 +156,8 @@ describe("PoliciesPanel attachment delete", () => {
await waitFor(() => {
expect(networkingMocks.deletePolicyAttachmentCall).toHaveBeenCalledTimes(1);
- expect(networkingMocks.deletePolicyAttachmentCall).toHaveBeenCalledWith("test-token", EXPECTED_ATTACHMENT_ID);
});
+ expect(networkingMocks.deletePolicyAttachmentCall).toHaveBeenCalledWith("test-token", EXPECTED_ATTACHMENT_ID);
});
it("should show mutation pending state while attachment delete is in flight", async () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/template_parameter_modal.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/template_parameter_modal.test.tsx
index 5dcab5cec80..c3b55cd18ff 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/template_parameter_modal.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/policies/_components/template_parameter_modal.test.tsx
@@ -95,7 +95,7 @@ describe("TemplateParameterModal", () => {
await user.type(screen.getByPlaceholderText("e.g. Contoso"), "Contoso");
- expect(screen.getByRole("button", { name: "Continue" })).not.toBeDisabled();
+ expect(screen.getByRole("button", { name: "Continue" })).toBeEnabled();
});
it("hands the entered parameters back to the caller", async () => {
@@ -181,7 +181,7 @@ describe("TemplateParameterModal", () => {
expect(await screen.findByText("Northwind")).toBeInTheDocument();
expect(screen.getByText("Fabrikam")).toBeInTheDocument();
await waitFor(() => {
- expect(screen.getByRole("button", { name: "Continue" })).not.toBeDisabled();
+ expect(screen.getByRole("button", { name: "Continue" })).toBeEnabled();
});
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/search-tools/_components/CreateSearchTools.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/search-tools/_components/CreateSearchTools.test.tsx
index 7f1d7edc97f..f860b1a8bd4 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/search-tools/_components/CreateSearchTools.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/search-tools/_components/CreateSearchTools.test.tsx
@@ -12,17 +12,20 @@ describe("SearchProviderLabel", () => {
it("renders the exa_ai logo file for the exa_ai slug", () => {
render();
const img = screen.getByRole("img", { name: "Exa AI logo" });
- expect(img.getAttribute("src")).toContain("exa_ai.png");
+ expect(img).toHaveAttribute("src", expect.stringContaining("exa_ai.png"));
});
it("renders the google_pse logo file for the google_pse slug", () => {
render();
- expect(screen.getByRole("img", { name: "Google PSE logo" }).getAttribute("src")).toContain("google_pse.png");
+ expect(screen.getByRole("img", { name: "Google PSE logo" })).toHaveAttribute(
+ "src",
+ expect.stringContaining("google_pse.png"),
+ );
});
it("falls back to a letter avatar for a provider with no bundled logo", () => {
render();
- expect(screen.queryByRole("img")).toBeNull();
+ expect(screen.queryByRole("img")).not.toBeInTheDocument();
expect(screen.getByText("B")).toBeInTheDocument();
expect(screen.getByText("Brave Search")).toBeInTheDocument();
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/search-tools/_components/SearchToolTester.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/search-tools/_components/SearchToolTester.test.tsx
index fd944120624..3d4144a74e6 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/search-tools/_components/SearchToolTester.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/search-tools/_components/SearchToolTester.test.tsx
@@ -82,7 +82,7 @@ describe("SearchToolTester", () => {
const input = screen.getByPlaceholderText("Enter your search query...");
await user.type(input, "test query");
const searchButton = screen.getByRole("button", { name: /search/i });
- expect(searchButton).not.toBeDisabled();
+ expect(searchButton).toBeEnabled();
});
it("should call searchToolQueryCall when search button is clicked", async () => {
@@ -416,11 +416,9 @@ describe("SearchToolTester", () => {
await user.type(input, "test query");
const searchButton = screen.getByRole("button", { name: /search/i });
await user.click(searchButton);
- await waitFor(() => {
- const link = screen.getByRole("link", { name: "Test Result 1" });
- expect(link).toHaveAttribute("href", "https://example.com/result1");
- expect(link).toHaveAttribute("target", "_blank");
- expect(link).toHaveAttribute("rel", "noopener noreferrer");
- });
+ const link = await screen.findByRole("link", { name: "Test Result 1" });
+ expect(link).toHaveAttribute("href", "https://example.com/result1");
+ expect(link).toHaveAttribute("rel", "noopener noreferrer");
+ expect(link).toHaveAttribute("target", "_blank");
});
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/skills/_components/add_plugin_form.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/skills/_components/add_plugin_form.test.tsx
index 74d1fb5facf..713cee7682c 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/skills/_components/add_plugin_form.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/skills/_components/add_plugin_form.test.tsx
@@ -90,7 +90,7 @@ describe("AddPluginForm", () => {
await waitFor(() => {
expect(screen.getByText(/Git repo/)).toBeInTheDocument();
});
- expect(screen.getByPlaceholderText(SUBPATH_PLACEHOLDER)).not.toBeDisabled();
+ expect(screen.getByPlaceholderText(SUBPATH_PLACEHOLDER)).toBeEnabled();
});
it("combines a repo URL with a subfolder into a git-subdir preview", async () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/transform-request/TransformRequestPanel.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/transform-request/TransformRequestPanel.test.tsx
index a0add153116..d8d46c361a2 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/transform-request/TransformRequestPanel.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/transform-request/TransformRequestPanel.test.tsx
@@ -76,10 +76,10 @@ describe("TransformRequestPanel", () => {
});
const output = await screen.findByText(/api\.anthropic\.com\/v1\/messages/);
- expect(output.textContent).toContain("curl -X POST");
- expect(output.textContent).toContain("-H 'x-api-key: redacted'");
- expect(output.textContent).toContain('"model": "claude-opus-4-8"');
- expect(output.textContent).toContain('"max_tokens": 42');
+ expect(output).toHaveTextContent(/curl \-X POST/);
+ expect(output).toHaveTextContent(/\-H 'x\-api\-key: redacted'/);
+ expect(output).toHaveTextContent(/"model": "claude\-opus\-4\-8"/);
+ expect(output).toHaveTextContent(/"max_tokens": 42/);
expect(notify.success).toHaveBeenCalledWith("Request transformed successfully");
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/components/EndpointUsage/components/EndpointUsageLineChart.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/components/EndpointUsage/components/EndpointUsageLineChart.test.tsx
index 33914e627dc..81ca90d8cb9 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/components/EndpointUsage/components/EndpointUsageLineChart.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/components/EndpointUsage/components/EndpointUsageLineChart.test.tsx
@@ -68,8 +68,8 @@ describe("EndpointUsageLineChart", () => {
const legend = container.querySelector(".recharts-legend-wrapper");
expect(legend).not.toBeNull();
- expect(legend!.textContent).toContain("/chat/completions");
- expect(legend!.textContent).toContain("/embeddings");
+ expect(legend!).toHaveTextContent(/\/chat\/completions/);
+ expect(legend!).toHaveTextContent(/\/embeddings/);
});
it("orders formatted dates oldest to newest on the x axis", () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/components/EntityUsage/EntityUsage.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/components/EntityUsage/EntityUsage.test.tsx
index 1f3dd5642ee..b11fbbee258 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/components/EntityUsage/EntityUsage.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/components/EntityUsage/EntityUsage.test.tsx
@@ -838,7 +838,7 @@ describe("EntityUsage", () => {
const sectors = container.querySelectorAll(".recharts-pie-sector path");
expect(sectors).toHaveLength(1);
- expect(sectors[0].getAttribute("fill")).toBe("var(--color-cyan-500, #06b6d4)");
+ expect(sectors[0]).toHaveAttribute("fill", "var(--color-cyan-500, #06b6d4)");
const centerLabels = Array.from(container.querySelectorAll("text.fill-foreground")).map((text) => text.textContent);
expect(centerLabels).toContain("$100.50");
@@ -883,7 +883,7 @@ describe("EntityUsage", () => {
render();
const logo = await screen.findByAltText("openai logo");
- expect(logo.getAttribute("src")).toContain("openai_small");
+ expect(logo).toHaveAttribute("src", expect.stringContaining("openai_small"));
});
describe("capability gating", () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/users/_components/user_edit_view.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/users/_components/user_edit_view.test.tsx
index 4d5ddaa1df6..b3d77a567f7 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/users/_components/user_edit_view.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/users/_components/user_edit_view.test.tsx
@@ -241,7 +241,7 @@ describe("UserEditView", () => {
await waitFor(() => {
const modelsSelect = screen.getByRole("combobox", { name: /select models/i });
- expect(modelsSelect).not.toBeDisabled();
+ expect(modelsSelect).toBeEnabled();
});
});
@@ -300,7 +300,7 @@ describe("UserEditView", () => {
await waitFor(() => {
const budgetInput = screen.getByRole("spinbutton", { name: /max budget/i });
- expect(budgetInput).not.toBeDisabled();
+ expect(budgetInput).toBeEnabled();
});
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/users/_components/view_users.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/users/_components/view_users.test.tsx
index 1a3d517df3e..57a50f6cfc2 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/users/_components/view_users.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/users/_components/view_users.test.tsx
@@ -273,7 +273,7 @@ describe("ViewUserDashboard", () => {
await user.click(screen.getByTestId("datatable-select-row-user-2"));
expect(screen.getByTestId("bulk-edit-users")).toHaveTextContent("Bulk Edit (1 selected)");
- expect(screen.getByTestId("bulk-edit-users")).not.toBeDisabled();
+ expect(screen.getByTestId("bulk-edit-users")).toBeEnabled();
await user.click(screen.getByTestId("datatable-select-all"));
expect(screen.getByTestId("bulk-edit-users")).toHaveTextContent("Bulk Edit (2 selected)");
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/users/_components/view_users/UsersTable.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/users/_components/view_users/UsersTable.test.tsx
index 6262fd60f70..860b1c35cfd 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/users/_components/view_users/UsersTable.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/users/_components/view_users/UsersTable.test.tsx
@@ -119,7 +119,7 @@ describe("UsersTable", () => {
"Created At",
"Updated At",
].forEach((header) => {
- expect(headerRow.textContent).toContain(header);
+ expect(headerRow).toHaveTextContent(header);
});
});
@@ -251,7 +251,7 @@ describe("UsersTable", () => {
await user.click(screen.getByTestId("datatable-select-row-user-1"));
- expect(screen.getByTestId("datatable-select-all")).toHaveAttribute("aria-checked", "mixed");
+ expect(screen.getByTestId("datatable-select-all")).toBePartiallyChecked();
});
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/vector-stores/_components/CreateVectorStore.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/vector-stores/_components/CreateVectorStore.test.tsx
index 6c7a647e2d3..048b2d05f1d 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/vector-stores/_components/CreateVectorStore.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/vector-stores/_components/CreateVectorStore.test.tsx
@@ -226,9 +226,9 @@ describe("CreateVectorStore", () => {
// Check if S3-specific fields are displayed
await waitFor(() => {
- expect(screen.queryByText("Vector Bucket Name")).toBeInTheDocument();
- expect(screen.queryByText("AWS Region")).toBeInTheDocument();
- expect(screen.queryByText("Embedding Model")).toBeInTheDocument();
+ expect(screen.getByText("Vector Bucket Name")).toBeInTheDocument();
+ expect(screen.getByText("AWS Region")).toBeInTheDocument();
+ expect(screen.getByText("Embedding Model")).toBeInTheDocument();
});
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/vector-stores/_components/IndexesTable.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/vector-stores/_components/IndexesTable.test.tsx
index f31c51f3fba..e318efb103b 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/vector-stores/_components/IndexesTable.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/vector-stores/_components/IndexesTable.test.tsx
@@ -87,7 +87,7 @@ describe("IndexesTable", () => {
it("should link created_by to the user detail deep link", () => {
render();
const link = screen.getByRole("link", { name: "admin@example.com" });
- expect(link.getAttribute("href")).toMatch(/\/users\?user=admin%40example\.com$/);
+ expect(link).toHaveAttribute("href", expect.stringMatching(/\/users\?user=admin%40example\.com$/));
});
it("should keep the dash fallback and render no link for a null created_by", () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/vector-stores/_components/VectorStoreForm.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/vector-stores/_components/VectorStoreForm.test.tsx
index 3eb013d47ad..94511ea114d 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/vector-stores/_components/VectorStoreForm.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/vector-stores/_components/VectorStoreForm.test.tsx
@@ -29,6 +29,6 @@ describe("VectorStoreForm", () => {
renderForm();
const logo = screen.getByRole("img", { name: `${VectorStoreProviders.Bedrock} logo` });
- expect(logo.getAttribute("src")).toBe(providerLogoMap[Providers.Bedrock]);
+ expect(logo).toHaveAttribute("src", providerLogoMap[Providers.Bedrock]);
});
});
diff --git a/ui/litellm-dashboard/src/app/chat/page.integration.test.tsx b/ui/litellm-dashboard/src/app/chat/page.integration.test.tsx
index 718c692a7a6..1918d19dae6 100644
--- a/ui/litellm-dashboard/src/app/chat/page.integration.test.tsx
+++ b/ui/litellm-dashboard/src/app/chat/page.integration.test.tsx
@@ -69,7 +69,7 @@ const ON_TOTAL_LATENCY_INDEX = 24;
async function sendOneMessage(): Promise {
render();
- await waitFor(() => expect(screen.getByRole("button", { name: /gpt-5\.4-mini/ })).toBeInTheDocument());
+ expect(await screen.findByRole("button", { name: /gpt-5\.4-mini/ })).toBeInTheDocument();
fireEvent.change(screen.getByPlaceholderText("How can I help you today?"), {
target: { value: "How much did this cost?" },
});
@@ -98,7 +98,7 @@ describe("/ui/chat request metrics", () => {
await sendOneMessage();
- await waitFor(() => expect(screen.getByLabelText("Total: 20")).toBeInTheDocument());
+ expect(await screen.findByLabelText("Total: 20")).toBeInTheDocument();
expect(screen.getByLabelText("TTFT: 0.25s")).toBeInTheDocument();
expect(screen.getByLabelText("Total Latency: 1.20s")).toBeInTheDocument();
expect(screen.getByLabelText("In: 12")).toBeInTheDocument();
@@ -126,7 +126,7 @@ describe("/ui/chat request metrics", () => {
await sendOneMessage();
- await waitFor(() => expect(screen.getByText("No usage here.")).toBeInTheDocument());
+ expect(await screen.findByText("No usage here.")).toBeInTheDocument();
expect(document.querySelector(".response-metrics")).toBeNull();
});
});
diff --git a/ui/litellm-dashboard/src/components/AIHub/UsefulLinksManagement.test.tsx b/ui/litellm-dashboard/src/components/AIHub/UsefulLinksManagement.test.tsx
index 0a859ca95f8..3a66efd9fe1 100644
--- a/ui/litellm-dashboard/src/components/AIHub/UsefulLinksManagement.test.tsx
+++ b/ui/litellm-dashboard/src/components/AIHub/UsefulLinksManagement.test.tsx
@@ -84,7 +84,7 @@ describe("UsefulLinksManagement", () => {
render();
- await waitFor(() => expect(screen.getByText("First Link")).toBeInTheDocument());
+ expect(await screen.findByText("First Link")).toBeInTheDocument();
await user.click(screen.getByRole("button", { name: /rearrange order/i }));
@@ -123,7 +123,7 @@ describe("UsefulLinksManagement", () => {
render();
- await waitFor(() => expect(screen.getByText("Test Link")).toBeInTheDocument());
+ expect(await screen.findByText("Test Link")).toBeInTheDocument();
// Click edit button
const editButton = screen.getByTestId("edit-link-0-Test Link");
@@ -147,7 +147,7 @@ describe("UsefulLinksManagement", () => {
render();
- await waitFor(() => expect(screen.getByText("Test Link")).toBeInTheDocument());
+ expect(await screen.findByText("Test Link")).toBeInTheDocument();
// Click edit button
const editButton = screen.getByTestId("edit-link-0-Test Link");
@@ -183,7 +183,7 @@ describe("UsefulLinksManagement", () => {
render();
- await waitFor(() => expect(screen.getByText("Test Link")).toBeInTheDocument());
+ expect(await screen.findByText("Test Link")).toBeInTheDocument();
// Click edit button
const editButton = screen.getByTestId("edit-link-0-Test Link");
@@ -216,7 +216,7 @@ describe("UsefulLinksManagement", () => {
render();
- await waitFor(() => expect(screen.getByText("First Link")).toBeInTheDocument());
+ expect(await screen.findByText("First Link")).toBeInTheDocument();
// Enter rearrange mode
await user.click(screen.getByRole("button", { name: /rearrange order/i }));
@@ -235,7 +235,7 @@ describe("UsefulLinksManagement", () => {
const user = userEvent.setup();
render();
- await waitFor(() => expect(screen.getByText("Link Management")).toBeInTheDocument());
+ expect(await screen.findByText("Link Management")).toBeInTheDocument();
// Initially expanded
expect(screen.getByText("Manage Existing Links")).toBeInTheDocument();
diff --git a/ui/litellm-dashboard/src/components/AIHub/forms/MakeAgentPublicForm.test.tsx b/ui/litellm-dashboard/src/components/AIHub/forms/MakeAgentPublicForm.test.tsx
index a55beaf517f..882e059e327 100644
--- a/ui/litellm-dashboard/src/components/AIHub/forms/MakeAgentPublicForm.test.tsx
+++ b/ui/litellm-dashboard/src/components/AIHub/forms/MakeAgentPublicForm.test.tsx
@@ -74,7 +74,7 @@ describe("MakeAgentPublicForm", () => {
// Check that the Next button is enabled (agents are preselected)
const nextButton = screen.getByRole("button", { name: "Next" });
- expect(nextButton).not.toBeDisabled();
+ expect(nextButton).toBeEnabled();
});
it("should handle agent selection and navigation", async () => {
@@ -91,7 +91,7 @@ describe("MakeAgentPublicForm", () => {
// Verify Next button is enabled
const nextButton = screen.getByRole("button", { name: "Next" });
- expect(nextButton).not.toBeDisabled();
+ expect(nextButton).toBeEnabled();
// Click Next
await act(async () => {
diff --git a/ui/litellm-dashboard/src/components/AIHub/forms/MakeMCPPublicForm.test.tsx b/ui/litellm-dashboard/src/components/AIHub/forms/MakeMCPPublicForm.test.tsx
index ff385b3ed7c..5b96e9ad194 100644
--- a/ui/litellm-dashboard/src/components/AIHub/forms/MakeMCPPublicForm.test.tsx
+++ b/ui/litellm-dashboard/src/components/AIHub/forms/MakeMCPPublicForm.test.tsx
@@ -97,7 +97,7 @@ describe("MakeMCPPublicForm", () => {
// Check that the Next button is enabled (servers are preselected)
const nextButton = screen.getByRole("button", { name: "Next" });
- expect(nextButton).not.toBeDisabled();
+ expect(nextButton).toBeEnabled();
});
it("should handle server selection and navigation", async () => {
@@ -114,7 +114,7 @@ describe("MakeMCPPublicForm", () => {
// Verify Next button is enabled
const nextButton = screen.getByRole("button", { name: "Next" });
- expect(nextButton).not.toBeDisabled();
+ expect(nextButton).toBeEnabled();
// Click Next
await act(async () => {
diff --git a/ui/litellm-dashboard/src/components/AIHub/forms/MakeModelPublicForm.test.tsx b/ui/litellm-dashboard/src/components/AIHub/forms/MakeModelPublicForm.test.tsx
index ac0df137f6a..013d92ea463 100644
--- a/ui/litellm-dashboard/src/components/AIHub/forms/MakeModelPublicForm.test.tsx
+++ b/ui/litellm-dashboard/src/components/AIHub/forms/MakeModelPublicForm.test.tsx
@@ -121,7 +121,7 @@ describe("MakeModelPublicForm", () => {
// Check that the Next button is enabled (models are preselected)
const nextButton = screen.getByRole("button", { name: "Next" });
- expect(nextButton).not.toBeDisabled();
+ expect(nextButton).toBeEnabled();
});
it("should handle model selection and navigation", async () => {
@@ -138,7 +138,7 @@ describe("MakeModelPublicForm", () => {
// Verify Next button is enabled
const nextButton = screen.getByRole("button", { name: "Next" });
- expect(nextButton).not.toBeDisabled();
+ expect(nextButton).toBeEnabled();
// Click Next
await act(async () => {
diff --git a/ui/litellm-dashboard/src/components/BetaBadge.test.tsx b/ui/litellm-dashboard/src/components/BetaBadge.test.tsx
index 7eaf414087d..888842feada 100644
--- a/ui/litellm-dashboard/src/components/BetaBadge.test.tsx
+++ b/ui/litellm-dashboard/src/components/BetaBadge.test.tsx
@@ -47,7 +47,7 @@ describe("BetaBadge", () => {
const { container } = render();
- expect(container.firstChild).toBeNull();
+ expect(container).toBeEmptyDOMElement();
});
it("should render badge with dot instead of text when dot prop is true", () => {
diff --git a/ui/litellm-dashboard/src/components/DashboardHeader.test.tsx b/ui/litellm-dashboard/src/components/DashboardHeader.test.tsx
index 6f08dc8ebd4..6c656382deb 100644
--- a/ui/litellm-dashboard/src/components/DashboardHeader.test.tsx
+++ b/ui/litellm-dashboard/src/components/DashboardHeader.test.tsx
@@ -1,5 +1,5 @@
import { afterEach, describe, expect, it, vi } from "vitest";
-import { act, fireEvent, render, screen, waitFor } from "@testing-library/react";
+import { act, fireEvent, render, screen } from "@testing-library/react";
import { DashboardHeader } from "./DashboardHeader";
const { mockUsePluginMode, mockUseUISettings, state } = vi.hoisted(() => {
@@ -44,7 +44,7 @@ describe("DashboardHeader breadcrumb", () => {
act(() => {
fireEvent.click(selector);
});
- await waitFor(() => expect(screen.getByText("Chat")).toBeInTheDocument());
+ expect(await screen.findByText("Chat")).toBeInTheDocument();
});
it("keeps the AI Gateway selector at the root even when there is nothing to switch to (discovery)", () => {
diff --git a/ui/litellm-dashboard/src/components/Navbar/BlogDropdown/BlogDropdown.test.tsx b/ui/litellm-dashboard/src/components/Navbar/BlogDropdown/BlogDropdown.test.tsx
index bad740fa361..0581a381a9a 100644
--- a/ui/litellm-dashboard/src/components/Navbar/BlogDropdown/BlogDropdown.test.tsx
+++ b/ui/litellm-dashboard/src/components/Navbar/BlogDropdown/BlogDropdown.test.tsx
@@ -197,12 +197,10 @@ describe("BlogDropdown", () => {
await openDropdown();
- await waitFor(() => {
- const link = screen.getByRole("link", { name: /post one/i });
- expect(link).toHaveAttribute("href", "https://example.com/1");
- expect(link).toHaveAttribute("target", "_blank");
- expect(link).toHaveAttribute("rel", "noopener noreferrer");
- });
+ const link = await screen.findByRole("link", { name: /post one/i });
+ expect(link).toHaveAttribute("href", "https://example.com/1");
+ expect(link).toHaveAttribute("rel", "noopener noreferrer");
+ expect(link).toHaveAttribute("target", "_blank");
});
it("should render formatted post dates", async () => {
@@ -226,12 +224,10 @@ describe("BlogDropdown", () => {
await openDropdown();
- await waitFor(() => {
- const viewAllLink = screen.getByRole("link", { 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");
- });
+ const viewAllLink = await screen.findByRole("link", { name: /view all posts/i });
+ expect(viewAllLink).toHaveAttribute("href", "https://docs.litellm.ai/blog");
+ expect(viewAllLink).toHaveAttribute("rel", "noopener noreferrer");
+ expect(viewAllLink).toHaveAttribute("target", "_blank");
});
});
diff --git a/ui/litellm-dashboard/src/components/Navbar/ViewSwitcher.test.tsx b/ui/litellm-dashboard/src/components/Navbar/ViewSwitcher.test.tsx
index d9a28b2ab8c..449ef2eddc6 100644
--- a/ui/litellm-dashboard/src/components/Navbar/ViewSwitcher.test.tsx
+++ b/ui/litellm-dashboard/src/components/Navbar/ViewSwitcher.test.tsx
@@ -1,5 +1,5 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
-import { act, fireEvent, render, screen, waitFor } from "@testing-library/react";
+import { act, fireEvent, render, screen } from "@testing-library/react";
import ViewSwitcher from "./ViewSwitcher";
const { mockUsePluginMode, mockUseUISettings, mockUsePathname, state } = vi.hoisted(() => {
@@ -58,7 +58,7 @@ describe("ViewSwitcher", () => {
act(() => {
fireEvent.click(button);
});
- await waitFor(() => expect(screen.getByText("Chat")).toBeInTheDocument());
+ expect(await screen.findByText("Chat")).toBeInTheDocument();
expect(screen.getByText(/Admins can enable in Settings/i)).toBeInTheDocument();
act(() => {
@@ -81,7 +81,7 @@ describe("ViewSwitcher", () => {
act(() => {
fireEvent.click(screen.getByRole("button"));
});
- await waitFor(() => expect(screen.getByText("AI Gateway")).toBeInTheDocument());
+ expect(await screen.findByText("AI Gateway")).toBeInTheDocument();
expect(screen.getByText("Observability")).toBeInTheDocument();
});
@@ -93,7 +93,7 @@ describe("ViewSwitcher", () => {
act(() => {
fireEvent.click(screen.getByRole("button"));
});
- await waitFor(() => expect(screen.getByText("Chat UI")).toBeInTheDocument());
+ expect(await screen.findByText("Chat UI")).toBeInTheDocument();
act(() => {
fireEvent.click(screen.getByText("Chat UI"));
});
@@ -108,7 +108,7 @@ describe("ViewSwitcher", () => {
act(() => {
fireEvent.click(screen.getByRole("button"));
});
- await waitFor(() => expect(screen.getByText("Chat")).toBeInTheDocument());
+ expect(await screen.findByText("Chat")).toBeInTheDocument();
expect(screen.queryByText(/Admins can enable in Settings/i)).not.toBeInTheDocument();
act(() => {
@@ -127,7 +127,7 @@ describe("ViewSwitcher", () => {
act(() => {
fireEvent.click(screen.getByRole("button"));
});
- await waitFor(() => expect(screen.getByText("AI Gateway")).toBeInTheDocument());
+ expect(await screen.findByText("AI Gateway")).toBeInTheDocument();
act(() => {
fireEvent.click(screen.getByText("AI Gateway"));
});
@@ -143,7 +143,7 @@ describe("ViewSwitcher", () => {
act(() => {
fireEvent.click(screen.getByRole("button"));
});
- await waitFor(() => expect(screen.getByText("Observability")).toBeInTheDocument());
+ expect(await screen.findByText("Observability")).toBeInTheDocument();
expect(screen.getByText("Chat")).toBeInTheDocument();
expect(screen.getByText(/Admins can enable in Settings/i)).toBeInTheDocument();
diff --git a/ui/litellm-dashboard/src/components/SSOModals.test.tsx b/ui/litellm-dashboard/src/components/SSOModals.test.tsx
index 0fcfe60ffe8..783fd58392a 100644
--- a/ui/litellm-dashboard/src/components/SSOModals.test.tsx
+++ b/ui/litellm-dashboard/src/components/SSOModals.test.tsx
@@ -67,10 +67,8 @@ describe("SSOModals", () => {
const ssoProviderSelect = screen.getByLabelText("SSO Provider");
fireEvent.mouseDown(ssoProviderSelect);
// Wait for dropdown and select Google
- await waitFor(() => {
- const googleOption = screen.getByText("Google SSO");
- fireEvent.click(googleOption);
- });
+ const googleOption = await screen.findByText("Google SSO");
+ fireEvent.click(googleOption);
// Fill in the email field
const emailInput = screen.getByLabelText("Proxy Admin Email");
@@ -119,10 +117,8 @@ describe("SSOModals", () => {
const ssoProviderSelect = screen.getByLabelText("SSO Provider");
fireEvent.mouseDown(ssoProviderSelect);
// Wait for dropdown and select Google
- await waitFor(() => {
- const googleOption = screen.getByText("Google SSO");
- fireEvent.click(googleOption);
- });
+ const googleOption = await screen.findByText("Google SSO");
+ fireEvent.click(googleOption);
// Fill in the email field
const emailInput = screen.getByLabelText("Proxy Admin Email");
@@ -216,10 +212,8 @@ describe("SSOModals", () => {
const ssoProviderSelect = screen.getByLabelText("SSO Provider");
fireEvent.mouseDown(ssoProviderSelect);
// Wait for dropdown and select Google
- await waitFor(() => {
- const googleOption = screen.getByText("Google SSO");
- fireEvent.click(googleOption);
- });
+ const googleOption = await screen.findByText("Google SSO");
+ fireEvent.click(googleOption);
// Fill in the email field
const emailInput = screen.getByLabelText("Proxy Admin Email");
diff --git a/ui/litellm-dashboard/src/components/Settings/AdminSettings/MCPSemanticFilterSettings/MCPSemanticFilterSettings.test.tsx b/ui/litellm-dashboard/src/components/Settings/AdminSettings/MCPSemanticFilterSettings/MCPSemanticFilterSettings.test.tsx
index 39542945c45..af2cc0beb7e 100644
--- a/ui/litellm-dashboard/src/components/Settings/AdminSettings/MCPSemanticFilterSettings/MCPSemanticFilterSettings.test.tsx
+++ b/ui/litellm-dashboard/src/components/Settings/AdminSettings/MCPSemanticFilterSettings/MCPSemanticFilterSettings.test.tsx
@@ -143,7 +143,7 @@ describe("MCPSemanticFilterSettings", () => {
await user.click(screen.getByRole("switch"));
- expect(screen.getByRole("button", { name: /save settings/i })).not.toBeDisabled();
+ expect(screen.getByRole("button", { name: /save settings/i })).toBeEnabled();
});
it("should show an error alert when the mutation fails", async () => {
diff --git a/ui/litellm-dashboard/src/components/Settings/AdminSettings/MCPSemanticFilterSettings/MCPSemanticFilterTestPanel.test.tsx b/ui/litellm-dashboard/src/components/Settings/AdminSettings/MCPSemanticFilterSettings/MCPSemanticFilterTestPanel.test.tsx
index c35caffc4be..2362f5ead60 100644
--- a/ui/litellm-dashboard/src/components/Settings/AdminSettings/MCPSemanticFilterSettings/MCPSemanticFilterTestPanel.test.tsx
+++ b/ui/litellm-dashboard/src/components/Settings/AdminSettings/MCPSemanticFilterSettings/MCPSemanticFilterTestPanel.test.tsx
@@ -69,7 +69,7 @@ describe("MCPSemanticFilterTestPanel", () => {
it("should enable the Test Filter button when testQuery is set and filter is enabled", () => {
render();
- expect(screen.getByRole("button", { name: /test filter/i })).not.toBeDisabled();
+ expect(screen.getByRole("button", { name: /test filter/i })).toBeEnabled();
});
it("should call onTest when the Test Filter button is clicked", async () => {
diff --git a/ui/litellm-dashboard/src/components/Settings/AdminSettings/SSOSettings/Modals/BaseSSOSettingsForm.test.tsx b/ui/litellm-dashboard/src/components/Settings/AdminSettings/SSOSettings/Modals/BaseSSOSettingsForm.test.tsx
index 2f9c49dfa56..8043e41a2de 100644
--- a/ui/litellm-dashboard/src/components/Settings/AdminSettings/SSOSettings/Modals/BaseSSOSettingsForm.test.tsx
+++ b/ui/litellm-dashboard/src/components/Settings/AdminSettings/SSOSettings/Modals/BaseSSOSettingsForm.test.tsx
@@ -39,10 +39,8 @@ describe("BaseSSOSettingsForm", () => {
fireEvent.mouseDown(providerSelect);
});
- await waitFor(() => {
- const googleOption = screen.getByText(/google sso/i);
- fireEvent.click(googleOption);
- });
+ const googleOption = await screen.findByText(/google sso/i);
+ fireEvent.click(googleOption);
await waitFor(() => {
expect(screen.getByText("Google Client ID")).toBeInTheDocument();
@@ -65,10 +63,8 @@ describe("BaseSSOSettingsForm", () => {
fireEvent.mouseDown(providerSelect);
});
- await waitFor(() => {
- const oktaOption = screen.getByText(/okta/i);
- fireEvent.click(oktaOption);
- });
+ const oktaOption = await screen.findByText(/okta/i);
+ fireEvent.click(oktaOption);
await waitFor(() => {
expect(screen.getByText("Use Role Mappings")).toBeInTheDocument();
@@ -132,10 +128,8 @@ describe("BaseSSOSettingsForm", () => {
fireEvent.mouseDown(providerSelect);
});
- await waitFor(() => {
- const genericOption = screen.getByText(/generic sso/i);
- fireEvent.click(genericOption);
- });
+ const genericOption = await screen.findByText(/generic sso/i);
+ fireEvent.click(genericOption);
await waitFor(() => {
expect(screen.getByText("Use Role Mappings")).toBeInTheDocument();
@@ -167,10 +161,8 @@ describe("BaseSSOSettingsForm", () => {
fireEvent.mouseDown(providerSelect);
});
- await waitFor(() => {
- const oktaOption = screen.getByText(/okta/i);
- fireEvent.click(oktaOption);
- });
+ const oktaOption = await screen.findByText(/okta/i);
+ fireEvent.click(oktaOption);
await waitFor(() => {
expect(screen.getByText("Use Team Mappings")).toBeInTheDocument();
@@ -192,10 +184,8 @@ describe("BaseSSOSettingsForm", () => {
fireEvent.mouseDown(providerSelect);
});
- await waitFor(() => {
- const genericOption = screen.getByText(/generic sso/i);
- fireEvent.click(genericOption);
- });
+ const genericOption = await screen.findByText(/generic sso/i);
+ fireEvent.click(genericOption);
await waitFor(() => {
expect(screen.getByText("Use Team Mappings")).toBeInTheDocument();
@@ -217,10 +207,8 @@ describe("BaseSSOSettingsForm", () => {
fireEvent.mouseDown(providerSelect);
});
- await waitFor(() => {
- const oktaOption = screen.getByText(/okta/i);
- fireEvent.click(oktaOption);
- });
+ const oktaOption = await screen.findByText(/okta/i);
+ fireEvent.click(oktaOption);
await waitFor(() => {
expect(screen.getByText("Use Team Mappings")).toBeInTheDocument();
@@ -251,10 +239,8 @@ describe("BaseSSOSettingsForm", () => {
fireEvent.mouseDown(providerSelect);
});
- await waitFor(() => {
- const googleOption = screen.getByText(/google sso/i);
- fireEvent.click(googleOption);
- });
+ const googleOption = await screen.findByText(/google sso/i);
+ fireEvent.click(googleOption);
await waitFor(() => {
expect(screen.getByText("Google Client ID")).toBeInTheDocument();
diff --git a/ui/litellm-dashboard/src/components/Settings/AdminSettings/SSOSettings/RoleMappings.test.tsx b/ui/litellm-dashboard/src/components/Settings/AdminSettings/SSOSettings/RoleMappings.test.tsx
index f4b7b9aadd4..8a1b9bc99ed 100644
--- a/ui/litellm-dashboard/src/components/Settings/AdminSettings/SSOSettings/RoleMappings.test.tsx
+++ b/ui/litellm-dashboard/src/components/Settings/AdminSettings/SSOSettings/RoleMappings.test.tsx
@@ -26,7 +26,7 @@ describe("RoleMappings", () => {
it("should return null when roleMappings is undefined", () => {
const { container } = renderWithProviders();
- expect(container.firstChild).toBeNull();
+ expect(container).toBeEmptyDOMElement();
});
it("should display Group Claim and Default Role with correct values and display names", () => {
diff --git a/ui/litellm-dashboard/src/components/Settings/RouterSettings/Fallbacks/AddFallbacks.test.tsx b/ui/litellm-dashboard/src/components/Settings/RouterSettings/Fallbacks/AddFallbacks.test.tsx
index 1253532f269..1cdb57335ce 100644
--- a/ui/litellm-dashboard/src/components/Settings/RouterSettings/Fallbacks/AddFallbacks.test.tsx
+++ b/ui/litellm-dashboard/src/components/Settings/RouterSettings/Fallbacks/AddFallbacks.test.tsx
@@ -189,7 +189,7 @@ describe("AddFallbacks", () => {
});
const saveButton = screen.getByRole("button", { name: /save all configurations/i });
- expect(saveButton).not.toBeDisabled();
+ expect(saveButton).toBeEnabled();
await user.click(saveButton);
await waitFor(() => {
diff --git a/ui/litellm-dashboard/src/components/Settings/RouterSettings/Fallbacks/Fallbacks.test.tsx b/ui/litellm-dashboard/src/components/Settings/RouterSettings/Fallbacks/Fallbacks.test.tsx
index a397b061801..cdcb1eefadb 100644
--- a/ui/litellm-dashboard/src/components/Settings/RouterSettings/Fallbacks/Fallbacks.test.tsx
+++ b/ui/litellm-dashboard/src/components/Settings/RouterSettings/Fallbacks/Fallbacks.test.tsx
@@ -125,7 +125,7 @@ describe("Fallbacks", () => {
it("should not render when accessToken is null", () => {
const { container } = renderWithQueryClient();
- expect(container.firstChild).toBeNull();
+ expect(container).toBeEmptyDOMElement();
});
it("should fetch router settings on mount", async () => {
diff --git a/ui/litellm-dashboard/src/components/TeamSSOSettings.test.tsx b/ui/litellm-dashboard/src/components/TeamSSOSettings.test.tsx
index 8fd03d7340f..9b4e0527190 100644
--- a/ui/litellm-dashboard/src/components/TeamSSOSettings.test.tsx
+++ b/ui/litellm-dashboard/src/components/TeamSSOSettings.test.tsx
@@ -368,7 +368,7 @@ describe("TeamSSOSettings", () => {
await userEvent.click(screen.getByRole("button", { name: /Edit Settings/i }));
const permissionComboboxes = screen.getAllByRole("combobox");
const permissionCombobox = permissionComboboxes[permissionComboboxes.length - 1];
- expect(permissionCombobox).toBeDefined();
+ expect(permissionCombobox).toBeInTheDocument();
await userEvent.click(permissionCombobox!);
const deletePermissionOptions = await screen.findAllByText("/key/delete");
await userEvent.click(deletePermissionOptions[deletePermissionOptions.length - 1]);
diff --git a/ui/litellm-dashboard/src/components/TeamsPage/TeamsTable.test.tsx b/ui/litellm-dashboard/src/components/TeamsPage/TeamsTable.test.tsx
index 71c6aa66cf3..9375673ba10 100644
--- a/ui/litellm-dashboard/src/components/TeamsPage/TeamsTable.test.tsx
+++ b/ui/litellm-dashboard/src/components/TeamsPage/TeamsTable.test.tsx
@@ -151,7 +151,7 @@ describe("sort contract – only backend-sortable columns are sortable", () => {
it("does not make Spend / Budget sortable (the backend rejects sort_by=spend)", () => {
renderTable();
- expect(screen.getByText("Spend / Budget").closest("button")).toBeNull();
+ expect(screen.queryByText("Spend / Budget").closest("button")).toBeNull();
// Team and Created are the only sortable headers.
expect(screen.getByText("Team").closest("button")).not.toBeNull();
expect(screen.getByText("Created").closest("button")).not.toBeNull();
diff --git a/ui/litellm-dashboard/src/components/UsagePage/components/EntityUsage/TopKeyView.test.tsx b/ui/litellm-dashboard/src/components/UsagePage/components/EntityUsage/TopKeyView.test.tsx
index be13ea1a7d3..dda1b805582 100644
--- a/ui/litellm-dashboard/src/components/UsagePage/components/EntityUsage/TopKeyView.test.tsx
+++ b/ui/litellm-dashboard/src/components/UsagePage/components/EntityUsage/TopKeyView.test.tsx
@@ -152,7 +152,7 @@ describe("TopKeyView", () => {
const bars = container.querySelectorAll("path.recharts-rectangle");
expect(bars).toHaveLength(1);
- expect(bars[0].getAttribute("fill")).toBe("var(--color-cyan-500, #06b6d4)");
+ expect(bars[0]).toHaveAttribute("fill", "var(--color-cyan-500, #06b6d4)");
expect(screen.getAllByText("A Very Lon...").length).toBeGreaterThan(0);
fireEvent.click(bars[0]);
diff --git a/ui/litellm-dashboard/src/components/UsagePage/components/KeyModelUsageView.test.tsx b/ui/litellm-dashboard/src/components/UsagePage/components/KeyModelUsageView.test.tsx
index 024226c3c03..d513d7c3a80 100644
--- a/ui/litellm-dashboard/src/components/UsagePage/components/KeyModelUsageView.test.tsx
+++ b/ui/litellm-dashboard/src/components/UsagePage/components/KeyModelUsageView.test.tsx
@@ -31,7 +31,7 @@ describe("KeyModelUsageView", () => {
it("should return null when topModels is empty", () => {
const { container } = render();
- expect(container.firstChild).toBeNull();
+ expect(container).toBeEmptyDOMElement();
});
it("should display Model Usage title", () => {
diff --git a/ui/litellm-dashboard/src/components/VirtualKeysPage/VirtualKeysTable.test.tsx b/ui/litellm-dashboard/src/components/VirtualKeysPage/VirtualKeysTable.test.tsx
index 0910925a940..9ef849dbeb2 100644
--- a/ui/litellm-dashboard/src/components/VirtualKeysPage/VirtualKeysTable.test.tsx
+++ b/ui/litellm-dashboard/src/components/VirtualKeysPage/VirtualKeysTable.test.tsx
@@ -339,13 +339,9 @@ it("emphasizes the active field in the Spend / Budget header so the sorted colum
await user.click(await screen.findByText("Budget descending"));
await waitFor(() => {
- expect(screen.getByText("Budget", { selector: "[data-sort-field='max_budget']" }).className).toContain(
- "font-semibold",
- );
+ expect(screen.getByText("Budget", { selector: "[data-sort-field='max_budget']" })).toHaveClass("font-semibold");
});
- expect(screen.getByText("Spend", { selector: "[data-sort-field='spend']" }).className).toContain(
- "text-muted-foreground",
- );
+ expect(screen.getByText("Spend", { selector: "[data-sort-field='spend']" })).toHaveClass("text-muted-foreground");
});
it("sorts by spend ascending when 'Spend ascending' is chosen from the Spend / Budget menu", async () => {
@@ -537,7 +533,7 @@ describe("refresh button", () => {
const refresh = screen.getByTestId("datatable-refresh");
expect(refresh).toBeInTheDocument();
- expect(refresh).not.toBeDisabled();
+ expect(refresh).toBeEnabled();
});
it("disables the refresh control while a fetch is in flight but keeps data visible", () => {
diff --git a/ui/litellm-dashboard/src/components/add_model/ClassifierPromptEditor.integration.test.tsx b/ui/litellm-dashboard/src/components/add_model/ClassifierPromptEditor.integration.test.tsx
index f80753bc9a8..c35457630a5 100644
--- a/ui/litellm-dashboard/src/components/add_model/ClassifierPromptEditor.integration.test.tsx
+++ b/ui/litellm-dashboard/src/components/add_model/ClassifierPromptEditor.integration.test.tsx
@@ -1,4 +1,4 @@
-import { renderWithProviders, screen, waitFor } from "../../../tests/test-utils";
+import { renderWithProviders, screen } from "../../../tests/test-utils";
import userEvent from "@testing-library/user-event";
import { vi } from "vitest";
import ClassifierPromptEditor from "./ClassifierPromptEditor";
@@ -45,7 +45,7 @@ const openEditor = async ({
/>,
);
await userEvent.click(screen.getByRole("button", { name: /prompt/i }));
- await waitFor(() => expect(screen.getByLabelText("Classifier system prompt")).toBeInTheDocument());
+ expect(await screen.findByLabelText("Classifier system prompt")).toBeInTheDocument();
return onChange;
};
diff --git a/ui/litellm-dashboard/src/components/add_model/add_auto_router_tab.test.tsx b/ui/litellm-dashboard/src/components/add_model/add_auto_router_tab.test.tsx
index f94f3306291..27ede9159a8 100644
--- a/ui/litellm-dashboard/src/components/add_model/add_auto_router_tab.test.tsx
+++ b/ui/litellm-dashboard/src/components/add_model/add_auto_router_tab.test.tsx
@@ -455,7 +455,7 @@ describe("AddAutoRouterTab", () => {
const anthropicOption = optionByLabel("Anthropic Family")!;
expect(isOptionDisabled(anthropicOption)).toBe(true);
- expect(anthropicOption.textContent).toContain("Checking model availability");
+ expect(anthropicOption).toHaveTextContent(/Checking model availability/);
// The dropdown is already open from above; polling re-reads its options in place rather than
// reopening (openTemplateDropdown toggles, so a second call here would close it instead).
@@ -474,7 +474,7 @@ describe("AddAutoRouterTab", () => {
openTemplateDropdown();
const anthropicOption = optionByLabel("Anthropic Family")!;
expect(isOptionDisabled(anthropicOption)).toBe(true);
- expect(anthropicOption.textContent).toContain("Cannot verify these models are available");
+ expect(anthropicOption).toHaveTextContent(/Cannot verify these models are available/);
});
it("keeps group-name presets selectable when only the deployment fetch fails", async () => {
@@ -496,7 +496,7 @@ describe("AddAutoRouterTab", () => {
openTemplateDropdown();
await waitFor(() => {
- expect(optionByLabel("Anthropic Family")!.textContent).toContain(`Missing: ${ANTHROPIC_ONLY_MODEL}`);
+ expect(optionByLabel("Anthropic Family")!).toHaveTextContent(new RegExp(`Missing: ${ANTHROPIC_ONLY_MODEL}`));
});
expect(isOptionDisabled(optionByLabel("Anthropic Family")!)).toBe(true);
});
@@ -695,7 +695,7 @@ describe("AddAutoRouterTab", () => {
await waitFor(() => {
expect(isOptionDisabled(optionByLabel("Anthropic Family")!)).toBe(false);
});
- expect(optionByLabel("Anthropic Family")!.textContent).toContain("Matches your deployments");
+ expect(optionByLabel("Anthropic Family")!).toHaveTextContent(/Matches your deployments/);
});
it("keeps detailed configuration open and prefills the admin's group names on apply", async () => {
@@ -755,7 +755,7 @@ describe("AddAutoRouterTab", () => {
openTemplateDropdown();
await waitFor(() => {
- expect(optionByLabel("OpenAI Family")!.textContent).toContain("Missing:");
+ expect(optionByLabel("OpenAI Family")!).toHaveTextContent(/Missing:/);
});
expect(isOptionDisabled(optionByLabel("OpenAI Family")!)).toBe(true);
});
@@ -784,7 +784,7 @@ describe("AddAutoRouterTab", () => {
await waitFor(() => {
expect(isOptionDisabled(optionByLabel("Anthropic Family")!)).toBe(false);
});
- expect(optionByLabel("Anthropic Family")!.textContent).toContain("Matches your deployments");
+ expect(optionByLabel("Anthropic Family")!).toHaveTextContent(/Matches your deployments/);
});
it("prefills the expanded group names and submits them", async () => {
diff --git a/ui/litellm-dashboard/src/components/add_model/auto_router_connection_test.test.tsx b/ui/litellm-dashboard/src/components/add_model/auto_router_connection_test.test.tsx
index b07270b5ced..41fb773dc96 100644
--- a/ui/litellm-dashboard/src/components/add_model/auto_router_connection_test.test.tsx
+++ b/ui/litellm-dashboard/src/components/add_model/auto_router_connection_test.test.tsx
@@ -44,7 +44,7 @@ describe("AutoRouterConnectionTest", () => {
renderWithProviders();
await waitFor(() => expect(screen.getAllByTestId("test-status-success")).toHaveLength(3));
- expect(screen.queryByTestId("test-status-error")).toBeNull();
+ expect(screen.queryByTestId("test-status-error")).not.toBeInTheDocument();
expect(screen.getByText("MEDIUM, COMPLEX")).toBeInTheDocument();
});
@@ -60,7 +60,7 @@ describe("AutoRouterConnectionTest", () => {
renderWithProviders();
- await waitFor(() => expect(screen.getByTestId("test-error-message")).toBeInTheDocument());
+ expect(await screen.findByTestId("test-error-message")).toBeInTheDocument();
expect(screen.getByTestId("test-error-message")).toHaveTextContent("invalid api key");
expect(screen.getByTestId("test-error-message")).not.toHaveTextContent("litellm.AuthenticationError");
expect(screen.getAllByTestId("test-status-success")).toHaveLength(2);
diff --git a/ui/litellm-dashboard/src/components/add_model/litellm_model_name.test.tsx b/ui/litellm-dashboard/src/components/add_model/litellm_model_name.test.tsx
index f1fd3fecb37..37eecec1f3f 100644
--- a/ui/litellm-dashboard/src/components/add_model/litellm_model_name.test.tsx
+++ b/ui/litellm-dashboard/src/components/add_model/litellm_model_name.test.tsx
@@ -25,6 +25,6 @@ describe("LitellmModelNameField", () => {
,
);
expect(getByPlaceholderText("my-deployment")).toBeInTheDocument();
- expect(queryByPlaceholderText("gpt-3.5-turbo")).toBeNull();
+ expect(queryByPlaceholderText("gpt-3.5-turbo")).not.toBeInTheDocument();
});
});
diff --git a/ui/litellm-dashboard/src/components/add_model/provider_specific_fields.test.tsx b/ui/litellm-dashboard/src/components/add_model/provider_specific_fields.test.tsx
index c2b730bf46a..bf62b4873b7 100644
--- a/ui/litellm-dashboard/src/components/add_model/provider_specific_fields.test.tsx
+++ b/ui/litellm-dashboard/src/components/add_model/provider_specific_fields.test.tsx
@@ -150,17 +150,15 @@ describe("ProviderSpecificFields", () => {
,
);
- await waitFor(() => {
- const apiKeyLabel = screen.getByLabelText("OpenAI API Key");
- expect(apiKeyLabel).toBeInTheDocument();
+ const apiKeyLabel = await screen.findByLabelText("OpenAI API Key");
+ expect(apiKeyLabel).toBeInTheDocument();
- const apiBaseInput = screen.getByPlaceholderText("https://api.openai.com/v1");
- expect(apiBaseInput).toBeInTheDocument();
- expect(apiBaseInput).toHaveAttribute("type", "text");
+ const apiBaseInput = screen.getByPlaceholderText("https://api.openai.com/v1");
+ expect(apiBaseInput).toBeInTheDocument();
+ expect(apiBaseInput).toHaveAttribute("type", "text");
- const orgInput = screen.getByPlaceholderText("[OPTIONAL] my-unique-org");
- expect(orgInput).toBeInTheDocument();
- });
+ const orgInput = screen.getByPlaceholderText("[OPTIONAL] my-unique-org");
+ expect(orgInput).toBeInTheDocument();
});
it("should render the provider specific fields for vLLM", async () => {
@@ -173,14 +171,12 @@ describe("ProviderSpecificFields", () => {
,
);
- await waitFor(() => {
- const apiKeyLabel = screen.getByLabelText("vLLM API Key");
- expect(apiKeyLabel).toBeInTheDocument();
+ const apiKeyLabel = await screen.findByLabelText("vLLM API Key");
+ expect(apiKeyLabel).toBeInTheDocument();
- const apiBaseInput = screen.getByPlaceholderText("https://...");
- expect(apiBaseInput).toBeInTheDocument();
- expect(apiBaseInput).toHaveAttribute("type", "text");
- });
+ const apiBaseInput = screen.getByPlaceholderText("https://...");
+ expect(apiBaseInput).toBeInTheDocument();
+ expect(apiBaseInput).toHaveAttribute("type", "text");
});
it("should render the provider specific fields for Azure", async () => {
@@ -193,27 +189,25 @@ describe("ProviderSpecificFields", () => {
,
);
- await waitFor(() => {
- const apiKeyInput = screen.getByLabelText("Azure API Key");
- expect(apiKeyInput).toBeInTheDocument();
- expect(apiKeyInput).toHaveAttribute("type", "password");
- expect(apiKeyInput).toHaveAttribute("placeholder", "Enter your Azure API Key");
+ const apiKeyInput = await screen.findByLabelText("Azure API Key");
+ expect(apiKeyInput).toBeInTheDocument();
+ expect(apiKeyInput).toHaveAttribute("type", "password");
+ expect(apiKeyInput).toHaveAttribute("placeholder", "Enter your Azure API Key");
- const azureAdTokenInput = screen.getByLabelText("Azure AD Token");
- expect(azureAdTokenInput).toBeInTheDocument();
- expect(azureAdTokenInput).toHaveAttribute("type", "password");
- expect(azureAdTokenInput).toHaveAttribute("placeholder", "Enter your Azure AD Token");
+ const azureAdTokenInput = screen.getByLabelText("Azure AD Token");
+ expect(azureAdTokenInput).toBeInTheDocument();
+ expect(azureAdTokenInput).toHaveAttribute("type", "password");
+ expect(azureAdTokenInput).toHaveAttribute("placeholder", "Enter your Azure AD Token");
- const apiBaseInput = screen.getByPlaceholderText("https://...");
- expect(apiBaseInput).toBeInTheDocument();
- expect(apiBaseInput).toHaveAttribute("type", "text");
+ const apiBaseInput = screen.getByPlaceholderText("https://...");
+ expect(apiBaseInput).toBeInTheDocument();
+ expect(apiBaseInput).toHaveAttribute("type", "text");
- const apiVersionInput = screen.getByPlaceholderText("2023-07-01-preview");
- expect(apiVersionInput).toBeInTheDocument();
+ const apiVersionInput = screen.getByPlaceholderText("2023-07-01-preview");
+ expect(apiVersionInput).toBeInTheDocument();
- const baseModelInput = screen.getByPlaceholderText("azure/gpt-3.5-turbo");
- expect(baseModelInput).toBeInTheDocument();
- });
+ const baseModelInput = screen.getByPlaceholderText("azure/gpt-3.5-turbo");
+ expect(baseModelInput).toBeInTheDocument();
});
it("sets Azure API version from the API base query parameter", async () => {
diff --git a/ui/litellm-dashboard/src/components/chat/ConnectFlowBanner.test.tsx b/ui/litellm-dashboard/src/components/chat/ConnectFlowBanner.test.tsx
index 4833b4ad8a4..b3cd6e229af 100644
--- a/ui/litellm-dashboard/src/components/chat/ConnectFlowBanner.test.tsx
+++ b/ui/litellm-dashboard/src/components/chat/ConnectFlowBanner.test.tsx
@@ -16,8 +16,8 @@ describe("ConnectFlowBanner", () => {
const { container } = render();
const form = container.querySelector("form")!;
- expect(form.getAttribute("method")).toBe("POST");
- expect(form.getAttribute("action")).toBe("https://gateway.example.com/authorize/complete");
+ expect(form).toHaveAttribute("method", "POST");
+ expect(form).toHaveAttribute("action", "https://gateway.example.com/authorize/complete");
const hidden = form.querySelector('input[name="flow"]') as HTMLInputElement;
expect(hidden.value).toBe("flow-handle-123");
diff --git a/ui/litellm-dashboard/src/components/chat/MCPAppsPanel.test.tsx b/ui/litellm-dashboard/src/components/chat/MCPAppsPanel.test.tsx
index 5fc3e75195b..e8795c36bc6 100644
--- a/ui/litellm-dashboard/src/components/chat/MCPAppsPanel.test.tsx
+++ b/ui/litellm-dashboard/src/components/chat/MCPAppsPanel.test.tsx
@@ -58,8 +58,8 @@ describe("MCPAppsPanel logos", () => {
renderPanel();
expect(await screen.findByText("external_logo")).toBeInTheDocument();
- expect(screen.getByAltText("external_logo logo").getAttribute("src")).toBe("https://cdn.example.com/ext.png");
- expect(screen.getByAltText("local_logo logo").getAttribute("src")).toBe("/litellm/ui/assets/logos/github.svg");
+ expect(screen.getByAltText("external_logo logo")).toHaveAttribute("src", "https://cdn.example.com/ext.png");
+ expect(screen.getByAltText("local_logo logo")).toHaveAttribute("src", "/litellm/ui/assets/logos/github.svg");
});
it("renders a colored letter avatar for servers without logo_url", async () => {
@@ -83,7 +83,7 @@ describe("MCPAppsPanel logos", () => {
fireEvent.click(await screen.findByText("local_logo"));
expect(await screen.findByRole("heading", { name: "local_logo" })).toBeInTheDocument();
- expect(screen.getByAltText("local_logo logo").getAttribute("src")).toBe("/litellm/ui/assets/logos/github.svg");
+ expect(screen.getByAltText("local_logo logo")).toHaveAttribute("src", "/litellm/ui/assets/logos/github.svg");
});
});
@@ -239,7 +239,7 @@ describe("MCPAppsPanel connected-app reachability (LIT-4861)", () => {
expect(onChange).not.toHaveBeenCalled();
expect(screen.queryByText("revoked_srv")).not.toBeInTheDocument();
- expect(screen.getByText("Connected", { exact: false }).textContent).toBe("Connected");
+ expect(screen.getByText("Connected", { exact: false })).toHaveTextContent("Connected");
});
it("does not select a server when Connect resolves in the same tick the refetch drops it", async () => {
diff --git a/ui/litellm-dashboard/src/components/chat/MCPConnectPicker.test.tsx b/ui/litellm-dashboard/src/components/chat/MCPConnectPicker.test.tsx
index f2912d460f0..4093688fcb9 100644
--- a/ui/litellm-dashboard/src/components/chat/MCPConnectPicker.test.tsx
+++ b/ui/litellm-dashboard/src/components/chat/MCPConnectPicker.test.tsx
@@ -40,8 +40,8 @@ describe("MCPConnectPicker logos", () => {
render();
expect(await screen.findByText("external_logo")).toBeInTheDocument();
- expect(screen.getByAltText("external_logo logo").getAttribute("src")).toBe("https://cdn.example.com/ext.png");
- expect(screen.getByAltText("local_logo logo").getAttribute("src")).toBe("/litellm/ui/assets/logos/github.svg");
+ expect(screen.getByAltText("external_logo logo")).toHaveAttribute("src", "https://cdn.example.com/ext.png");
+ expect(screen.getByAltText("local_logo logo")).toHaveAttribute("src", "/litellm/ui/assets/logos/github.svg");
});
it("renders no logo at all for servers without logo_url", async () => {
diff --git a/ui/litellm-dashboard/src/components/common_components/DefaultProxyAdminTag.test.tsx b/ui/litellm-dashboard/src/components/common_components/DefaultProxyAdminTag.test.tsx
index e330bb2e1b9..9236a56a8b9 100644
--- a/ui/litellm-dashboard/src/components/common_components/DefaultProxyAdminTag.test.tsx
+++ b/ui/litellm-dashboard/src/components/common_components/DefaultProxyAdminTag.test.tsx
@@ -22,6 +22,6 @@ describe("DefaultProxyAdminTag", () => {
it("should render empty text when userId is null", () => {
const { container } = render();
expect(screen.queryByText("Default Proxy Admin")).not.toBeInTheDocument();
- expect(container.textContent).toBe("");
+ expect(container).toHaveTextContent("");
});
});
diff --git a/ui/litellm-dashboard/src/components/common_components/DeleteResourceModal.test.tsx b/ui/litellm-dashboard/src/components/common_components/DeleteResourceModal.test.tsx
index 465f7fcfcf0..ebcb8221b1a 100644
--- a/ui/litellm-dashboard/src/components/common_components/DeleteResourceModal.test.tsx
+++ b/ui/litellm-dashboard/src/components/common_components/DeleteResourceModal.test.tsx
@@ -118,7 +118,7 @@ describe("DeleteResourceModal", () => {
const input = screen.getByPlaceholderText("DELETE");
await user.type(input, "DELETE");
const deleteButton = screen.getByRole("button", { name: /delete/i });
- expect(deleteButton).not.toBeDisabled();
+ expect(deleteButton).toBeEnabled();
});
it("should reset requiredConfirmation input when modal opens", async () => {
diff --git a/ui/litellm-dashboard/src/components/common_components/KeyLifecycleSettings.test.tsx b/ui/litellm-dashboard/src/components/common_components/KeyLifecycleSettings.test.tsx
index a4263e2f321..5dca1f65874 100644
--- a/ui/litellm-dashboard/src/components/common_components/KeyLifecycleSettings.test.tsx
+++ b/ui/litellm-dashboard/src/components/common_components/KeyLifecycleSettings.test.tsx
@@ -144,7 +144,7 @@ describe("KeyLifecycleSettings", () => {
expect(screen.queryByText("Rotation Interval")).not.toBeInTheDocument();
await user.click(screen.getByRole("switch"));
- await waitFor(() => expect(screen.getByText("Rotation Interval")).toBeInTheDocument());
+ expect(await screen.findByText("Rotation Interval")).toBeInTheDocument();
});
it("propagates a selected predefined interval", async () => {
@@ -152,7 +152,7 @@ describe("KeyLifecycleSettings", () => {
renderWithProviders();
await user.click(screen.getByRole("switch"));
- await waitFor(() => expect(screen.getByText("Rotation Interval")).toBeInTheDocument());
+ expect(await screen.findByText("Rotation Interval")).toBeInTheDocument();
await user.click(screen.getByRole("combobox"));
await user.click(await screen.findByText("90 days"));
@@ -166,7 +166,7 @@ describe("KeyLifecycleSettings", () => {
renderWithProviders();
await user.click(screen.getByRole("switch"));
- await waitFor(() => expect(screen.getByText("Rotation Interval")).toBeInTheDocument());
+ expect(await screen.findByText("Rotation Interval")).toBeInTheDocument();
await user.click(screen.getByRole("combobox"));
await user.click(await screen.findByText("Custom interval"));
@@ -181,7 +181,7 @@ describe("KeyLifecycleSettings", () => {
renderWithProviders();
await user.click(screen.getByRole("switch"));
- await waitFor(() => expect(screen.getByText("Rotation Interval")).toBeInTheDocument());
+ expect(await screen.findByText("Rotation Interval")).toBeInTheDocument();
await user.click(screen.getByRole("combobox"));
await user.click(await screen.findByText("Custom interval"));
@@ -198,7 +198,7 @@ describe("KeyLifecycleSettings", () => {
renderWithProviders();
await user.click(screen.getByRole("switch"));
- await waitFor(() => expect(screen.getByText("Rotation Interval")).toBeInTheDocument());
+ expect(await screen.findByText("Rotation Interval")).toBeInTheDocument();
await user.click(screen.getByRole("combobox"));
await user.click(await screen.findByText("Custom interval"));
diff --git a/ui/litellm-dashboard/src/components/common_components/NewBadge.test.tsx b/ui/litellm-dashboard/src/components/common_components/NewBadge.test.tsx
index 2500551d37b..3ae24b16e7b 100644
--- a/ui/litellm-dashboard/src/components/common_components/NewBadge.test.tsx
+++ b/ui/litellm-dashboard/src/components/common_components/NewBadge.test.tsx
@@ -47,7 +47,7 @@ describe("NewBadge", () => {
const { container } = render();
- expect(container.firstChild).toBeNull();
+ expect(container).toBeEmptyDOMElement();
});
it("should render badge with dot when dot prop is true", () => {
diff --git a/ui/litellm-dashboard/src/components/common_components/chartUtils.test.tsx b/ui/litellm-dashboard/src/components/common_components/chartUtils.test.tsx
index 01a4d8373c4..bae11ff5671 100644
--- a/ui/litellm-dashboard/src/components/common_components/chartUtils.test.tsx
+++ b/ui/litellm-dashboard/src/components/common_components/chartUtils.test.tsx
@@ -46,7 +46,7 @@ describe("CustomTooltip", () => {
label: "2024-01-15",
};
const { container } = render();
- expect(container.firstChild).toBeNull();
+ expect(container).toBeEmptyDOMElement();
});
it("should return null when payload is empty", () => {
@@ -56,7 +56,7 @@ describe("CustomTooltip", () => {
label: "2024-01-15",
};
const { container } = render();
- expect(container.firstChild).toBeNull();
+ expect(container).toBeEmptyDOMElement();
});
it("should display formatted category names", () => {
diff --git a/ui/litellm-dashboard/src/components/common_components/routerSettingsWiring.test.tsx b/ui/litellm-dashboard/src/components/common_components/routerSettingsWiring.test.tsx
index 15c52e71e8f..6bfda813eaa 100644
--- a/ui/litellm-dashboard/src/components/common_components/routerSettingsWiring.test.tsx
+++ b/ui/litellm-dashboard/src/components/common_components/routerSettingsWiring.test.tsx
@@ -58,8 +58,8 @@ describe("key router settings wiring, /key/info payload through to rendered outp
it("should not leak a field the accordion has no control for into the editor", async () => {
render(renderAccordion(KEY_INFO_ROUTER_SETTINGS));
- await waitFor(() => expect(screen.getByTestId("loadbalancing")).toBeInTheDocument());
- expect(screen.getByTestId("loadbalancing").textContent).not.toContain("tag_routing_prefix");
+ expect(await screen.findByTestId("loadbalancing")).toBeInTheDocument();
+ expect(screen.getByTestId("loadbalancing")).not.toHaveTextContent(/tag_routing_prefix/);
});
it("should render an empty editor for a key holding only fields it cannot show", async () => {
diff --git a/ui/litellm-dashboard/src/components/edit_auto_router/edit_auto_router_modal.test.tsx b/ui/litellm-dashboard/src/components/edit_auto_router/edit_auto_router_modal.test.tsx
index f8a6f671de0..cd37e05c13b 100644
--- a/ui/litellm-dashboard/src/components/edit_auto_router/edit_auto_router_modal.test.tsx
+++ b/ui/litellm-dashboard/src/components/edit_auto_router/edit_auto_router_modal.test.tsx
@@ -519,6 +519,7 @@ describe("EditAutoRouterModal custom classifier prompt and fallback", () => {
await user.click(await screen.findByText("Advanced: Classification Method"));
expect(await screen.findByRole("button", { name: "Edit custom prompt" })).toBeInTheDocument();
+ // eslint-disable-next-line jest-dom/prefer-checked -- antd sets the checked attribute without the DOM property, so toBeChecked reads false
expect(screen.getByRole("radio", { name: /Route to the default model/ })).toHaveAttribute("checked");
await user.click(screen.getByRole("button", { name: /save changes/i }));
diff --git a/ui/litellm-dashboard/src/components/email_settings.test.tsx b/ui/litellm-dashboard/src/components/email_settings.test.tsx
index 198577e405e..691e0f251f2 100644
--- a/ui/litellm-dashboard/src/components/email_settings.test.tsx
+++ b/ui/litellm-dashboard/src/components/email_settings.test.tsx
@@ -101,13 +101,13 @@ describe("EmailSettings", () => {
renderWithProviders();
expect(inputNamed("EMAIL_LOGO_URL")).toBeDisabled();
- expect(inputNamed("SMTP_HOST")).not.toBeDisabled();
+ expect(inputNamed("SMTP_HOST")).toBeEnabled();
});
it("leaves the premium-only fields editable for premium users", () => {
renderWithProviders();
- expect(inputNamed("EMAIL_LOGO_URL")).not.toBeDisabled();
+ expect(inputNamed("EMAIL_LOGO_URL")).toBeEnabled();
});
it("triggers a live email health check", async () => {
diff --git a/ui/litellm-dashboard/src/components/key_team_helpers/BudgetFallbacksEditor.test.tsx b/ui/litellm-dashboard/src/components/key_team_helpers/BudgetFallbacksEditor.test.tsx
index 1b5603045e0..6b21421184f 100644
--- a/ui/litellm-dashboard/src/components/key_team_helpers/BudgetFallbacksEditor.test.tsx
+++ b/ui/litellm-dashboard/src/components/key_team_helpers/BudgetFallbacksEditor.test.tsx
@@ -9,8 +9,8 @@ describe("BudgetFallbacksEditor", () => {
it("renders empty state with add button", () => {
const onChange = vi.fn();
render();
- expect(screen.getByText("Add Budget Fallback")).toBeTruthy();
- expect(screen.getByText(/reroute to fallback models/)).toBeTruthy();
+ expect(screen.getByText("Add Budget Fallback")).toBeInTheDocument();
+ expect(screen.getByText(/reroute to fallback models/)).toBeInTheDocument();
});
it("renders existing entries from value prop", () => {
@@ -22,9 +22,9 @@ describe("BudgetFallbacksEditor", () => {
availableModels={MODELS}
/>,
);
- expect(screen.getByText("IF BUDGET EXCEEDED, TRY")).toBeTruthy();
- expect(screen.getByText("Primary Model")).toBeTruthy();
- expect(screen.getByText("Fallback Models")).toBeTruthy();
+ expect(screen.getByText("IF BUDGET EXCEEDED, TRY")).toBeInTheDocument();
+ expect(screen.getByText("Primary Model")).toBeInTheDocument();
+ expect(screen.getByText("Fallback Models")).toBeInTheDocument();
});
it("adds a new empty entry when clicking add button", async () => {
@@ -33,7 +33,7 @@ describe("BudgetFallbacksEditor", () => {
render();
await user.click(screen.getByText("Add Budget Fallback"));
- expect(screen.getByText("Primary Model")).toBeTruthy();
+ expect(screen.getByText("Primary Model")).toBeInTheDocument();
expect(onChange).toHaveBeenCalledWith({});
});
@@ -81,8 +81,8 @@ describe("BudgetFallbacksEditor", () => {
expect(screen.getAllByText("Primary Model").length).toBe(1);
rerender();
- expect(screen.queryByText("Primary Model")).toBeNull();
- expect(screen.getByText("Add Budget Fallback")).toBeTruthy();
+ expect(screen.queryByText("Primary Model")).not.toBeInTheDocument();
+ expect(screen.getByText("Add Budget Fallback")).toBeInTheDocument();
});
it("shows ordering hint when multiple fallback models are configured", () => {
@@ -94,6 +94,6 @@ describe("BudgetFallbacksEditor", () => {
availableModels={MODELS}
/>,
);
- expect(screen.getByText(/first model still within its own budget/)).toBeTruthy();
+ expect(screen.getByText(/first model still within its own budget/)).toBeInTheDocument();
});
});
diff --git a/ui/litellm-dashboard/src/components/leftnav.test.tsx b/ui/litellm-dashboard/src/components/leftnav.test.tsx
index 8eca990261c..61b6bf8e515 100644
--- a/ui/litellm-dashboard/src/components/leftnav.test.tsx
+++ b/ui/litellm-dashboard/src/components/leftnav.test.tsx
@@ -456,8 +456,8 @@ describe("Sidebar (leftnav)", () => {
const costOptimization = container.querySelector('a[href*="cost-optimization"]');
expect(costOptimization).not.toBeNull();
- expect(costOptimization!.textContent).toContain("Cost Optimization");
- expect(costOptimization!.textContent).toContain("Beta");
+ expect(costOptimization!).toHaveTextContent(/Cost Optimization/);
+ expect(costOptimization!).toHaveTextContent(/Beta/);
expect(container.querySelector('a[href*="projects"]')).toBeNull();
});
diff --git a/ui/litellm-dashboard/src/components/logging_settings_view.test.tsx b/ui/litellm-dashboard/src/components/logging_settings_view.test.tsx
index b0a1b54bac7..b21ba396411 100644
--- a/ui/litellm-dashboard/src/components/logging_settings_view.test.tsx
+++ b/ui/litellm-dashboard/src/components/logging_settings_view.test.tsx
@@ -34,7 +34,7 @@ describe("LoggingSettingsView logos", () => {
it("renders a letter avatar for the custom callback API, which has no bundled logo", () => {
render();
- expect(screen.queryByAltText("Custom Callback API logo")).toBeNull();
+ expect(screen.queryByAltText("Custom Callback API logo")).not.toBeInTheDocument();
expect(screen.getByText("C")).toBeInTheDocument();
});
});
diff --git a/ui/litellm-dashboard/src/components/model_add/CredentialModal.test.tsx b/ui/litellm-dashboard/src/components/model_add/CredentialModal.test.tsx
index 6804d0cba92..c8140765479 100644
--- a/ui/litellm-dashboard/src/components/model_add/CredentialModal.test.tsx
+++ b/ui/litellm-dashboard/src/components/model_add/CredentialModal.test.tsx
@@ -97,7 +97,7 @@ describe("CredentialModal", () => {
expect(screen.getByText("Add Credential")).toBeInTheDocument();
const nameInput = screen.getByLabelText("Credential Name:") as HTMLInputElement;
expect(nameInput.value).toBe("");
- expect(nameInput.disabled).toBe(false);
+ expect(nameInput).toBeEnabled();
});
it("shows provider-specific fields for the selected provider", async () => {
@@ -124,7 +124,7 @@ describe("CredentialModal", () => {
await waitFor(() => {
const nameInput = screen.getByLabelText("Credential Name:") as HTMLInputElement;
expect(nameInput.value).toBe("test-credential");
- expect(nameInput.disabled).toBe(true);
+ expect(nameInput).toBeDisabled();
});
});
@@ -134,7 +134,7 @@ describe("CredentialModal", () => {
existingCredential: { ...mockCredential, credential_name: "" },
});
- expect((screen.getByLabelText("Credential Name:") as HTMLInputElement).disabled).toBe(true);
+ expect(screen.getByLabelText("Credential Name:")).toBeDisabled();
});
});
});
diff --git a/ui/litellm-dashboard/src/components/model_dashboard/HealthCheckComponent.test.tsx b/ui/litellm-dashboard/src/components/model_dashboard/HealthCheckComponent.test.tsx
index 011d0568afd..1b0194b6478 100644
--- a/ui/litellm-dashboard/src/components/model_dashboard/HealthCheckComponent.test.tsx
+++ b/ui/litellm-dashboard/src/components/model_dashboard/HealthCheckComponent.test.tsx
@@ -179,7 +179,7 @@ describe("HealthCheckComponent", () => {
await user.click(screen.getByTestId("datatable-select-row-id-alpha"));
await user.click(screen.getByTestId("clear-health-selection"));
- expect(screen.getByTestId("datatable-select-row-id-alpha")).toHaveAttribute("aria-checked", "false");
+ expect(screen.getByTestId("datatable-select-row-id-alpha")).not.toBeChecked();
expect(screen.getByTestId("run-health-checks")).toHaveTextContent("Run All Checks");
});
@@ -195,7 +195,7 @@ describe("HealthCheckComponent", () => {
await user.click(screen.getByTestId("pagination-next"));
expect(screen.queryByTestId("clear-health-selection")).not.toBeInTheDocument();
- expect(screen.getByTestId("datatable-select-row-id-alpha")).toHaveAttribute("aria-checked", "false");
+ expect(screen.getByTestId("datatable-select-row-id-alpha")).not.toBeChecked();
});
});
diff --git a/ui/litellm-dashboard/src/components/model_info_view.test.tsx b/ui/litellm-dashboard/src/components/model_info_view.test.tsx
index 46bd80a0bc5..4c8b9153077 100644
--- a/ui/litellm-dashboard/src/components/model_info_view.test.tsx
+++ b/ui/litellm-dashboard/src/components/model_info_view.test.tsx
@@ -955,8 +955,8 @@ describe("ModelInfoView", () => {
await waitFor(() => {
expect(mockTestModelGroupConnection).toHaveBeenCalledWith("test-token", "gpt-4o-mini", "chat");
- expect(mockTestModelGroupConnection).toHaveBeenCalledWith("test-token", "gpt-4o", "chat");
});
+ expect(mockTestModelGroupConnection).toHaveBeenCalledWith("test-token", "gpt-4o", "chat");
expect(mockTestConnectionRequest).not.toHaveBeenCalled();
});
@@ -988,8 +988,8 @@ describe("ModelInfoView", () => {
await waitFor(() => {
expect(mockTestModelGroupConnection).toHaveBeenCalledWith("test-token", "gpt-4o-mini", "chat");
- expect(mockTestModelGroupConnection).toHaveBeenCalledWith("test-token", "gpt-4o", "chat");
});
+ expect(mockTestModelGroupConnection).toHaveBeenCalledWith("test-token", "gpt-4o", "chat");
});
it("does not duplicate the default model as a test target when it is already covered by a configured tier", async () => {
@@ -1128,7 +1128,7 @@ describe("ModelInfoView", () => {
render(, { wrapper });
const logo = await screen.findByAltText("openai logo");
- expect(logo.getAttribute("src")).toContain("openai_small");
+ expect(logo).toHaveAttribute("src", expect.stringContaining("openai_small"));
});
it("renders a letter avatar instead of an img for an unknown provider slug", async () => {
diff --git a/ui/litellm-dashboard/src/components/molecules/cost_optimization_feedback_banner.test.tsx b/ui/litellm-dashboard/src/components/molecules/cost_optimization_feedback_banner.test.tsx
index 328c1441fbc..bad92555bd5 100644
--- a/ui/litellm-dashboard/src/components/molecules/cost_optimization_feedback_banner.test.tsx
+++ b/ui/litellm-dashboard/src/components/molecules/cost_optimization_feedback_banner.test.tsx
@@ -16,8 +16,8 @@ describe("CostOptimizationFeedbackBanner", () => {
});
it("hides itself and persists the dismissal when the dismiss button is clicked", () => {
- const { queryByText, getByLabelText } = render();
- expect(queryByText("Help shape cost optimization")).toBeInTheDocument();
+ const { getByText, queryByText, getByLabelText } = render();
+ expect(getByText("Help shape cost optimization")).toBeInTheDocument();
fireEvent.click(getByLabelText("Dismiss banner"));
diff --git a/ui/litellm-dashboard/src/components/molecules/logo/Logo.test.tsx b/ui/litellm-dashboard/src/components/molecules/logo/Logo.test.tsx
index c0b52e03a30..5e4da208f4e 100644
--- a/ui/litellm-dashboard/src/components/molecules/logo/Logo.test.tsx
+++ b/ui/litellm-dashboard/src/components/molecules/logo/Logo.test.tsx
@@ -10,8 +10,8 @@ describe("Logo", () => {
it("renders the bundled logo untouched by the server root path for a known provider", () => {
render();
const img = screen.getByRole("img", { name: "openai logo" });
- expect(img.getAttribute("src")).toBe(providerLogoMap[Providers.OpenAI]);
- expect(img.getAttribute("src")).toContain("openai_small");
+ expect(img).toHaveAttribute("src", providerLogoMap[Providers.OpenAI]);
+ expect(img).toHaveAttribute("src", expect.stringContaining("openai_small"));
});
it("renders a letter avatar and no img for an unknown provider", () => {
@@ -29,12 +29,12 @@ describe("Logo", () => {
it("resolves a backend asset path through the server root path in src mode", () => {
render();
const img = screen.getByRole("img", { name: "GitHub logo" });
- expect(img.getAttribute("src")).toBe("/litellm/ui/assets/logos/github.svg");
+ expect(img).toHaveAttribute("src", "/litellm/ui/assets/logos/github.svg");
});
it("passes an external https URL through untouched in src mode", () => {
render();
- expect(screen.getByRole("img").getAttribute("src")).toBe("https://cdn.example.com/logo.png");
+ expect(screen.getByRole("img")).toHaveAttribute("src", "https://cdn.example.com/logo.png");
});
it("swaps to the letter avatar and warns with the failing URL on image error", () => {
@@ -63,7 +63,7 @@ describe("Logo", () => {
rerender();
const img = screen.getByRole("img", { name: "Agent logo" });
- expect(img.getAttribute("src")).toBe("/litellm/ui/assets/logos/github.svg");
+ expect(img).toHaveAttribute("src", "/litellm/ui/assets/logos/github.svg");
rerender();
expect(screen.queryByRole("img")).not.toBeInTheDocument();
diff --git a/ui/litellm-dashboard/src/components/navbar.test.tsx b/ui/litellm-dashboard/src/components/navbar.test.tsx
index 72c15990f20..e3d0e4f0b38 100644
--- a/ui/litellm-dashboard/src/components/navbar.test.tsx
+++ b/ui/litellm-dashboard/src/components/navbar.test.tsx
@@ -96,7 +96,7 @@ vi.mock("./Navbar/CommunityEngagementButtons/CommunityEngagementButtons", () =>
let mockUseThemeImpl = () => ({ logoUrl: null as string | null });
let mockUseHealthReadinessDetailsImpl = () => ({ data: null as any });
let mockGetLocalStorageItemImpl = (key: string) => null as string | null;
-let mockUseAuthorizedImpl = () => ({
+const mockUseAuthorizedImpl = () => ({
userId: "test-user",
userEmail: "test@example.com",
userRole: "Admin",
diff --git a/ui/litellm-dashboard/src/components/organisms/create_key_button.test.tsx b/ui/litellm-dashboard/src/components/organisms/create_key_button.test.tsx
index 8609bb1f82a..4f3cd4455a1 100644
--- a/ui/litellm-dashboard/src/components/organisms/create_key_button.test.tsx
+++ b/ui/litellm-dashboard/src/components/organisms/create_key_button.test.tsx
@@ -611,7 +611,7 @@ describe("CreateKey", () => {
});
await waitFor(() => {
- expect(screen.getByTestId("org-dropdown")).not.toBeDisabled();
+ expect(screen.getByTestId("org-dropdown")).toBeEnabled();
});
});
diff --git a/ui/litellm-dashboard/src/components/organization/organization_view.test.tsx b/ui/litellm-dashboard/src/components/organization/organization_view.test.tsx
index ec7baecad2d..4d96fc84ca9 100644
--- a/ui/litellm-dashboard/src/components/organization/organization_view.test.tsx
+++ b/ui/litellm-dashboard/src/components/organization/organization_view.test.tsx
@@ -124,9 +124,8 @@ test("renders organization view after loading data", async () => {
/>,
);
- await waitFor(() => {
- expect(findAllByText("Acme Corp")).toBeTruthy();
- });
+ const [orgName] = await findAllByText("Acme Corp");
+ expect(orgName).toBeInTheDocument();
});
test("should display empty state when organization has no members", async () => {
diff --git a/ui/litellm-dashboard/src/components/per_user_usage.test.tsx b/ui/litellm-dashboard/src/components/per_user_usage.test.tsx
index 443ae66af8f..9cd199d786c 100644
--- a/ui/litellm-dashboard/src/components/per_user_usage.test.tsx
+++ b/ui/litellm-dashboard/src/components/per_user_usage.test.tsx
@@ -117,8 +117,8 @@ describe("PerUserUsage", () => {
const xPositions = new Set(rectangles.map((rect) => rect.getAttribute("d")?.match(/^M\s*([\d.]+)/)?.[1]));
expect(xPositions.size).toBe(3);
- expect(chart.textContent).toContain("curl/8.0");
- expect(chart.textContent).toContain("Unknown");
+ expect(chart).toHaveTextContent("curl/8.0");
+ expect(chart).toHaveTextContent("Unknown");
for (const bucket of [
"1-9 requests",
"10-99 requests",
@@ -127,7 +127,7 @@ describe("PerUserUsage", () => {
"10K-99.9K requests",
"100K+ requests",
]) {
- expect(chart.textContent).toContain(bucket);
+ expect(chart).toHaveTextContent(bucket);
}
const tickTexts = Array.from(chart.querySelectorAll(".recharts-cartesian-axis-tick-value")).map(
diff --git a/ui/litellm-dashboard/src/components/settings.test.tsx b/ui/litellm-dashboard/src/components/settings.test.tsx
index 62efa1dc372..dd45521ab4f 100644
--- a/ui/litellm-dashboard/src/components/settings.test.tsx
+++ b/ui/litellm-dashboard/src/components/settings.test.tsx
@@ -345,7 +345,7 @@ describe("CallbackSelector logos", () => {
expect(await screen.findByAltText("Langfuse logo")).toHaveAttribute("src", "/ui/assets/logos/langfuse.png");
expect(screen.getByAltText("Hosted logo")).toHaveAttribute("src", "https://logos.example.com/hosted.png");
- expect(screen.queryByAltText("NoLogo logo")).toBeNull();
+ expect(screen.queryByAltText("NoLogo logo")).not.toBeInTheDocument();
expect(screen.getByText("N")).toBeInTheDocument();
});
});
diff --git a/ui/litellm-dashboard/src/components/shared/DataTable/DataTable.test.tsx b/ui/litellm-dashboard/src/components/shared/DataTable/DataTable.test.tsx
index 3afdd2849ae..58a0cd94997 100644
--- a/ui/litellm-dashboard/src/components/shared/DataTable/DataTable.test.tsx
+++ b/ui/litellm-dashboard/src/components/shared/DataTable/DataTable.test.tsx
@@ -343,7 +343,7 @@ describe("DataTable loading", () => {
it("renders skeleton rows while loading and real rows once loaded", () => {
const { rerender } = render();
expect(screen.getAllByTestId("skeleton-row").length).toBeGreaterThan(0);
- expect(screen.queryByTestId("name-cell")).toBeNull();
+ expect(screen.queryByTestId("name-cell")).not.toBeInTheDocument();
rerender();
expect(screen.queryAllByTestId("skeleton-row")).toHaveLength(0);
@@ -462,7 +462,7 @@ describe("DataTable column visibility", () => {
await user.click(screen.getByTestId("view-options-trigger"));
expect(await screen.findByTestId("view-option-email")).toBeInTheDocument();
- expect(screen.queryByTestId("view-option-name")).toBeNull();
+ expect(screen.queryByTestId("view-option-name")).not.toBeInTheDocument();
});
});
@@ -615,7 +615,7 @@ describe("DataTable layout", () => {
const { container } = render();
expect(container.querySelector("thead")?.className).toContain("sticky");
const scroller = container.querySelector('[data-slot="table-container"]')?.parentElement as HTMLElement;
- expect(scroller.style.maxHeight).toBe("240px");
+ expect(scroller).toHaveStyle({ maxHeight: "240px" });
});
it("caps fillHeight at the parent's height instead of stretching to it, so a short table stays short", () => {
@@ -634,7 +634,7 @@ describe("DataTable layout", () => {
expect(frame.className).toContain("flex-col");
expect(scroller.className).toContain("min-h-0");
expect(scroller.className).toContain("overflow-auto");
- expect(scroller.style.maxHeight).toBe("");
+ expect(scroller).toHaveStyle({ maxHeight: "" });
// Without this the Table primitive's own overflow container captures the sticky header.
expect(scroller.className).toContain("[&_[data-slot=table-container]]:overflow-visible");
@@ -650,7 +650,7 @@ describe("DataTable layout", () => {
expect(scroller.className).toContain("overflow-x-auto");
expect(scroller.className).not.toContain("min-h-0");
- expect(scroller.style.maxHeight).toBe("");
+ expect(scroller).toHaveStyle({ maxHeight: "" });
expect((scroller.parentElement as HTMLElement).className).not.toContain("flex-col");
expect(container.querySelector("thead")?.className).not.toContain("sticky");
expect(container.querySelector("thead")?.className).not.toContain("bg-background");
diff --git a/ui/litellm-dashboard/src/components/shared/DataTable/DataTableFilterDrawer.test.tsx b/ui/litellm-dashboard/src/components/shared/DataTable/DataTableFilterDrawer.test.tsx
index 0770c17cba6..c6a8049de55 100644
--- a/ui/litellm-dashboard/src/components/shared/DataTable/DataTableFilterDrawer.test.tsx
+++ b/ui/litellm-dashboard/src/components/shared/DataTable/DataTableFilterDrawer.test.tsx
@@ -68,7 +68,7 @@ describe("DataTableFilterDrawer", () => {
await user.type(await screen.findByTestId("draft-name"), "Bob");
expect(names()).toEqual(["Alice", "Bob", "Carol"]);
- expect(screen.queryByTestId("filter-chip-name")).toBeNull();
+ expect(screen.queryByTestId("filter-chip-name")).not.toBeInTheDocument();
await user.click(screen.getByTestId("filter-drawer-apply"));
expect(names()).toEqual(["Bob"]);
@@ -92,7 +92,7 @@ describe("DataTableFilterDrawer", () => {
await user.click(await screen.findByTestId("filter-drawer-reset"));
expect(names()).toEqual(["Alice", "Bob", "Carol"]);
- expect(screen.queryByTestId("filter-chip-name")).toBeNull();
+ expect(screen.queryByTestId("filter-chip-name")).not.toBeInTheDocument();
expect(screen.getByTestId("draft-name")).toHaveValue("");
});
});
diff --git a/ui/litellm-dashboard/src/components/shared/DataTable/DataTableSortHeader.test.tsx b/ui/litellm-dashboard/src/components/shared/DataTable/DataTableSortHeader.test.tsx
index a6164307a78..70403ba2efe 100644
--- a/ui/litellm-dashboard/src/components/shared/DataTable/DataTableSortHeader.test.tsx
+++ b/ui/litellm-dashboard/src/components/shared/DataTable/DataTableSortHeader.test.tsx
@@ -64,7 +64,7 @@ function SortHeaderHarness({ variant, canSort = true, onSortingChange }: Harness
describe("DataTableSortHeader", () => {
it("renders a plain label and no button when the column cannot sort", () => {
render();
- expect(screen.queryByTestId("sort-header-name")).toBeNull();
+ expect(screen.queryByTestId("sort-header-name")).not.toBeInTheDocument();
expect(screen.getByText("Name")).toBeInTheDocument();
});
diff --git a/ui/litellm-dashboard/src/components/shared/DataTable/DataTableToolbar.test.tsx b/ui/litellm-dashboard/src/components/shared/DataTable/DataTableToolbar.test.tsx
index 8571b13e4d8..c6181cb90dc 100644
--- a/ui/litellm-dashboard/src/components/shared/DataTable/DataTableToolbar.test.tsx
+++ b/ui/litellm-dashboard/src/components/shared/DataTable/DataTableToolbar.test.tsx
@@ -66,7 +66,7 @@ describe("DataTableToolbar", () => {
const user = userEvent.setup();
render();
await user.click(screen.getByTestId("filter-chip-remove-name"));
- expect(screen.queryByTestId("filter-chip-name")).toBeNull();
+ expect(screen.queryByTestId("filter-chip-name")).not.toBeInTheDocument();
expect(names()).toEqual(["Alice", "Bob"]);
});
@@ -74,7 +74,7 @@ describe("DataTableToolbar", () => {
const user = userEvent.setup();
render();
await user.click(screen.getByTestId("datatable-clear-filters"));
- expect(screen.queryByTestId("filter-chip-name")).toBeNull();
+ expect(screen.queryByTestId("filter-chip-name")).not.toBeInTheDocument();
expect(names()).toEqual(["Alice", "Bob"]);
});
diff --git a/ui/litellm-dashboard/src/components/shared/charts/area_chart.test.tsx b/ui/litellm-dashboard/src/components/shared/charts/area_chart.test.tsx
index f3ef72392b0..6e4ab14be33 100644
--- a/ui/litellm-dashboard/src/components/shared/charts/area_chart.test.tsx
+++ b/ui/litellm-dashboard/src/components/shared/charts/area_chart.test.tsx
@@ -23,7 +23,7 @@ describe("AreaChart", () => {
it("renders the No data placeholder instead of a chart when data is empty", () => {
const { container, getByText } = render();
- expect(getByText("No data")).toBeTruthy();
+ expect(getByText("No data")).toBeInTheDocument();
expect(container.querySelector('[data-slot="chart"]')).toBeNull();
});
@@ -37,7 +37,7 @@ describe("AreaChart", () => {
const areas = Array.from(container.querySelectorAll("path.recharts-area-area"));
expect(areas).toHaveLength(2);
for (const area of areas) {
- expect(area.getAttribute("fill")).toMatch(/^url\(#fill-/);
+ expect(area).toHaveAttribute("fill", expect.stringMatching(/^url\(#fill-/));
}
});
diff --git a/ui/litellm-dashboard/src/components/shared/charts/bar_chart.test.tsx b/ui/litellm-dashboard/src/components/shared/charts/bar_chart.test.tsx
index cb0d5c603a4..a322eeb3ad0 100644
--- a/ui/litellm-dashboard/src/components/shared/charts/bar_chart.test.tsx
+++ b/ui/litellm-dashboard/src/components/shared/charts/bar_chart.test.tsx
@@ -23,7 +23,7 @@ describe("BarChart", () => {
it("renders the No data placeholder instead of a chart when data is empty", () => {
const { container, getByText } = render();
- expect(getByText("No data")).toBeTruthy();
+ expect(getByText("No data")).toBeInTheDocument();
expect(container.querySelector('[data-slot="chart"]')).toBeNull();
});
diff --git a/ui/litellm-dashboard/src/components/shared/charts/chart_tooltip.test.tsx b/ui/litellm-dashboard/src/components/shared/charts/chart_tooltip.test.tsx
index 7afc7532760..bb0fa985c42 100644
--- a/ui/litellm-dashboard/src/components/shared/charts/chart_tooltip.test.tsx
+++ b/ui/litellm-dashboard/src/components/shared/charts/chart_tooltip.test.tsx
@@ -29,10 +29,10 @@ describe("CustomTooltip", () => {
const inactive = render(
,
);
- expect(inactive.container.firstChild).toBeNull();
+ expect(inactive.container).toBeEmptyDOMElement();
const empty = render();
- expect(empty.container.firstChild).toBeNull();
+ expect(empty.container).toBeEmptyDOMElement();
});
it("renders the label and title-cased category names without the metrics prefix", () => {
@@ -82,7 +82,7 @@ describe("ValueTooltip", () => {
it("returns null when not active", () => {
const { container } = render();
- expect(container.firstChild).toBeNull();
+ expect(container).toBeEmptyDOMElement();
});
it("renders label, series name, and locale-formatted value by default", () => {
diff --git a/ui/litellm-dashboard/src/components/shared/form/FormField.test.tsx b/ui/litellm-dashboard/src/components/shared/form/FormField.test.tsx
index af9122e2bd5..3b37638b0bc 100644
--- a/ui/litellm-dashboard/src/components/shared/form/FormField.test.tsx
+++ b/ui/litellm-dashboard/src/components/shared/form/FormField.test.tsx
@@ -101,7 +101,7 @@ describe("FormField", () => {
const control = await screen.findByLabelText("Team Name");
await waitFor(() => expect(control).toHaveAttribute("aria-invalid", "true"));
- expect(control.getAttribute("aria-describedby")).toBe(screen.getByRole("alert").id);
+ expect(control).toHaveAttribute("aria-describedby", screen.getByRole("alert").id);
});
it("leaves a valid control free of aria-invalid", () => {
diff --git a/ui/litellm-dashboard/src/components/shared/table_cells/id_cell.test.tsx b/ui/litellm-dashboard/src/components/shared/table_cells/id_cell.test.tsx
index 1a87f17d50b..e02cbdf941c 100644
--- a/ui/litellm-dashboard/src/components/shared/table_cells/id_cell.test.tsx
+++ b/ui/litellm-dashboard/src/components/shared/table_cells/id_cell.test.tsx
@@ -26,22 +26,22 @@ describe("IdCell", () => {
render();
const el = screen.getByText("sk-1234567890abcdef");
expect(el.tagName).toBe("SPAN");
- expect(el.className).toContain("bg-blue-50");
- expect(el.className).toContain("font-mono");
- expect(el.className).toContain("max-w-[15ch]");
- expect(el.className).toContain("truncate");
+ expect(el).toHaveClass("bg-blue-50");
+ expect(el).toHaveClass("font-mono");
+ expect(el).toHaveClass("max-w-[15ch]");
+ expect(el).toHaveClass("truncate");
});
it("renders plain mono text without pill styling for the plain variant", () => {
render();
const el = screen.getByText("req-123");
- expect(el.className).toContain("font-mono");
- expect(el.className).not.toContain("bg-blue-50");
+ expect(el).toHaveClass("font-mono");
+ expect(el).not.toHaveClass("bg-blue-50");
});
it("does not truncate when truncate is false", () => {
render();
- expect(screen.getByText("audit-object-id").className).not.toContain("truncate");
+ expect(screen.getByText("audit-object-id")).not.toHaveClass("truncate");
});
it("becomes a button that fires onClick with the id value", async () => {
diff --git a/ui/litellm-dashboard/src/components/shared/table_cells/identity_cell.test.tsx b/ui/litellm-dashboard/src/components/shared/table_cells/identity_cell.test.tsx
index 9a91e163baf..1122eede522 100644
--- a/ui/litellm-dashboard/src/components/shared/table_cells/identity_cell.test.tsx
+++ b/ui/litellm-dashboard/src/components/shared/table_cells/identity_cell.test.tsx
@@ -36,8 +36,8 @@ describe("IdentityCell", () => {
const button = screen.getByRole("button");
expect(button.querySelector(".lucide-chevron-right")).not.toBeNull();
// The clickable area must read as clickable: a hover background and a pointer cursor.
- expect(button.className).toContain("hover:bg-muted");
- expect(button.className).toContain("cursor-pointer");
+ expect(button).toHaveClass("hover:bg-muted");
+ expect(button).toHaveClass("cursor-pointer");
await user.click(button);
expect(onClick).toHaveBeenCalledTimes(1);
});
@@ -48,7 +48,7 @@ describe("IdentityCell", () => {
const link = screen.getByRole("link", { name: /routing-qa-key-alpha/ });
expect(link).toHaveAttribute("href", "/api-keys?key=abc123");
expect(link.querySelector(".lucide-chevron-right")).not.toBeNull();
- expect(link.className).toContain("hover:bg-muted");
+ expect(link).toHaveClass("hover:bg-muted");
await user.click(link);
expect(routerPush).toHaveBeenCalledWith("/api-keys?key=abc123");
});
diff --git a/ui/litellm-dashboard/src/components/team/LoggingSettings.test.tsx b/ui/litellm-dashboard/src/components/team/LoggingSettings.test.tsx
index f998d7d3ecf..83c541afd15 100644
--- a/ui/litellm-dashboard/src/components/team/LoggingSettings.test.tsx
+++ b/ui/litellm-dashboard/src/components/team/LoggingSettings.test.tsx
@@ -135,7 +135,7 @@ describe("LoggingSettings", () => {
renderWithProviders();
expect(screen.getByText("Custom Callback API Configuration")).toBeInTheDocument();
- expect(screen.queryByAltText("Custom Callback API logo")).toBeNull();
+ expect(screen.queryByAltText("Custom Callback API logo")).not.toBeInTheDocument();
expect(screen.getByText("C")).toBeInTheDocument();
});
diff --git a/ui/litellm-dashboard/src/components/team/TeamInfo.test.tsx b/ui/litellm-dashboard/src/components/team/TeamInfo.test.tsx
index 22481eaa4b2..1d6c46dc0c9 100644
--- a/ui/litellm-dashboard/src/components/team/TeamInfo.test.tsx
+++ b/ui/litellm-dashboard/src/components/team/TeamInfo.test.tsx
@@ -816,7 +816,7 @@ describe("TeamInfoView", () => {
const secretField = await screen.findByPlaceholderText(
'{"namespace": "admin", "mount": "secret", "path_prefix": "litellm"}',
);
- expect(secretField).not.toBeDisabled();
+ expect(secretField).toBeEnabled();
});
it("should add team member when form is submitted", async () => {
diff --git a/ui/litellm-dashboard/src/components/team/TeamVirtualKeysTable.test.tsx b/ui/litellm-dashboard/src/components/team/TeamVirtualKeysTable.test.tsx
index f71b2a05f3f..2cefe33eb8d 100644
--- a/ui/litellm-dashboard/src/components/team/TeamVirtualKeysTable.test.tsx
+++ b/ui/litellm-dashboard/src/components/team/TeamVirtualKeysTable.test.tsx
@@ -212,7 +212,7 @@ describe("TeamVirtualKeysTable", () => {
renderWithProviders();
- await waitFor(() => expect(screen.getByTestId("sort-header-created_at")).toBeInTheDocument());
+ expect(await screen.findByTestId("sort-header-created_at")).toBeInTheDocument();
await user.click(screen.getByTestId("sort-header-created_at"));
await waitFor(() =>
diff --git a/ui/litellm-dashboard/src/components/templates/KeyInfoHeader.test.tsx b/ui/litellm-dashboard/src/components/templates/KeyInfoHeader.test.tsx
index b81495e68e8..cc876758f74 100644
--- a/ui/litellm-dashboard/src/components/templates/KeyInfoHeader.test.tsx
+++ b/ui/litellm-dashboard/src/components/templates/KeyInfoHeader.test.tsx
@@ -161,7 +161,7 @@ describe("KeyInfoHeader", () => {
it("should not disable Regenerate button by default", () => {
render();
- expect(screen.getByRole("button", { name: /regenerate key/i })).not.toBeDisabled();
+ expect(screen.getByRole("button", { name: /regenerate key/i })).toBeEnabled();
});
});
diff --git a/ui/litellm-dashboard/src/components/user_agent_activity.test.tsx b/ui/litellm-dashboard/src/components/user_agent_activity.test.tsx
index 07a03f4addf..79bb63da31a 100644
--- a/ui/litellm-dashboard/src/components/user_agent_activity.test.tsx
+++ b/ui/litellm-dashboard/src/components/user_agent_activity.test.tsx
@@ -206,9 +206,9 @@ describe("UserAgentActivity", () => {
const xPositions = new Set(rectangles.map((rect) => rect.getAttribute("d")?.match(/^M\s*([\d.]+)/)?.[1]));
expect(xPositions.size).toBe(1);
- expect(chart.textContent).toContain("Chrome/1.0");
- expect(chart.textContent).toContain("Firefox/2.0");
- expect(chart.textContent).toContain(firstBucketLabel);
+ expect(chart).toHaveTextContent(/Chrome\/1\.0/);
+ expect(chart).toHaveTextContent(/Firefox\/2\.0/);
+ expect(chart).toHaveTextContent(new RegExp(firstBucketLabel));
const tickTexts = Array.from(chart.querySelectorAll(".recharts-cartesian-axis-tick-value")).map(
(tick) => tick.textContent ?? "",
diff --git a/ui/litellm-dashboard/src/components/vector_store_management/VectorStoreSelector.test.tsx b/ui/litellm-dashboard/src/components/vector_store_management/VectorStoreSelector.test.tsx
index 07468abc582..52c51a8ecc4 100644
--- a/ui/litellm-dashboard/src/components/vector_store_management/VectorStoreSelector.test.tsx
+++ b/ui/litellm-dashboard/src/components/vector_store_management/VectorStoreSelector.test.tsx
@@ -307,21 +307,21 @@ describe("VectorStoreSelector", () => {
renderComponent({ value: ["store-1", "store-2"] });
await waitForDataFetch();
- expect(getSelectElement().getAttribute("data-value")).toBe(JSON.stringify(["store-1", "store-2"]));
+ expect(getSelectElement()).toHaveAttribute("data-value", JSON.stringify(["store-1", "store-2"]));
});
it("should handle empty value array", async () => {
renderComponent({ value: [] });
await waitForDataFetch();
- expect(getSelectElement().getAttribute("data-value")).toBe(JSON.stringify([]));
+ expect(getSelectElement()).toHaveAttribute("data-value", JSON.stringify([]));
});
it("should handle undefined value", async () => {
renderComponent({ value: undefined });
await waitForDataFetch();
- expect(getSelectElement().getAttribute("data-value")).toBeNull();
+ expect(getSelectElement()).not.toHaveAttribute("data-value");
});
});
diff --git a/ui/litellm-dashboard/src/components/view_logs/AuditLogsTable.test.tsx b/ui/litellm-dashboard/src/components/view_logs/AuditLogsTable.test.tsx
index dbb0a39e2ee..8bc771ee298 100644
--- a/ui/litellm-dashboard/src/components/view_logs/AuditLogsTable.test.tsx
+++ b/ui/litellm-dashboard/src/components/view_logs/AuditLogsTable.test.tsx
@@ -95,7 +95,7 @@ describe("AuditLogsTable", () => {
renderTable({ isLoading: true, data: [] });
expect(screen.getAllByTestId("skeleton-row").length).toBeGreaterThan(0);
- expect(screen.queryByText("No audit logs yet")).toBeNull();
+ expect(screen.queryByText("No audit logs yet")).not.toBeInTheDocument();
});
it("uses a distinct empty state for unfiltered vs filtered-empty results", () => {
diff --git a/ui/litellm-dashboard/src/components/view_logs/ConfigInfoMessage.test.tsx b/ui/litellm-dashboard/src/components/view_logs/ConfigInfoMessage.test.tsx
index ad9b724ba80..2e93b10e3ae 100644
--- a/ui/litellm-dashboard/src/components/view_logs/ConfigInfoMessage.test.tsx
+++ b/ui/litellm-dashboard/src/components/view_logs/ConfigInfoMessage.test.tsx
@@ -10,7 +10,7 @@ describe("ConfigInfoMessage", () => {
it("should render nothing when show is false", () => {
const { container } = render();
- expect(container.innerHTML).toBe("");
+ expect(container).toBeEmptyDOMElement();
});
it("should display the YAML config snippet", () => {
diff --git a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/CollapsibleMessage.test.tsx b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/CollapsibleMessage.test.tsx
index 3aa8d21c31c..377615d3cb8 100644
--- a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/CollapsibleMessage.test.tsx
+++ b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/CollapsibleMessage.test.tsx
@@ -7,12 +7,12 @@ import { CollapsibleMessage } from "./CollapsibleMessage";
describe("CollapsibleMessage", () => {
it("should return null when content is empty", () => {
const { container } = render();
- expect(container.innerHTML).toBe("");
+ expect(container).toBeEmptyDOMElement();
});
it("should return null when content is undefined", () => {
const { container } = render();
- expect(container.innerHTML).toBe("");
+ expect(container).toBeEmptyDOMElement();
});
it("should render the label and char count", () => {
diff --git a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/HistoryTree.test.tsx b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/HistoryTree.test.tsx
index 0726a9f4b82..07796de6927 100644
--- a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/HistoryTree.test.tsx
+++ b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/HistoryTree.test.tsx
@@ -8,7 +8,7 @@ import { ParsedMessage } from "./prettyMessagesTypes";
describe("HistoryTree", () => {
it("should return null when messages array is empty", () => {
const { container } = render();
- expect(container.innerHTML).toBe("");
+ expect(container).toBeEmptyDOMElement();
});
it('should render message count with plural "messages" for multiple messages', () => {
diff --git a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/InputCard.test.tsx b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/InputCard.test.tsx
index 5bf97b16233..df9d00a05d6 100644
--- a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/InputCard.test.tsx
+++ b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/InputCard.test.tsx
@@ -42,7 +42,7 @@ describe("InputCard", () => {
it("should return null when messages array is empty", () => {
const { container } = render();
- expect(container.firstChild).toBeNull();
+ expect(container).toBeEmptyDOMElement();
});
it("should display system message when present", () => {
diff --git a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/LogDetailsDrawer.test.tsx b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/LogDetailsDrawer.test.tsx
index b913f7c8d21..b96e5279722 100644
--- a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/LogDetailsDrawer.test.tsx
+++ b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/LogDetailsDrawer.test.tsx
@@ -153,7 +153,7 @@ describe("LogDetailsDrawer session sidebar auto-router icon", () => {
it("marks the auto-routed entry with the router icon and leaves a direct call on the default icon", async () => {
renderRoutedSession();
- await waitFor(() => expect(screen.queryByText("claude-opus-4-8")).not.toBeNull());
+ expect(await screen.findByText("claude-opus-4-8")).toBeInTheDocument();
const routedRow = rowFor("claude-opus-4-8");
const directRow = rowFor("claude-haiku-4-5");
diff --git a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/SimpleMessageBlock.test.tsx b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/SimpleMessageBlock.test.tsx
index c4be05f0e9c..ecd2e0fdf2a 100644
--- a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/SimpleMessageBlock.test.tsx
+++ b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/SimpleMessageBlock.test.tsx
@@ -12,12 +12,12 @@ describe("SimpleMessageBlock", () => {
it("should return null when content is empty and no tool calls", () => {
const { container } = render();
- expect(container.innerHTML).toBe("");
+ expect(container).toBeEmptyDOMElement();
});
it('should return null when content is "null" string and no tool calls', () => {
const { container } = render();
- expect(container.innerHTML).toBe("");
+ expect(container).toBeEmptyDOMElement();
});
it("should render tool calls when present", () => {
diff --git a/ui/litellm-dashboard/src/components/view_logs/RequestLogsPanel.test.tsx b/ui/litellm-dashboard/src/components/view_logs/RequestLogsPanel.test.tsx
index 852f146c786..9e2abec4716 100644
--- a/ui/litellm-dashboard/src/components/view_logs/RequestLogsPanel.test.tsx
+++ b/ui/litellm-dashboard/src/components/view_logs/RequestLogsPanel.test.tsx
@@ -210,15 +210,16 @@ describe("RequestLogsPanel", () => {
await user.click(screen.getByRole("button", { name: /Last 24 Hours/i }));
await user.click(await screen.findByRole("button", { name: "Last 15 Minutes" }));
- await waitFor(() => {
+ const windowSeconds = () => {
const call = lastCall();
if (!call) throw new Error("no call");
- const diff = moment
+ return moment
.utc(call.end_date, "YYYY-MM-DD HH:mm:ss")
.diff(moment.utc(call.start_date, "YYYY-MM-DD HH:mm:ss"), "seconds");
- expect(diff).toBeGreaterThanOrEqual(15 * 60);
- expect(diff).toBeLessThanOrEqual(16 * 60);
- });
+ };
+
+ await waitFor(() => expect(windowSeconds()).toBeGreaterThanOrEqual(15 * 60));
+ expect(windowSeconds()).toBeLessThanOrEqual(16 * 60);
});
it("restores the default 24 hour window when filters are reset", async () => {
@@ -228,7 +229,7 @@ describe("RequestLogsPanel", () => {
await waitFor(() => expect(uiSpendLogsCall).toHaveBeenCalled());
await user.click(screen.getByRole("button", { name: /Last 24 Hours/i }));
await user.click(await screen.findByRole("button", { name: "Last 15 Minutes" }));
- await waitFor(() => expect(screen.getByRole("button", { name: /Last 15 Minutes/i })).toBeInTheDocument());
+ expect(await screen.findByRole("button", { name: /Last 15 Minutes/i })).toBeInTheDocument();
await user.click(screen.getByRole("button", { name: "Reset Filters" }));
@@ -262,8 +263,8 @@ describe("RequestLogsPanel", () => {
expect(historyModes()).toEqual(["push"]);
await waitFor(() => {
expect(drawer()).toHaveTextContent("open");
- expect(drawer()).toHaveAttribute("data-log-id", "req-1");
});
+ expect(drawer()).toHaveAttribute("data-log-id", "req-1");
});
it("opens the drawer on load when ?log_id= matches a log in the loaded page", async () => {
@@ -272,8 +273,8 @@ describe("RequestLogsPanel", () => {
await waitFor(() => {
expect(drawer()).toHaveTextContent("open");
- expect(drawer()).toHaveAttribute("data-log-id", "req-2");
});
+ expect(drawer()).toHaveAttribute("data-log-id", "req-2");
});
it("fetches the log by request_id and opens the drawer when it is not in the loaded page", async () => {
@@ -286,8 +287,8 @@ describe("RequestLogsPanel", () => {
await waitFor(() => {
expect(drawer()).toHaveTextContent("open");
- expect(drawer()).toHaveAttribute("data-log-id", "req-old");
});
+ expect(drawer()).toHaveAttribute("data-log-id", "req-old");
const byIdCall = vi
.mocked(uiSpendLogsCall)
@@ -344,8 +345,8 @@ describe("RequestLogsPanel", () => {
expect(historyModes()).toEqual(["push"]);
await waitFor(() => {
expect(drawer()).toHaveTextContent("open");
- expect(drawer()).toHaveAttribute("data-session-id", "sess-solo");
});
+ expect(drawer()).toHaveAttribute("data-session-id", "sess-solo");
});
it("clicking a log row clears a lingering ?session_id= so the drawer shows the clicked log", async () => {
@@ -366,8 +367,8 @@ describe("RequestLogsPanel", () => {
expect(urlParams().get("session_id")).toBeNull();
await waitFor(() => {
expect(drawer()).toHaveAttribute("data-log-id", "req-b");
- expect(drawer()).toHaveAttribute("data-session-id", "");
});
+ expect(drawer()).toHaveAttribute("data-session-id", "");
});
it("closing a drawer opened via a session id clears both params", async () => {
@@ -394,9 +395,9 @@ describe("RequestLogsPanel", () => {
await waitFor(() => {
expect(drawer()).toHaveTextContent("open");
- expect(drawer()).toHaveAttribute("data-log-id", "req-llm");
- expect(drawer()).toHaveAttribute("data-session-id", "sess-1");
});
+ expect(drawer()).toHaveAttribute("data-session-id", "sess-1");
+ expect(drawer()).toHaveAttribute("data-log-id", "req-llm");
});
it("clicking a multi-call session's row writes ?session_id= alongside ?log_id=", async () => {
@@ -442,7 +443,7 @@ describe("RequestLogsPanel", () => {
await user.click(screen.getByRole("button", { name: "Stop" }));
- expect(screen.queryByText("Auto-refreshing every 15 seconds")).toBeNull();
+ expect(screen.queryByText("Auto-refreshing every 15 seconds")).not.toBeInTheDocument();
});
});
});
diff --git a/ui/litellm-dashboard/src/components/view_logs/RequestLogsTableColumns.test.tsx b/ui/litellm-dashboard/src/components/view_logs/RequestLogsTableColumns.test.tsx
index 2fdc8455ca1..3d0ea03c5d5 100644
--- a/ui/litellm-dashboard/src/components/view_logs/RequestLogsTableColumns.test.tsx
+++ b/ui/litellm-dashboard/src/components/view_logs/RequestLogsTableColumns.test.tsx
@@ -103,7 +103,7 @@ describe("sortable headers", () => {
expect(screen.getByTestId(`sort-trigger-${field}`)).toBeInTheDocument();
}
for (const field of ["request_id", "session_id", "status", "type", "end_user"]) {
- expect(screen.queryByTestId(`sort-trigger-${field}`)).toBeNull();
+ expect(screen.queryByTestId(`sort-trigger-${field}`)).not.toBeInTheDocument();
}
});
});
diff --git a/ui/litellm-dashboard/src/contexts/PluginModeContext.test.tsx b/ui/litellm-dashboard/src/contexts/PluginModeContext.test.tsx
index 96576269fbe..f0af7313a2c 100644
--- a/ui/litellm-dashboard/src/contexts/PluginModeContext.test.tsx
+++ b/ui/litellm-dashboard/src/contexts/PluginModeContext.test.tsx
@@ -39,15 +39,15 @@ describe("PluginModeProvider effectiveMode fallback", () => {
renderWithPlugins([]);
await waitFor(() => expect(getMock).toHaveBeenCalled());
- await waitFor(() => expect(screen.getByTestId("mode").textContent).toBe("ai-gateway"));
- expect(screen.getByTestId("active").textContent).toBe("none");
+ await waitFor(() => expect(screen.getByTestId("mode")).toHaveTextContent("ai-gateway"));
+ expect(screen.getByTestId("active")).toHaveTextContent("none");
});
it("keeps the stored mode when it is still registered", async () => {
renderWithPlugins([{ name: "my-plugin", display_name: "My Plugin", url: "https://p.example.com" }]);
- await waitFor(() => expect(screen.getByTestId("active").textContent).toBe("my-plugin"));
- expect(screen.getByTestId("mode").textContent).toBe("my-plugin");
+ await waitFor(() => expect(screen.getByTestId("active")).toHaveTextContent("my-plugin"));
+ expect(screen.getByTestId("mode")).toHaveTextContent("my-plugin");
});
it("falls back to ai-gateway when the plugins fetch fails, never stranding the user", async () => {
@@ -59,6 +59,6 @@ describe("PluginModeProvider effectiveMode fallback", () => {
);
await waitFor(() => expect(getMock).toHaveBeenCalled());
- await waitFor(() => expect(screen.getByTestId("mode").textContent).toBe("ai-gateway"));
+ await waitFor(() => expect(screen.getByTestId("mode")).toHaveTextContent("ai-gateway"));
});
});
diff --git a/ui/litellm-dashboard/src/utils/dataUtils.test.ts b/ui/litellm-dashboard/src/utils/dataUtils.test.ts
index 14eba8a7edd..f9e2be81163 100644
--- a/ui/litellm-dashboard/src/utils/dataUtils.test.ts
+++ b/ui/litellm-dashboard/src/utils/dataUtils.test.ts
@@ -225,9 +225,11 @@ describe("dataUtils", () => {
await copyToClipboard("test text");
expect(mockTextArea.value).toBe("test text");
+ /* eslint-disable jest-dom/prefer-to-have-style -- the subject is a plain mock object, not a DOM node, so toHaveStyle cannot read it */
expect(mockTextArea.style.position).toBe("fixed");
expect(mockTextArea.style.left).toBe("-999999px");
expect(mockTextArea.style.top).toBe("-999999px");
+ /* eslint-enable jest-dom/prefer-to-have-style */
expect(mockTextArea.setAttribute).toHaveBeenCalledWith("readonly", "");
expect(mockTextArea.focus).toHaveBeenCalled();
expect(mockTextArea.select).toHaveBeenCalled();