108 lines
2.3 KiB
TypeScript
108 lines
2.3 KiB
TypeScript
/**
|
|
* 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<void> {
|
|
// 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<string> {
|
|
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<void> {
|
|
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,
|
|
): void {
|
|
for (const theme of THEMES) {
|
|
test(`${name} - ${theme} theme`, async () => {
|
|
await testFn(theme);
|
|
});
|
|
}
|
|
}
|