Files
git.stella-ops.org/src/Web/StellaOps.Web/e2e/fixtures/auth.fixture.ts

210 lines
5.7 KiB
TypeScript

import { test as base, expect, Page } from '@playwright/test';
/**
* StubAuthSession shape matches src/app/testing/auth-fixtures.ts.
* The Angular APP_INITIALIZER in app.config.ts reads
* `window.__stellaopsTestSession` and calls seedAuthSession() to
* populate the AuthSessionStore before guards execute.
*/
interface StubAuthSession {
subjectId: string;
tenant: string;
scopes: string[];
}
/** Admin session with all major scopes for unrestricted route access. */
const adminTestSession: StubAuthSession = {
subjectId: 'e2e-admin-user',
tenant: 'tenant-default',
scopes: [
'admin',
'ui.read',
'ui.admin',
'orch:read',
'orch:operate',
'orch:quota',
'orch:backfill',
'policy:read',
'policy:write',
'policy:author',
'policy:review',
'policy:approve',
'policy:operate',
'policy:simulate',
'policy:audit',
'exception:read',
'exception:write',
'exception:approve',
'release:read',
'release:write',
'release:publish',
'analytics.read',
'graph:read',
'graph:write',
'graph:admin',
'sbom:read',
'sbom:write',
'scanner:read',
'vex:read',
'vex:export',
'advisory:read',
'scheduler:read',
'scheduler:operate',
'findings:read',
'exceptions:read',
],
};
/** Minimal runtime config for deterministic SPA bootstrap in E2E. */
const e2eRuntimeConfig = {
setup: 'complete',
authority: {
issuer: 'https://127.0.0.1',
clientId: 'stellaops-web-e2e',
authorizeEndpoint: 'https://127.0.0.1/connect/authorize',
tokenEndpoint: 'https://127.0.0.1/connect/token',
logoutEndpoint: 'https://127.0.0.1/connect/logout',
redirectUri: 'https://127.0.0.1/auth/callback',
postLogoutRedirectUri: 'https://127.0.0.1/',
scope: 'openid profile ui.read',
audience: 'stellaops',
dpopAlgorithms: ['ES256'],
refreshLeewaySeconds: 60,
},
apiBaseUrls: {
authority: '',
gateway: '',
policy: '',
scanner: '',
concelier: '',
attestor: '',
},
telemetry: {
sampleRate: 0,
},
};
export const test = base.extend<{ authenticatedPage: Page }>({
authenticatedPage: async ({ page }, use) => {
// Ensure APP_INITIALIZER config resolution does not hang on missing backend proxy targets.
await page.route('**/platform/envsettings.json', (route) => {
route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify(e2eRuntimeConfig),
});
});
await page.route('**/config.json', (route) => {
route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify(e2eRuntimeConfig),
});
});
// Keep backend probe guard reachable in isolated E2E runs.
await page.route('https://127.0.0.1/.well-known/openid-configuration', (route) => {
route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
issuer: 'https://127.0.0.1',
authorization_endpoint: 'https://127.0.0.1/connect/authorize',
}),
});
});
// Prevent background health polling from failing the shell bootstrap path.
await page.route('**/health', (route) => {
route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ status: 'ok' }),
});
});
// Intercept branding endpoint that can return 500 in dev/Docker
await page.route('**/console/branding**', (route) => {
route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
tenantId: 'tenant-default',
productName: 'Stella Ops',
logoUrl: null,
theme: 'default',
}),
});
});
// Intercept OIDC authorize to prevent redirect loops
await page.route('**/connect/authorize**', (route) => {
route.fulfill({ status: 200, body: '' });
});
// Intercept console profile/introspect calls that fire after session seed
await page.route('**/console/profile**', (route) => {
route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
subjectId: adminTestSession.subjectId,
username: 'qa-tester',
displayName: 'QA Test User',
tenant: adminTestSession.tenant,
roles: ['admin'],
scopes: adminTestSession.scopes,
audiences: ['stellaops'],
authenticationMethods: ['pwd'],
}),
});
});
await page.route('**/console/token/introspect**', (route) => {
route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
active: true,
tenant: adminTestSession.tenant,
subject: adminTestSession.subjectId,
clientId: 'stellaops-console',
scopes: adminTestSession.scopes,
audiences: ['stellaops'],
}),
});
});
await page.route('**/console/tenants**', (route) => {
route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
tenants: [
{
id: adminTestSession.tenant,
displayName: 'Default Tenant',
status: 'active',
isolationMode: 'shared',
defaultRoles: ['admin'],
},
],
}),
});
});
// Inject test session via addInitScript so it is available
// before any Angular code runs (APP_INITIALIZER reads it).
await page.addInitScript((session: StubAuthSession) => {
(window as any).__stellaopsTestSession = session;
}, adminTestSession);
await use(page);
},
});
export { expect } from '@playwright/test';
export { adminTestSession };
export type { StubAuthSession };