feat(analytics): integrate Langfuse with Keycloak SSO
Some checks failed
CI / Format (pull_request) Has been cancelled
CI / Clippy (pull_request) Has been cancelled
CI / Security Audit (pull_request) Has been cancelled
CI / Tests (pull_request) Has been cancelled
CI / E2E Tests (pull_request) Has been cancelled
CI / Deploy (pull_request) Has been cancelled
CI / Format (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Security Audit (push) Has been cancelled
CI / Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Deploy (push) Has been cancelled
Some checks failed
CI / Format (pull_request) Has been cancelled
CI / Clippy (pull_request) Has been cancelled
CI / Security Audit (pull_request) Has been cancelled
CI / Tests (pull_request) Has been cancelled
CI / E2E Tests (pull_request) Has been cancelled
CI / Deploy (pull_request) Has been cancelled
CI / Format (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Security Audit (push) Has been cancelled
CI / Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Deploy (push) Has been cancelled
Add certifai-langfuse OIDC client to Keycloak realm export and configure the Langfuse Docker service with Keycloak SSO env vars (shared realm, account linking, local auth disabled). Replace the iframe-based analytics page with an informational landing since cross-origin SSO breaks in iframes. Users open Langfuse in a new tab where the active Keycloak session authenticates them transparently. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -123,17 +123,51 @@ test.describe("Developer section", () => {
|
||||
}
|
||||
});
|
||||
|
||||
test("analytics page shows Not Configured when URL is empty", async ({
|
||||
test("analytics page renders informational landing", async ({ page }) => {
|
||||
await page.goto("/developer/analytics");
|
||||
await page.waitForSelector(".analytics-page", { timeout: 15_000 });
|
||||
|
||||
// Hero section
|
||||
await expect(page.locator(".analytics-hero-title")).toBeVisible();
|
||||
await expect(page.locator(".analytics-hero-desc")).toBeVisible();
|
||||
|
||||
// Connection status indicator
|
||||
await expect(page.locator(".agents-status")).toBeVisible();
|
||||
|
||||
// Metrics bar
|
||||
await expect(page.locator(".analytics-stats-bar")).toBeVisible();
|
||||
});
|
||||
|
||||
test("analytics page shows Not Connected when URL is empty", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.goto("/developer/analytics");
|
||||
await page.waitForSelector(".placeholder-page", { timeout: 15_000 });
|
||||
await page.waitForSelector(".analytics-page", { timeout: 15_000 });
|
||||
|
||||
await expect(
|
||||
page.locator("h2", { hasText: "Analytics" })
|
||||
).toBeVisible();
|
||||
await expect(page.locator(".placeholder-badge")).toContainText(
|
||||
"Not Configured"
|
||||
await expect(page.locator(".agents-status")).toContainText(
|
||||
"Not Connected"
|
||||
);
|
||||
await expect(page.locator(".agents-status-dot--off")).toBeVisible();
|
||||
});
|
||||
|
||||
test("analytics page shows quick action cards", async ({ page }) => {
|
||||
await page.goto("/developer/analytics");
|
||||
await page.waitForSelector(".analytics-page", { timeout: 15_000 });
|
||||
|
||||
const grid = page.locator(".agents-grid");
|
||||
const cards = grid.locator(".agents-card, .agents-card--disabled");
|
||||
await expect(cards).toHaveCount(2);
|
||||
});
|
||||
|
||||
test("analytics page shows SSO hint when connected", async ({ page }) => {
|
||||
// Only meaningful when LANGFUSE_URL is configured.
|
||||
await page.goto("/developer/analytics");
|
||||
await page.waitForSelector(".analytics-page", { timeout: 15_000 });
|
||||
|
||||
const connectedDot = page.locator(".agents-status-dot--on");
|
||||
if (await connectedDot.isVisible()) {
|
||||
await expect(page.locator(".analytics-sso-hint")).toBeVisible();
|
||||
await expect(page.locator(".analytics-launch-btn")).toBeVisible();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user