/** * Interactive Smoke Tests - Section by Section * Tests actual UI interactions, clicks, navigation elements on every screen. * Takes screenshots for visual verification. */ import { test, expect } from './fixtures/auth.fixture'; const SCREENSHOT_DIR = 'e2e/screenshots'; async function snap(page: import('@playwright/test').Page, label: string) { await page.screenshot({ path: `${SCREENSHOT_DIR}/${label}.png`, fullPage: true }); } function collectErrors(page: import('@playwright/test').Page) { const errors: string[] = []; page.on('console', (msg) => { if (msg.type() === 'error') errors.push(msg.text()); }); page.on('pageerror', (err) => errors.push(err.message)); return errors; } async function go(page: import('@playwright/test').Page, path: string) { await page.goto(path, { waitUntil: 'networkidle', timeout: 30_000 }); await page.waitForLoadState('domcontentloaded'); await page.waitForTimeout(1500); } // SECTION 1: Mission Control test.describe('Section 1: Mission Control', () => { test('dashboard loads with widgets', async ({ authenticatedPage: page }) => { const errors = collectErrors(page); await go(page, '/'); await snap(page, '01-mission-control-dashboard'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(20); const nav = page.locator('nav, [role="navigation"], .sidebar, .sidenav, mat-sidenav'); const navCount = await nav.count(); expect(navCount, 'Should have navigation element').toBeGreaterThanOrEqual(1); const criticalErrors = errors.filter(e => e.includes('NG0') || e.includes('TypeError') || e.includes('ReferenceError') ); expect(criticalErrors, 'Critical errors: ' + criticalErrors.join('\n')).toHaveLength(0); }); test('sidebar navigation has main sections', async ({ authenticatedPage: page }) => { await go(page, '/'); const links = page.locator('a[href], [routerlink], mat-list-item, .nav-item, .menu-item'); const count = await links.count(); expect(count, 'Should have navigation links').toBeGreaterThan(3); await snap(page, '01-mission-control-nav'); }); test('mission control alerts page', async ({ authenticatedPage: page }) => { const errors = collectErrors(page); await go(page, '/mission-control/alerts'); await snap(page, '01-mission-control-alerts'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); const criticalErrors = errors.filter(e => e.includes('NG0')); expect(criticalErrors).toHaveLength(0); }); test('mission control activity page', async ({ authenticatedPage: page }) => { const errors = collectErrors(page); await go(page, '/mission-control/activity'); await snap(page, '01-mission-control-activity'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); const criticalErrors = errors.filter(e => e.includes('NG0')); expect(criticalErrors).toHaveLength(0); }); }); // SECTION 2: Releases test.describe('Section 2: Releases', () => { test('releases overview loads', async ({ authenticatedPage: page }) => { const errors = collectErrors(page); await go(page, '/releases/overview'); await snap(page, '02-releases-overview'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); const criticalErrors = errors.filter(e => e.includes('NG0')); expect(criticalErrors).toHaveLength(0); }); test('release versions page', async ({ authenticatedPage: page }) => { await go(page, '/releases/versions'); await snap(page, '02-releases-versions'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('releases runs page', async ({ authenticatedPage: page }) => { await go(page, '/releases/runs'); await snap(page, '02-releases-runs'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('approvals queue page', async ({ authenticatedPage: page }) => { await go(page, '/releases/approvals'); await snap(page, '02-releases-approvals'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('promotion queue page', async ({ authenticatedPage: page }) => { await go(page, '/releases/promotion-queue'); await snap(page, '02-releases-promotion-queue'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('environments page', async ({ authenticatedPage: page }) => { await go(page, '/releases/environments'); await snap(page, '02-releases-environments'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('deployments page', async ({ authenticatedPage: page }) => { await go(page, '/releases/deployments'); await snap(page, '02-releases-deployments'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); }); // SECTION 3: Security test.describe('Section 3: Security', () => { test('security posture page', async ({ authenticatedPage: page }) => { const errors = collectErrors(page); await go(page, '/security/posture'); await snap(page, '03-security-posture'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); const criticalErrors = errors.filter(e => e.includes('NG0')); expect(criticalErrors).toHaveLength(0); }); test('security triage page', async ({ authenticatedPage: page }) => { await go(page, '/security/triage'); await snap(page, '03-security-triage'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('advisories and VEX page', async ({ authenticatedPage: page }) => { await go(page, '/security/advisories-vex'); await snap(page, '03-security-advisories-vex'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('disposition center page', async ({ authenticatedPage: page }) => { await go(page, '/security/disposition'); await snap(page, '03-security-disposition'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('supply chain data page', async ({ authenticatedPage: page }) => { await go(page, '/security/supply-chain-data'); await snap(page, '03-security-supply-chain'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('reachability center page', async ({ authenticatedPage: page }) => { await go(page, '/security/reachability'); await snap(page, '03-security-reachability'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('security reports page', async ({ authenticatedPage: page }) => { await go(page, '/security/reports'); await snap(page, '03-security-reports'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); }); // SECTION 4: Evidence test.describe('Section 4: Evidence', () => { test('evidence overview', async ({ authenticatedPage: page }) => { await go(page, '/evidence/overview'); await snap(page, '04-evidence-overview'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('decision capsules page', async ({ authenticatedPage: page }) => { await go(page, '/evidence/capsules'); await snap(page, '04-evidence-capsules'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('verify and replay page', async ({ authenticatedPage: page }) => { await go(page, '/evidence/verify-replay'); await snap(page, '04-evidence-verify-replay'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('evidence exports page', async ({ authenticatedPage: page }) => { await go(page, '/evidence/exports'); await snap(page, '04-evidence-exports'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('audit log dashboard', async ({ authenticatedPage: page }) => { await go(page, '/evidence/audit-log'); await snap(page, '04-evidence-audit-log'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('audit log events', async ({ authenticatedPage: page }) => { await go(page, '/evidence/audit-log/events'); await snap(page, '04-evidence-audit-events'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('audit timeline search', async ({ authenticatedPage: page }) => { await go(page, '/evidence/audit-log/timeline'); await snap(page, '04-evidence-audit-timeline'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); }); // SECTION 5: Ops - Operations test.describe('Section 5: Ops - Operations', () => { test('ops overview', async ({ authenticatedPage: page }) => { await go(page, '/ops/operations'); await snap(page, '05-ops-overview'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('jobs and queues', async ({ authenticatedPage: page }) => { await go(page, '/ops/operations/jobs-queues'); await snap(page, '05-ops-jobs-queues'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('system health', async ({ authenticatedPage: page }) => { await go(page, '/ops/operations/system-health'); await snap(page, '05-ops-system-health'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('jobengine dashboard', async ({ authenticatedPage: page }) => { await go(page, '/ops/operations/jobengine'); await snap(page, '05-ops-jobengine'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('doctor diagnostics', async ({ authenticatedPage: page }) => { await go(page, '/ops/operations/doctor'); await snap(page, '05-ops-doctor'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('notifications', async ({ authenticatedPage: page }) => { await go(page, '/ops/operations/notifications'); await snap(page, '05-ops-notifications'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('AI runs list', async ({ authenticatedPage: page }) => { await go(page, '/ops/operations/ai-runs'); await snap(page, '05-ops-ai-runs'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); }); // SECTION 6: Ops - Integrations test.describe('Section 6: Ops - Integrations', () => { test('integration hub', async ({ authenticatedPage: page }) => { await go(page, '/ops/integrations'); await snap(page, '06-integrations-hub'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('registries page', async ({ authenticatedPage: page }) => { await go(page, '/ops/integrations/registries'); await snap(page, '06-integrations-registries'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('source control page', async ({ authenticatedPage: page }) => { await go(page, '/ops/integrations/scm'); await snap(page, '06-integrations-scm'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('CI/CD page', async ({ authenticatedPage: page }) => { await go(page, '/ops/integrations/ci'); await snap(page, '06-integrations-ci'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('runtime hosts page', async ({ authenticatedPage: page }) => { await go(page, '/ops/integrations/runtime-hosts'); await snap(page, '06-integrations-runtime'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); }); // SECTION 7: Ops - Policy test.describe('Section 7: Ops - Policy', () => { test('policy overview', async ({ authenticatedPage: page }) => { await go(page, '/ops/policy/overview'); await snap(page, '07-policy-overview'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('policy baselines', async ({ authenticatedPage: page }) => { await go(page, '/ops/policy/baselines'); await snap(page, '07-policy-baselines'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('gate catalog', async ({ authenticatedPage: page }) => { await go(page, '/ops/policy/gates'); await snap(page, '07-policy-gates'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('shadow mode / simulation', async ({ authenticatedPage: page }) => { await go(page, '/ops/policy/simulation'); await snap(page, '07-policy-simulation'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('policy lint', async ({ authenticatedPage: page }) => { await go(page, '/ops/policy/simulation/lint'); await snap(page, '07-policy-lint'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('risk budget', async ({ authenticatedPage: page }) => { await go(page, '/ops/policy/risk-budget'); await snap(page, '07-policy-risk-budget'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('sealed mode', async ({ authenticatedPage: page }) => { await go(page, '/ops/policy/sealed-mode'); await snap(page, '07-policy-sealed-mode'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('policy profiles', async ({ authenticatedPage: page }) => { await go(page, '/ops/policy/profiles'); await snap(page, '07-policy-profiles'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); }); // SECTION 8: Setup test.describe('Section 8: Setup and Configuration', () => { test('identity and access', async ({ authenticatedPage: page }) => { await go(page, '/setup/identity-access'); await snap(page, '08-setup-identity'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('tenant and branding', async ({ authenticatedPage: page }) => { await go(page, '/setup/tenant-branding'); await snap(page, '08-setup-tenant'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('notifications rules', async ({ authenticatedPage: page }) => { await go(page, '/setup/notifications/rules'); await snap(page, '08-setup-notifications-rules'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('notifications channels', async ({ authenticatedPage: page }) => { await go(page, '/setup/notifications/channels'); await snap(page, '08-setup-notifications-channels'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('notifications templates', async ({ authenticatedPage: page }) => { await go(page, '/setup/notifications/templates'); await snap(page, '08-setup-notifications-templates'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('usage and limits', async ({ authenticatedPage: page }) => { await go(page, '/setup/usage'); await snap(page, '08-setup-usage'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('system settings', async ({ authenticatedPage: page }) => { await go(page, '/setup/system'); await snap(page, '08-setup-system'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); }); // SECTION 9: Topology test.describe('Section 9: Topology', () => { test('topology overview', async ({ authenticatedPage: page }) => { await go(page, '/setup/topology/overview'); await snap(page, '09-topology-overview'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('topology map', async ({ authenticatedPage: page }) => { await go(page, '/setup/topology/map'); await snap(page, '09-topology-map'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('regions and environments', async ({ authenticatedPage: page }) => { await go(page, '/setup/topology/regions'); await snap(page, '09-topology-regions'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('targets', async ({ authenticatedPage: page }) => { await go(page, '/setup/topology/targets'); await snap(page, '09-topology-targets'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('hosts', async ({ authenticatedPage: page }) => { await go(page, '/setup/topology/hosts'); await snap(page, '09-topology-hosts'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('agent fleet', async ({ authenticatedPage: page }) => { await go(page, '/setup/topology/agents'); await snap(page, '09-topology-agents'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('promotion graph', async ({ authenticatedPage: page }) => { await go(page, '/setup/topology/promotion-graph'); await snap(page, '09-topology-promotion-graph'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); }); // SECTION 10: Platform Setup test.describe('Section 10: Platform Setup', () => { test('platform setup home', async ({ authenticatedPage: page }) => { await go(page, '/ops/platform-setup'); await snap(page, '10-platform-setup-home'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('promotion paths', async ({ authenticatedPage: page }) => { await go(page, '/ops/platform-setup/promotion-paths'); await snap(page, '10-platform-promotion-paths'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('workflows and gates', async ({ authenticatedPage: page }) => { await go(page, '/ops/platform-setup/workflows-gates'); await snap(page, '10-platform-workflows-gates'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('trust and signing', async ({ authenticatedPage: page }) => { await go(page, '/ops/platform-setup/trust-signing'); await snap(page, '10-platform-trust-signing'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); }); // SECTION 11: AI and Analysis test.describe('Section 11: AI and Analysis', () => { test('AI chat', async ({ authenticatedPage: page }) => { await go(page, '/ai/chat'); await snap(page, '11-ai-chat'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('AI autofix', async ({ authenticatedPage: page }) => { await go(page, '/ai/autofix'); await snap(page, '11-ai-autofix'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('graph explorer', async ({ authenticatedPage: page }) => { await go(page, '/graph'); await snap(page, '11-graph-explorer'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('timeline', async ({ authenticatedPage: page }) => { await go(page, '/timeline'); await snap(page, '11-timeline'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); test('change trace', async ({ authenticatedPage: page }) => { await go(page, '/change-trace'); await snap(page, '11-change-trace'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); }); // SECTION 12: Welcome test.describe('Section 12: Welcome and Setup Wizard', () => { test('welcome page (no auth)', async ({ page }) => { await page.goto('/welcome', { waitUntil: 'networkidle', timeout: 30_000 }); await page.waitForTimeout(1500); await snap(page, '12-welcome'); const body = await page.locator('body').innerText(); expect(body.length).toBeGreaterThan(10); }); });