/** * Background Pattern Tests * * Validates that background patterns are correctly applied in both light and dark themes. * Tests cover: * - Pattern existence (not "none") * - Correct background colors * - Pattern application to body element * - Theme switching maintains patterns */ import { test, expect } from '@playwright/test'; const URL = process.env.TEST_URL || 'http://localhost:1999'; const CURRENT_YEAR = new Date().getFullYear(); test.describe('Background Patterns', () => { test('Light theme has concentric squares pattern on light gray background', async ({ page }) => { // Navigate to light theme await page.goto(`${URL}/?lang=en`); await page.evaluate(() => { localStorage.setItem('color-theme-mode', 'light'); document.documentElement.setAttribute('data-color-theme', 'light'); }); await page.reload(); await page.waitForTimeout(500); // Get computed styles const styles = await page.evaluate(() => { const body = document.body; const computed = window.getComputedStyle(body); return { backgroundColor: computed.backgroundColor, backgroundImage: computed.backgroundImage, backgroundSize: computed.backgroundSize, backgroundAttachment: computed.backgroundAttachment, themeAttr: document.documentElement.getAttribute('data-color-theme') }; }); // Verify background color is light gray (#d6d6d6) expect(styles.backgroundColor).toBe('rgb(214, 214, 214)'); // Verify pattern exists (not "none") expect(styles.backgroundImage).not.toBe('none'); // Verify it's a concentric squares pattern (contains repeating-linear-gradient) expect(styles.backgroundImage).toContain('repeating-linear-gradient'); // Verify background size is set (may have multiple values for multiple gradient layers) expect(styles.backgroundSize).toContain('40px 40px'); // Verify background attachment is fixed (may have multiple values for multiple gradient layers) expect(styles.backgroundAttachment).toContain('fixed'); console.log('✅ Light theme: Light gray background (#d6d6d6) with concentric squares pattern'); }); test('Dark theme has diagonal green grid pattern on medium gray background', async ({ page }) => { // Navigate to dark theme await page.goto(`${URL}/?lang=en`); await page.evaluate(() => { localStorage.setItem('color-theme-mode', 'dark'); document.documentElement.setAttribute('data-color-theme', 'dark'); }); await page.reload(); await page.waitForTimeout(500); // Get computed styles const styles = await page.evaluate(() => { const body = document.body; const computed = window.getComputedStyle(body); return { backgroundColor: computed.backgroundColor, backgroundImage: computed.backgroundImage, backgroundSize: computed.backgroundSize, backgroundAttachment: computed.backgroundAttachment, themeAttr: document.documentElement.getAttribute('data-color-theme') }; }); // Verify background color is medium gray (#3a3a3a) expect(styles.backgroundColor).toBe('rgb(58, 58, 58)'); // Verify pattern exists (not "none") expect(styles.backgroundImage).not.toBe('none'); // Verify it's a diagonal grid pattern (contains 45deg and green color) expect(styles.backgroundImage).toContain('45deg'); expect(styles.backgroundImage).toContain('rgba(0, 255, 128'); // Verify background size is set (may have multiple values for multiple gradient layers) expect(styles.backgroundSize).toContain('40px 40px'); // Verify background attachment is fixed (may have multiple values for multiple gradient layers) expect(styles.backgroundAttachment).toContain('fixed'); console.log('✅ Dark theme: Medium gray background (#3a3a3a) with diagonal green grid pattern'); }); test('Pattern persists when switching between themes', async ({ page }) => { await page.goto(`${URL}/?lang=en`); // Start with light theme await page.evaluate(() => { localStorage.setItem('color-theme-mode', 'light'); document.documentElement.setAttribute('data-color-theme', 'light'); }); await page.reload(); await page.waitForTimeout(500); const lightPattern = await page.evaluate(() => { return window.getComputedStyle(document.body).backgroundImage; }); expect(lightPattern).not.toBe('none'); expect(lightPattern).toContain('repeating-linear-gradient'); // Switch to dark theme await page.evaluate(() => { localStorage.setItem('color-theme-mode', 'dark'); document.documentElement.setAttribute('data-color-theme', 'dark'); }); await page.reload(); await page.waitForTimeout(500); const darkPattern = await page.evaluate(() => { return window.getComputedStyle(document.body).backgroundImage; }); expect(darkPattern).not.toBe('none'); expect(darkPattern).toContain('45deg'); expect(darkPattern).toContain('rgba(0, 255, 128'); // Patterns should be different expect(lightPattern).not.toBe(darkPattern); console.log('✅ Patterns persist and change correctly when switching themes'); }); test('Auto theme uses correct pattern based on system preference', async ({ page }) => { // Test auto theme in light mode await page.emulateMedia({ colorScheme: 'light' }); await page.goto(`${URL}/?lang=en`); await page.evaluate(() => { localStorage.setItem('color-theme-mode', 'auto'); document.documentElement.setAttribute('data-color-theme', 'auto'); }); await page.reload(); await page.waitForTimeout(500); const autoLightStyles = await page.evaluate(() => { const computed = window.getComputedStyle(document.body); return { backgroundColor: computed.backgroundColor, backgroundImage: computed.backgroundImage }; }); // In light mode, auto theme should use light gray background with concentric squares pattern expect(autoLightStyles.backgroundColor).toBe('rgb(214, 214, 214)'); expect(autoLightStyles.backgroundImage).toContain('repeating-linear-gradient'); // Test auto theme in dark mode await page.emulateMedia({ colorScheme: 'dark' }); await page.reload(); await page.waitForTimeout(500); const autoDarkStyles = await page.evaluate(() => { const computed = window.getComputedStyle(document.body); return { backgroundColor: computed.backgroundColor, backgroundImage: computed.backgroundImage }; }); // In dark mode, auto theme should use medium gray background with diagonal grid expect(autoDarkStyles.backgroundColor).toBe('rgb(58, 58, 58)'); expect(autoDarkStyles.backgroundImage).toContain('45deg'); expect(autoDarkStyles.backgroundImage).toContain('rgba(0, 255, 128'); console.log('✅ Auto theme uses correct patterns based on system preference'); }); test('Take visual screenshots of both patterns for manual verification', async ({ page }) => { // Light mode screenshot await page.goto(`${URL}/?lang=en`); await page.evaluate(() => { localStorage.setItem('color-theme-mode', 'light'); document.documentElement.setAttribute('data-color-theme', 'light'); }); await page.reload(); await page.waitForTimeout(500); await page.screenshot({ path: 'tests/screenshots/pattern-light-theme.png', fullPage: false }); // Dark mode screenshot await page.evaluate(() => { localStorage.setItem('color-theme-mode', 'dark'); document.documentElement.setAttribute('data-color-theme', 'dark'); }); await page.reload(); await page.waitForTimeout(500); await page.screenshot({ path: 'tests/screenshots/pattern-dark-theme.png', fullPage: false }); console.log('✅ Screenshots saved to tests/screenshots/'); }); });