test(e2e): browser contract for the otel_internal_spans dropdown

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
yucheng 2026-09-23 22:30:55 +00:00
parent 4cd3d97eb1
commit 5d778f2b01
2 changed files with 80 additions and 0 deletions

View file

@ -1,5 +1,6 @@
[
"tests/e2e/ui/tests/integrationCritical/projectDetachment.spec.ts::project creation and explicit detachment preserve saved scope and restore serving",
"tests/e2e/ui/tests/integrationCritical/otelInternalSpans.spec.ts::team logging settings persist otel_internal_spans exclude through the callback editor",
"tests/e2e/ui/tests/integrationCritical/mcpUserEnvVars.spec.ts::per-user MCP env var stays updatable and clearable from the card after it is set",
"tests/e2e/ui/tests/integrationCritical/mcpUserEnvVars.spec.ts::cancelling the clear confirmation keeps the stored value and sends no delete",
"tests/e2e/ui/tests/integrationCritical/mcpUserEnvVars.spec.ts::pressing Enter on Update opens the credentials modal instead of the server editor",

View file

@ -0,0 +1,79 @@
import { test, expect } from "@playwright/test";
import { randomUUID } from "node:crypto";
import { Page } from "../../fixtures/pages";
import { navigateToPage } from "../../helpers/navigation";
import { captureRequestBody, readBack } from "../../helpers/roundTrip";
test("team logging settings persist otel_internal_spans exclude through the callback editor", async ({
page,
request,
}) => {
const master = process.env.LITELLM_MASTER_KEY ?? "sk-integration-master";
const headers = { Authorization: `Bearer ${master}` };
const prefix = `integration-browser-${randomUUID()}`;
const post = async (url: string, data: object) => {
const response = await request.post(url, { headers, data });
expect(response.ok(), `${url}: ${await response.text()}`).toBe(true);
return response.json();
};
const team = await post("/team/new", { team_alias: prefix });
try {
await page.goto("/ui/login");
await page.getByPlaceholder("Enter your username").fill("admin");
await page.getByPlaceholder("Enter your password").fill(master);
await page.getByRole("button", { name: "Login", exact: true }).click();
await expect(page).toHaveURL(
(url) => url.pathname.startsWith("/ui") && !url.pathname.includes("login"),
);
await navigateToPage(page, Page.Teams);
await page.getByRole("button", { name: new RegExp(`^${prefix}`) }).click();
await page.getByRole("tab", { name: "Settings" }).click();
await page.getByRole("button", { name: "Edit Settings" }).click();
await page
.getByRole("button", { name: "Add Integration", exact: true })
.click();
await page
.getByRole("combobox")
.filter({ hasText: "Select integration" })
.click();
await page
.getByRole("option", { name: /Langfuse OTEL/ })
.click();
const internalSpans = page.getByRole("combobox", {
name: "otel internal spans",
});
await internalSpans.click();
await expect(
page.getByRole("option", { name: "include", exact: true }),
).toBeVisible();
await page
.getByRole("option", { name: "exclude", exact: true })
.click();
const update = await captureRequestBody(
page,
{ method: "POST", urlIncludes: "/team/update" },
async () => {
await page.getByRole("button", { name: "Save Changes" }).click();
},
);
const logging = (update.metadata as { logging: any[] }).logging;
expect(logging).toEqual([
{
callback_name: "langfuse_otel",
callback_type: "success",
callback_vars: { otel_internal_spans: "exclude" },
},
]);
await expect(
page.getByText("Team settings updated successfully"),
).toBeVisible();
const info = await readBack<{
team_info: { metadata: { logging: any[] } };
}>(page, `/team/info?team_id=${team.team_id}`);
expect(
info.team_info.metadata.logging[0].callback_vars.otel_internal_spans,
).toBe("exclude");
} finally {
await post("/team/delete", { team_ids: [team.team_id] });
}
});