mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: add theme mode dropdown (#25183)
## Summary - Wire the Appearance settings page to the new theme mode dropdown and sync or single theme selectors. - Update Appearance page tests and stories for theme mode behavior. - Update the user settings e2e test to exercise single theme selection. ## Dependencies - Depends on #25076, #25180, #25181, and #25182. - This PR targets helper branch `pr25077/05-theme-mode-dropdown-base`, which contains dependency commits only, so this PR diff stays focused on final dropdown wiring. Rebase and retarget after the dependency PRs merge. ## Validation - `pnpm -C site exec vitest run --project=unit src/pages/UserSettingsPage/AppearancePage/AppearancePage.test.tsx src/theme/themeMode.test.ts src/api/queries/users.test.ts` - `pnpm -C site lint:types` - `pnpm -C site storybook:ci` - `pnpm -C site build` - `pnpm -C site playwright:test -- e2e/tests/users/userSettings.spec.ts` - Pre-commit hook passed on the branch commit.
This commit is contained in:
@@ -12,15 +12,19 @@ const rootClassNames = async (page: Page) => {
|
||||
return page.locator("html").evaluate((it) => Array.from(it.classList));
|
||||
};
|
||||
|
||||
// Assert the light theme without rejecting unrelated root classes.
|
||||
const expectLightThemeClasses = (classes: string[]) => {
|
||||
const className = "light";
|
||||
expect(classes).toContain(className);
|
||||
for (const themeClassName of CONCRETE_THEMES.filter(
|
||||
(it) => it !== className,
|
||||
)) {
|
||||
expect(classes).not.toContain(themeClassName);
|
||||
}
|
||||
const expectLightThemeClasses = async (page: Page) => {
|
||||
await expect(async () => {
|
||||
const classes = await rootClassNames(page);
|
||||
const className = "light";
|
||||
|
||||
// Assert the light theme without rejecting unrelated root classes.
|
||||
expect(classes).toContain(className);
|
||||
for (const themeClassName of CONCRETE_THEMES.filter(
|
||||
(it) => it !== className,
|
||||
)) {
|
||||
expect(classes).not.toContain(themeClassName);
|
||||
}
|
||||
}).toPass({ timeout: 10_000 });
|
||||
};
|
||||
|
||||
test("adjust user theme preference", async ({ page }) => {
|
||||
@@ -28,14 +32,18 @@ test("adjust user theme preference", async ({ page }) => {
|
||||
|
||||
await page.goto("/settings/appearance", { waitUntil: "domcontentloaded" });
|
||||
|
||||
await page.getByText("Light", { exact: true }).click();
|
||||
await expect(page.getByLabel("Light")).toBeChecked();
|
||||
await page.getByRole("combobox", { name: /theme mode/i }).click();
|
||||
await page.getByRole("option", { name: /single theme/i }).click();
|
||||
|
||||
expectLightThemeClasses(await rootClassNames(page));
|
||||
const singleThemeGroup = page.getByRole("group", { name: "Theme" });
|
||||
await expect(singleThemeGroup).toBeVisible();
|
||||
await singleThemeGroup.getByText("Light default", { exact: true }).click();
|
||||
|
||||
await expectLightThemeClasses(page);
|
||||
|
||||
await page.goto("/", { waitUntil: "domcontentloaded" });
|
||||
|
||||
// Make sure the page is still using the light theme after reloading and
|
||||
// navigating away from the settings page.
|
||||
expectLightThemeClasses(await rootClassNames(page));
|
||||
await expectLightThemeClasses(page);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user