Files
Stirling-PDF/frontend/src/core/tests/enterprise/saml-keycloak-login.spec.ts
T
2026-04-27 11:35:50 +01:00

64 lines
2.2 KiB
TypeScript

import { test, expect } from "@playwright/test";
import { ensureCookieConsent } from "@app/tests/helpers/login";
import { bypassOnboarding } from "@app/tests/helpers/api-stubs";
/**
* SAML login round-trip via Keycloak.
*
* Requires the docker-compose-keycloak-saml stack:
* - Keycloak on http://localhost:9080 with realm `stirling-saml`
* - Stirling-PDF on http://localhost:8080 with PREMIUM_KEY set and
* security.saml2.enabled=true
*
* Validates:
* 1. SAML redirect chain → IdP form → SP callback → dashboard.
* 2. Identity surfaces in settings panel.
* 3. A real tool run completes after SAML login.
*/
test.describe("Enterprise SAML (Keycloak) — full SSO flow", () => {
test.beforeEach(async ({ page }) => {
await bypassOnboarding(page);
await ensureCookieConsent(page);
});
test("SAML redirect, identity in settings, real split tool run", async ({
page,
}) => {
test.setTimeout(120_000);
// ── 1. SAML redirect chain ────────────────────────────────
await page.goto("/login", { waitUntil: "domcontentloaded" });
const samlBtn = page
.locator('a[href*="saml"], a[href*="saml2"]')
.or(page.getByRole("button", { name: /saml|authentik|keycloak/i }))
.first();
await expect(samlBtn).toBeVisible({ timeout: 10_000 });
await samlBtn.click();
await page.waitForURL(/\/realms\/stirling-saml\//, {
timeout: 30_000,
});
await page.locator("#username").fill("samluser");
await page.locator("#password").fill("samlpassword");
await page.locator('input[type="submit"], button[type="submit"]').click();
await page.waitForURL((url) => !url.pathname.includes("/login"), {
timeout: 30_000,
});
await expect(
page.getByRole("link", { name: /^Tools$/i }).first(),
).toBeVisible({ timeout: 15_000 });
// ── 2. Identity in settings → Account ────────────────────
await page.locator('[data-testid="config-button"]').first().click();
await page
.getByText(/account settings/i)
.first()
.click();
await expect(page.getByText(/samluser/i).first()).toBeVisible({
timeout: 10_000,
});
});
});