/** * Theme profile helpers for testing across light/dark/contrast themes */ export type Theme = "light" | "dark" | "contrast"; export const THEMES: Theme[] = ["light", "dark", "contrast"]; /** * Theme-specific CSS custom property values */ export const THEME_VALUES = { light: { "--cf-bg": "#f8fafc", "--cf-text": "#0f172a", "--cf-text-strong": "#0f172a", "--cf-text-muted": "#475569", "--cf-link": "#1d4ed8", "--cf-link-hover": "#1e40af", "--cf-link-visited": "#6d28d9", "--cf-card-bg": "#ffffff", }, dark: { "--cf-bg": "#0f172a", "--cf-text": "#f1f5f9", "--cf-text-strong": "#e2e8f0", "--cf-text-muted": "#94a3b8", "--cf-link": "#93c5fd", "--cf-link-hover": "#bfdbfe", "--cf-link-visited": "#c4b5fd", "--cf-card-bg": "#1e293b", }, contrast: { "--cf-bg": "#000000", "--cf-text": "#ffffff", "--cf-text-strong": "#ffffff", "--cf-text-muted": "#f8fafc", "--cf-link": "#ffff80", "--cf-link-hover": "#ffff00", "--cf-link-visited": "#ffb3ff", "--cf-card-bg": "#000000", }, } as const; /** * WCAG 2.2 AA contrast ratio requirements */ export const WCAG_CONTRAST = { normalText: 4.5, largeText: 3, uiComponents: 3, } as const; /** * Set theme on the page */ export async function setTheme(page: any, theme: Theme): Promise { // Open theme menu await page.click("#theme-menu-button"); // Click theme option await page.click(`[data-theme-option="${theme}"]`); // Wait for theme to apply await page.waitForSelector(`html[data-theme="${theme}"]`, { timeout: 5000 }); } /** * Get computed CSS custom property value */ export async function getCssVariable( page: any, variable: string, ): Promise { return page.evaluate((varName: string) => { return getComputedStyle(document.documentElement) .getPropertyValue(varName) .trim(); }, variable); } /** * Assert that a theme is active */ export async function assertThemeActive( page: any, theme: Theme, ): Promise { const themeAttr = await page.getAttribute("html", "data-theme"); if (themeAttr !== theme) { throw new Error(`Expected theme "${theme}" but got "${themeAttr}"`); } } /** * Run a test across all themes */ export function testAllThemes( name: string, testFn: (theme: Theme) => Promise | void, ): void { for (const theme of THEMES) { test(`${name} - ${theme} theme`, async () => { await testFn(theme); }); } }