import { expect, test, type Page } from '@playwright/test'; import { policyAuthorSession } from '../../src/app/testing'; const mockConfig = { authority: { issuer: 'https://authority.local', clientId: 'stella-ops-ui', authorizeEndpoint: 'https://authority.local/connect/authorize', tokenEndpoint: 'https://authority.local/connect/token', logoutEndpoint: 'https://authority.local/connect/logout', redirectUri: 'http://127.0.0.1:4400/auth/callback', postLogoutRedirectUri: 'http://127.0.0.1:4400/', scope: 'openid profile email ui.read findings:read', audience: 'https://scanner.local', dpopAlgorithms: ['ES256'], refreshLeewaySeconds: 60, }, apiBaseUrls: { authority: 'https://authority.local', scanner: 'https://scanner.local', policy: 'https://policy.local', concelier: 'https://concelier.local', attestor: 'https://attestor.local', gateway: 'https://gateway.local', }, quickstartMode: true, setup: 'complete', }; const oidcConfig = { issuer: mockConfig.authority.issuer, authorization_endpoint: mockConfig.authority.authorizeEndpoint, token_endpoint: mockConfig.authority.tokenEndpoint, jwks_uri: 'https://authority.local/.well-known/jwks.json', response_types_supported: ['code'], subject_types_supported: ['public'], id_token_signing_alg_values_supported: ['RS256'], }; const shellSession = { ...policyAuthorSession, scopes: [ ...new Set([ ...policyAuthorSession.scopes, 'ui.read', 'admin', 'ui.admin', 'orch:read', 'orch:operate', 'orch:quota', 'findings:read', 'vuln:view', 'vuln:investigate', 'vuln:operate', 'vuln:audit', 'authority:tenants.read', 'advisory:read', 'vex:read', 'exceptions:read', 'exceptions:approve', 'aoc:verify', 'policy:read', 'policy:author', 'policy:review', 'policy:approve', 'policy:simulate', 'policy:audit', 'health:read', 'notify:viewer', 'release:read', 'release:write', 'release:publish', 'sbom:read', 'signer:read', ]), ], }; async function setupBasicMocks(page: Page) { page.on('console', (message) => { if (message.type() === 'error') { console.log('[browser:error]', message.text()); } }); await page.route('**/config.json', (route) => route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(mockConfig), }), ); await page.route('**/platform/envsettings.json', (route) => route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(mockConfig), }), ); await page.route('https://authority.local/**', (route) => { const url = route.request().url(); if (url.includes('/.well-known/openid-configuration')) { return route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(oidcConfig), }); } if (url.includes('/.well-known/jwks.json')) { return route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ keys: [] }), }); } if (url.includes('authorize')) { return route.abort(); } return route.fulfill({ status: 400, body: 'blocked' }); }); } async function setupAuthenticatedSession(page: Page) { await page.addInitScript((stubSession) => { (window as any).__stellaopsTestSession = stubSession; }, shellSession); } test.describe('Authentication smoke', () => { test.beforeEach(async ({ page }) => { await setupBasicMocks(page); }); test('sign in button is visible on welcome page', async ({ page }) => { await page.goto('/welcome'); await expect(page.getByRole('button', { name: /sign in/i })).toBeVisible(); }); test('clicking sign in starts authority authorization flow', async ({ page }) => { await page.goto('/welcome'); const signInButton = page.getByRole('button', { name: /sign in/i }); await expect(signInButton).toBeVisible(); const [request] = await Promise.all([ page.waitForRequest('https://authority.local/connect/authorize*'), signInButton.click({ noWaitAfter: true }), ]); expect(request.url()).toContain('authority.local/connect/authorize'); }); }); test.describe('Authenticated shell smoke', () => { test.beforeEach(async ({ page }) => { await setupBasicMocks(page); await setupAuthenticatedSession(page); }); test('mission board renders for authenticated session', async ({ page }) => { await page.goto('/'); await expect(page.locator('aside.sidebar')).toBeVisible({ timeout: 15000 }); await expect(page.getByRole('heading', { level: 1, name: /dashboard/i })).toBeVisible({ timeout: 15000, }); }); test('canonical root workspaces are user-reachable', async ({ page }) => { const routes = ['/mission-control/board', '/releases', '/security', '/evidence', '/ops', '/setup']; for (const route of routes) { await page.goto(route); await expect(page.locator('aside.sidebar')).toBeVisible({ timeout: 15000 }); await expect(page.locator('main')).toBeVisible({ timeout: 15000 }); const main = page.locator('main'); const mainText = ((await main.textContent()) ?? '').trim(); const nodeCount = await main.locator('*').count(); expect(mainText.length > 0 || nodeCount > 0).toBe(true); } }); });