import { test, expect } from '@playwright/test'; import { OAUTH_TARGETS, url, BASE_DOMAIN } from '../targets'; import { completeAuthentikLogin } from '../helpers/authentik'; // OIDC/OAuth federation flow — the real SSO integration signal. A healthy app pod // does NOT prove SSO works: client mis-registration, redirect-URI mismatch, issuer // cert, or a broken Authentik provider all fail HERE, not at the pod. Each test: // 1. open the app, // 2. click its "sign in via Authentik" control, // 3. complete the Authentik login on the redirect, // 4. assert we return to the app authenticated. const USER = process.env.AK_ADMIN_USER ?? 'akadmin'; const PASS = process.env.AK_ADMIN_PASSWORD; for (const t of OAUTH_TARGETS) { test(`${t.name} SSO login via Authentik`, async ({ page }) => { test.skip(!PASS, 'AK_ADMIN_PASSWORD not set — provide via secret to run OAuth flows'); await page.goto(url(t), { waitUntil: 'domcontentloaded' }); // Click the SSO control. const b = t.ssoButton; const btn = b.selector ? page.locator(b.selector).first() : page.getByRole((b.role as any) ?? 'link', { name: b.name! }).first(); await expect(btn, `${t.name}: SSO login control not found`).toBeVisible(); await btn.click(); // We should be redirected to the Authentik domain (or already have a session). await page.waitForLoadState('domcontentloaded'); if (page.url().includes(`.${BASE_DOMAIN}`) && /authentik|\/if\/flow/i.test(page.url())) { await completeAuthentikLogin(page, USER, PASS!); } else { // Not obviously on Authentik — still attempt, in case creds render inline. await completeAuthentikLogin(page, USER, PASS!).catch(() => {}); } // Back in the app, authenticated. const s = t.success; if (s.urlRe) await expect(page).toHaveURL(s.urlRe, { timeout: 25_000 }); if (s.selector) await expect(page.locator(s.selector).first()).toBeVisible({ timeout: 25_000 }); if (s.text) await expect(page.getByText(s.text).first()).toBeVisible({ timeout: 25_000 }); await expect(page.getByText(/invalid|unauthorized|access denied|redirect_uri/i)).toHaveCount(0); await page.screenshot({ path: `test-results/oauth-${t.name}.png`, fullPage: true }); }); }