test(ui): fix key and credential e2e specs after the overflow menu migrations (#34206)

Delete Key moved into the key info page's overflow dropdown (#34116) and the
credentials table's row actions moved into a shared DataTable overflow menu, so
both specs were clicking a button that no longer exists. Point them at the menu
items instead.

Add a CredentialsPanel unit test asserting the update payload drops the masked
api key and keeps the edited api base, so that guard is not held up solely by an
e2e a table migration can silently disarm.
This commit is contained in:
yuneng-jiang 2026-07-21 18:14:24 -07:00 committed by GitHub
parent 0326722379
commit 5b676b91bd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 35 additions and 7 deletions

View file

@ -38,7 +38,8 @@ test.describe("Edit LLM credential", () => {
const row = page.locator("tr", { hasText: credentialName });
await expect(row).toBeVisible({ timeout: 15_000 });
await row.getByRole("button").first().click();
await row.getByTestId(`credential-actions-${credentialName}`).click();
await page.getByTestId("credential-action-edit").click();
const modal = page.locator(".ant-modal-content").filter({ hasText: "Edit Credential" });
await expect(modal).toBeVisible({ timeout: 10_000 });

View file

@ -103,7 +103,8 @@ test.describe("Proxy Admin - Keys", () => {
await expect(page.getByText("Back to Keys")).toBeVisible({ timeout: 10_000 });
await page.getByRole("button", { name: "Delete Key" }).click();
await page.getByRole("button", { name: "More key actions" }).click();
await page.getByRole("menuitem", { name: "Delete Key" }).click();
const modal = page.locator(".ant-modal:visible");
await expect(modal).toBeVisible({ timeout: 5_000 });

View file

@ -4,7 +4,7 @@ import userEvent from "@testing-library/user-event";
import { UploadProps } from "antd/es/upload";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { CredentialItem, credentialCreateCall } from "@/components/networking";
import { CredentialItem, credentialCreateCall, credentialUpdateCall } from "@/components/networking";
import NotificationsManager from "@/components/molecules/notifications_manager";
import CredentialsPanel from "./CredentialsPanel";
@ -51,11 +51,17 @@ vi.mock("./CredentialModal", () => ({
if (!open) {
return null;
}
const values =
mode === "edit"
? {
credential_name: "openai-key",
custom_llm_provider: "openai",
api_key: "sk-1****2345",
api_base: "https://proxy.e2e.example.com/v1",
}
: { credential_name: "new-cred", custom_llm_provider: "openai" };
return (
<button
data-testid={`credential-modal-${mode}-submit`}
onClick={() => onSubmit({ credential_name: "new-cred", custom_llm_provider: "openai" })}
>
<button data-testid={`credential-modal-${mode}-submit`} onClick={() => onSubmit(values)}>
submit {mode}
</button>
);
@ -179,6 +185,26 @@ describe("CredentialsPanel", () => {
expect(NotificationsManager.success).not.toHaveBeenCalled();
});
it("drops the masked api key from the update payload while keeping the edited api base", async () => {
const user = userEvent.setup();
mockUseAuthorized.mockReturnValue({ accessToken: "test-token", userRole: "Admin" });
mockUseCredentials.mockReturnValue({ data: { credentials }, isLoading: false, refetch: vi.fn() });
vi.mocked(credentialUpdateCall).mockResolvedValueOnce(undefined as never);
renderPanel();
await user.click(screen.getByTestId("credential-actions-openai-key"));
await user.click(await screen.findByTestId("credential-action-edit"));
await user.click(screen.getByTestId("credential-modal-edit-submit"));
await waitFor(() => {
expect(credentialUpdateCall).toHaveBeenCalled();
});
const [, updatedName, payload] = vi.mocked(credentialUpdateCall).mock.calls[0];
expect(updatedName).toBe("openai-key");
expect(payload.credential_values).toEqual({ api_base: "https://proxy.e2e.example.com/v1" });
});
describe("Admin Viewer write-action gating", () => {
// Admin Viewer can VIEW credentials but must not add / edit / delete them.
it("hides the Add Credential button but still lists credentials", () => {