44 lines
1.7 KiB
TypeScript
44 lines
1.7 KiB
TypeScript
|
|
/**
|
|||
|
|
* V10 · Sprint 4 · T-B-23.1 · e2e: theme switch (3-mode persistence)
|
|||
|
|
*
|
|||
|
|
* V10 不变量 D2: light / dark / system
|
|||
|
|
* ThemeToggle 实现:3 个 radio 按钮 + 同步 localStorage['theme-pref']
|
|||
|
|
*/
|
|||
|
|
import { test, expect } from '@playwright/test';
|
|||
|
|
|
|||
|
|
test.describe('Theme Switch (V10 Sprint 4 · T-B-23.1 · V10 不变量 D2)', () => {
|
|||
|
|
test('3-theme switch + persistence', async ({ page }) => {
|
|||
|
|
await page.goto('/');
|
|||
|
|
|
|||
|
|
const html = page.locator('html');
|
|||
|
|
|
|||
|
|
// 切换到亮色
|
|||
|
|
await page.getByRole('radio', { name: '亮色' }).click();
|
|||
|
|
await expect(html).toHaveClass(/light/);
|
|||
|
|
await expect(page.getByRole('radio', { name: '亮色' })).toHaveAttribute('aria-checked', 'true');
|
|||
|
|
|
|||
|
|
// 切换到暗色
|
|||
|
|
await page.getByRole('radio', { name: '暗色' }).click();
|
|||
|
|
await expect(html).toHaveClass(/dark/);
|
|||
|
|
await expect(page.getByRole('radio', { name: '暗色' })).toHaveAttribute('aria-checked', 'true');
|
|||
|
|
|
|||
|
|
// 切换到跟随系统
|
|||
|
|
await page.getByRole('radio', { name: '系统' }).click();
|
|||
|
|
await expect(html).toHaveClass(/light|dark/);
|
|||
|
|
await expect(page.getByRole('radio', { name: '系统' })).toHaveAttribute('aria-checked', 'true');
|
|||
|
|
|
|||
|
|
// localStorage 持久化
|
|||
|
|
const stored = await page.evaluate(() => localStorage.getItem('theme-pref'));
|
|||
|
|
expect(stored).toBe('system');
|
|||
|
|
|
|||
|
|
// 刷新后保持
|
|||
|
|
await page.reload();
|
|||
|
|
await expect(page.getByRole('radio', { name: '系统' })).toHaveAttribute('aria-checked', 'true');
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
test('inline script prevents theme flash on first paint', async ({ page }) => {
|
|||
|
|
await page.goto('/');
|
|||
|
|
const htmlClass = await page.locator('html').getAttribute('class');
|
|||
|
|
expect(htmlClass).toMatch(/light|dark/);
|
|||
|
|
});
|
|||
|
|
});
|