import { test, expect } from '@playwright/test' /** * E2E Tests: Analytics Navigation * * Tests all 10 analytics pages are accessible and load correctly: * - Revenue, Transactions, Costs, P&L * - Performance, Errors, Real-Time * - Bounce Rate, Conversions, A/B Tests * * NOTE: These tests are designed to run in the context of platform-admin * which mounts the analytics pages at /analytics/* routes. */ test.describe('Analytics Navigation - Comprehensive Route Testing', () => { test.beforeEach(async ({ page }) => { // Navigate to platform-admin (assuming dev auth bypass is enabled) await page.goto('/', { waitUntil: 'networkidle' }) // Wait for React app to mount and render await page.waitForSelector('[data-testid="sidebar"]', { timeout: 15000 }) }) // ======================================== // SECTION 1: ANALYTICS SECTION VISIBLE // ======================================== test('should display analytics section in sidebar', async ({ page }) => { const analyticsSection = page.locator('h3:has-text("Analytics")') await expect(analyticsSection).toBeVisible() // Verify all 10 analytics links are present const expectedLinks = [ 'Revenue', 'Transactions', 'Costs', 'P&L', 'Performance', 'Errors', 'Real-time', 'Bounce Rate', 'Conversions', 'A/B Tests', ] for (const linkText of expectedLinks) { const link = page.locator(`a:has-text("${linkText}")`) await expect(link).toBeVisible() } }) // ======================================== // SECTION 2: ANALYTICS ROUTES (10 routes) // ======================================== test.describe('Analytics Routes', () => { const analyticsRoutes = [ { path: '/analytics/revenue', label: 'Revenue' }, { path: '/analytics/transactions', label: 'Transactions' }, { path: '/analytics/costs', label: 'Costs' }, { path: '/analytics/pnl', label: 'P&L' }, { path: '/analytics/performance', label: 'Performance' }, { path: '/analytics/errors', label: 'Errors' }, { path: '/analytics/real-time', label: 'Real-Time' }, { path: '/analytics/bounce-rate', label: 'Bounce Rate' }, { path: '/analytics/conversions', label: 'Conversions' }, { path: '/analytics/ab-tests', label: 'A/B Tests' }, ] for (const route of analyticsRoutes) { test(`should navigate to ${route.label} (${route.path})`, async ({ page }) => { const link = page.locator(`a[href="${route.path}"]`).first() await link.click() await expect(page).toHaveURL(route.path) // Verify page loaded with Suspense fallback or content await page.waitForLoadState('networkidle', { timeout: 15000 }) // Verify page title is visible (all analytics pages have data-testid="page-title") const pageTitle = page.locator('[data-testid="page-title"]') await expect(pageTitle).toBeVisible({ timeout: 10000 }) // Verify no error state const main = page.locator('main') await expect(main).toBeVisible() }) } test('should verify all 10 analytics links are present', async ({ page }) => { const analyticsSection = page.locator('h3:has-text("Analytics")').locator('..') const links = await analyticsSection.locator('a').count() expect(links).toBe(10) }) }) // ======================================== // SECTION 3: NAVIGATION FUNCTIONALITY // ======================================== test.describe('Navigation Functionality', () => { test('should highlight active link correctly', async ({ page }) => { // Navigate to a specific page const link = page.locator('a[href="/analytics/revenue"]').first() await link.click() await expect(page).toHaveURL('/analytics/revenue') // Verify active link is visible and navigation succeeded const activeLink = page.locator('a[href="/analytics/revenue"]').first() await expect(activeLink).toBeVisible() // The page title should be visible, confirming successful navigation await expect(page.locator('[data-testid="page-title"]')).toBeVisible() }) test('should navigate between different analytics pages smoothly', async ({ page }) => { // Navigate to Revenue await page.click('a[href="/analytics/revenue"]') await expect(page).toHaveURL('/analytics/revenue') await page.locator('[data-testid="page-title"]').waitFor({ state: 'visible' }) // Navigate to Transactions await page.click('a[href="/analytics/transactions"]') await expect(page).toHaveURL('/analytics/transactions') await page.locator('[data-testid="page-title"]').waitFor({ state: 'visible' }) // Navigate to Performance await page.click('a[href="/analytics/performance"]') await expect(page).toHaveURL('/analytics/performance') await page.locator('[data-testid="page-title"]').waitFor({ state: 'visible' }) // Navigate back to Revenue await page.click('a[href="/analytics/revenue"]') await expect(page).toHaveURL('/analytics/revenue') await page.locator('[data-testid="page-title"]').waitFor({ state: 'visible' }) }) test('should maintain sidebar visibility during navigation', async ({ page }) => { const sidebar = page.locator('[data-testid="sidebar"]') // Verify sidebar initially visible await expect(sidebar).toBeVisible() // Navigate to different pages and verify sidebar remains visible await page.click('a[href="/analytics/revenue"]') await expect(sidebar).toBeVisible() await page.click('a[href="/analytics/transactions"]') await expect(sidebar).toBeVisible() await page.click('a[href="/analytics/costs"]') await expect(sidebar).toBeVisible() }) test('should handle browser back/forward navigation', async ({ page }) => { // Navigate to several pages await page.click('a[href="/analytics/revenue"]') await expect(page).toHaveURL('/analytics/revenue') await page.click('a[href="/analytics/transactions"]') await expect(page).toHaveURL('/analytics/transactions') // Go back await page.goBack() await expect(page).toHaveURL('/analytics/revenue') // Go forward await page.goForward() await expect(page).toHaveURL('/analytics/transactions') }) }) // ======================================== // SECTION 4: LAZY LOADING // ======================================== test.describe('Lazy Loading', () => { test('should display loading state for lazy-loaded pages', async ({ page }) => { // Click on a lazy-loaded route await page.click('a[href="/analytics/revenue"]') // Check for either loading state or immediate content await page.waitForLoadState('networkidle') // Verify page eventually loads const pageTitle = page.locator('[data-testid="page-title"]') await expect(pageTitle).toBeVisible({ timeout: 10000 }) }) test('should successfully load all lazy-loaded analytics pages', async ({ page }) => { const lazyRoutes = [ '/analytics/revenue', '/analytics/transactions', '/analytics/costs', '/analytics/pnl', '/analytics/performance', ] for (const route of lazyRoutes) { await page.goto(route) await page.waitForLoadState('networkidle', { timeout: 15000 }) // Verify no error const pageTitle = page.locator('[data-testid="page-title"]') await expect(pageTitle).toBeVisible({ timeout: 10000 }) } }) }) // ======================================== // SECTION 5: COMPREHENSIVE SUMMARY TEST // ======================================== test('SUMMARY: All 10 analytics routes are accessible', async ({ page }) => { test.setTimeout(120000) // 2 minutes for comprehensive route testing const allRoutes = [ '/analytics/revenue', '/analytics/transactions', '/analytics/costs', '/analytics/pnl', '/analytics/performance', '/analytics/errors', '/analytics/real-time', '/analytics/bounce-rate', '/analytics/conversions', '/analytics/ab-tests', ] const results: { route: string; success: boolean; error?: string }[] = [] for (const route of allRoutes) { try { await page.goto(route) await page.waitForLoadState('networkidle', { timeout: 15000 }) // Verify URL matches expect(page.url()).toContain(route) // Verify page title visible const pageTitle = page.locator('[data-testid="page-title"]') await expect(pageTitle).toBeVisible({ timeout: 10000 }) results.push({ route, success: true }) } catch (error) { results.push({ route, success: false, error: error instanceof Error ? error.message : 'Unknown error', }) } } // Report results const failedRoutes = results.filter(r => !r.success) const passedRoutes = results.filter(r => r.success) console.log('\n========================================') console.log('ANALYTICS NAVIGATION TEST SUMMARY') console.log('========================================') console.log(`Total routes tested: ${results.length}`) console.log(`Passed: ${passedRoutes.length}`) console.log(`Failed: ${failedRoutes.length}`) if (failedRoutes.length > 0) { console.log('\nFailed routes:') failedRoutes.forEach(r => { console.log(` - ${r.route}: ${r.error}`) }) } console.log('\n========================================\n') // All analytics routes should work expect(passedRoutes.length).toBe(allRoutes.length) }) })