test: Add comprehensive background pattern tests
Tests verify both light and dark theme patterns:
- Light: #d6d6d6 gray with concentric squares pattern
- Dark: #3a3a3a gray with diagonal green grid pattern
- Auto theme switches patterns based on system preference
- Pattern persistence when switching themes
- Visual screenshots for manual verification
All 5 tests passing ✅
This commit is contained in:
@@ -0,0 +1,216 @@
|
||||
/**
|
||||
* 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/');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user