Files
coder/site/e2e/tests/users/userSettings.spec.ts
T
Jaayden Halko 2c18e07e39 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.
2026-05-15 16:15:06 +01:00

50 lines
1.6 KiB
TypeScript

import { expect, type Page, test } from "@playwright/test";
import { CONCRETE_THEMES } from "#/theme";
import { users } from "../../constants";
import { login } from "../../helpers";
import { beforeCoderTest } from "../../hooks";
test.beforeEach(({ page }) => {
beforeCoderTest(page);
});
const rootClassNames = async (page: Page) => {
return page.locator("html").evaluate((it) => Array.from(it.classList));
};
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 }) => {
await login(page, users.member);
await page.goto("/settings/appearance", { waitUntil: "domcontentloaded" });
await page.getByRole("combobox", { name: /theme mode/i }).click();
await page.getByRole("option", { name: /single theme/i }).click();
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.
await expectLightThemeClasses(page);
});