import { test, expect } from '@playwright/test'; /** * Dark Mode Toggle Integration Tests * Tests the theme switching functionality across the admin dashboard */ test.describe('Dark Mode Toggle', () => { // Clear theme preference before each test (keep auth tokens) test.beforeEach(async ({ page }) => { await page.goto('/'); await page.waitForLoadState('domcontentloaded'); // Only clear theme preference, not auth tokens await page.evaluate(() => localStorage.removeItem('didi-admin-theme')); }); test.describe('Service Monitor Page', () => { test('should display theme toggle in sidebar', async ({ page }) => { await page.goto('/'); await page.waitForLoadState('domcontentloaded'); // Theme toggle should be visible in the sidebar header const sidebarToggle = page.locator('.MuiDrawer-root button[aria-label*="Switch to"]'); await expect(sidebarToggle.first()).toBeVisible(); }); test('should switch to dark mode when toggle is clicked', async ({ page }) => { await page.goto('/'); await page.waitForLoadState('domcontentloaded'); // Click the theme toggle (switch to dark) const toggleButton = page.locator('button[aria-label*="Switch to dark"]').first(); await toggleButton.click(); // Verify localStorage was updated const theme = await page.evaluate(() => localStorage.getItem('didi-admin-theme')); expect(theme).toBe('dark'); // Verify the toggle now shows "switch to light" const lightToggle = page.locator('button[aria-label*="Switch to light"]').first(); await expect(lightToggle).toBeVisible(); }); test('should apply dark background color in dark mode', async ({ page }) => { await page.goto('/'); await page.waitForLoadState('domcontentloaded'); // Switch to dark mode await page.locator('button[aria-label*="Switch to dark"]').first().click(); // Check that background color changed to dark const bgColor = await page.evaluate(() => { const main = document.querySelector('main') || document.body; return getComputedStyle(main).backgroundColor; }); // Dark mode background should be dark (#121212 = rgb(18, 18, 18)) expect(bgColor).toMatch(/rgb\(18,\s*18,\s*18\)|rgb\(30,\s*30,\s*30\)/); }); test('should switch back to light mode', async ({ page }) => { await page.goto('/'); await page.waitForLoadState('domcontentloaded'); // Switch to dark mode first await page.locator('button[aria-label*="Switch to dark"]').first().click(); // Switch back to light mode await page.locator('button[aria-label*="Switch to light"]').first().click(); // Verify localStorage const theme = await page.evaluate(() => localStorage.getItem('didi-admin-theme')); expect(theme).toBe('light'); }); }); test.describe('Theme Persistence', () => { test('should persist dark mode after page refresh', async ({ page }) => { await page.goto('/'); await page.waitForLoadState('networkidle'); // Switch to dark mode await page.locator('button[aria-label*="Switch to dark"]').first().click(); // Wait for theme to be saved await page.waitForTimeout(500); // Refresh the page await page.reload({ waitUntil: 'networkidle' }); // Wait for app to stabilize and verify toggle is visible first const lightToggle = page.locator('button[aria-label*="Switch to light"]').first(); await expect(lightToggle).toBeVisible({ timeout: 10000 }); // Now verify localStorage const theme = await page.evaluate(() => localStorage.getItem('didi-admin-theme')); expect(theme).toBe('dark'); }); test('should persist light mode after page refresh', async ({ page }) => { await page.goto('/'); await page.waitForLoadState('networkidle'); // Refresh the page await page.reload({ waitUntil: 'networkidle' }); // Wait for app to stabilize and verify toggle is visible const darkToggle = page.locator('button[aria-label*="Switch to dark"]').first(); await expect(darkToggle).toBeVisible({ timeout: 10000 }); }); }); test.describe('Orchestrator Page', () => { test('should display theme toggle in sidebar header', async ({ page }) => { await page.goto('/orchestrator'); await page.waitForLoadState('domcontentloaded'); // Theme toggle should be visible in the drawer header const sidebarToggle = page.locator('.MuiDrawer-root button[aria-label*="Switch to"]'); await expect(sidebarToggle.first()).toBeVisible(); }); test('should share theme state with Service Monitor', async ({ page }) => { // Set dark mode on Service Monitor await page.goto('/'); await page.waitForLoadState('networkidle'); await page.locator('button[aria-label*="Switch to dark"]').first().click(); // Wait for theme to be saved await page.waitForTimeout(500); // Navigate to Orchestrator await page.goto('/orchestrator', { waitUntil: 'networkidle' }); // Wait for toggle to be visible first (proves page is loaded) const lightToggle = page.locator('button[aria-label*="Switch to light"]').first(); await expect(lightToggle).toBeVisible({ timeout: 10000 }); // Now verify localStorage const theme = await page.evaluate(() => localStorage.getItem('didi-admin-theme')); expect(theme).toBe('dark'); }); test('should apply dark mode styling on Orchestrator page', async ({ page }) => { await page.goto('/orchestrator'); await page.waitForLoadState('domcontentloaded'); // Switch to dark mode await page.locator('button[aria-label*="Switch to dark"]').first().click(); // Main content should have dark background const bgColor = await page.evaluate(() => { const main = document.querySelector('main') || document.body; return getComputedStyle(main).backgroundColor; }); expect(bgColor).toMatch(/rgb\(18,\s*18,\s*18\)|rgb\(30,\s*30,\s*30\)/); }); }); test.describe('Cross-Page Consistency', () => { test('theme toggle position should be consistent (sidebar)', async ({ page }) => { // Check Service Monitor await page.goto('/'); await page.waitForLoadState('domcontentloaded'); const serviceMonitorToggle = page.locator('.MuiDrawer-root button[aria-label*="Switch to"]').first(); await expect(serviceMonitorToggle).toBeVisible(); // Check Orchestrator await page.goto('/orchestrator'); await page.waitForLoadState('domcontentloaded'); const orchestratorToggle = page.locator('.MuiDrawer-root button[aria-label*="Switch to"]').first(); await expect(orchestratorToggle).toBeVisible(); }); }); }); test.describe('Mobile Dark Mode', () => { test.use({ viewport: { width: 375, height: 667 } }); // iPhone SE test('should have theme toggle in mobile app bar', async ({ page }) => { await page.goto('/'); await page.waitForLoadState('domcontentloaded'); // On mobile, toggle should be in the AppBar const appBarToggle = page.locator('.MuiAppBar-root button[aria-label*="Switch to"]'); await expect(appBarToggle).toBeVisible(); }); test('should toggle dark mode on mobile', async ({ page }) => { await page.goto('/'); await page.waitForLoadState('domcontentloaded'); // Click toggle in AppBar await page.locator('.MuiAppBar-root button[aria-label*="Switch to dark"]').click(); // Verify dark mode const theme = await page.evaluate(() => localStorage.getItem('didi-admin-theme')); expect(theme).toBe('dark'); }); });