Skip to content

Commit 5cd7d7a

Browse files
committed
test(e2e): theme + font-size persistence across renderer reload
- ThemeSwitcher: testids on the dropdown trigger and each option; expose the live value via data-theme-active for locale-independent assertions - FontSizeSwitcher: same — data-font-size-active on the trigger, testid per option - New settings-interface-persistence.e2e.ts: pick a non-default theme (light) and font size (18px), reload the renderer, reopen the Interface panel, assert both values re-hydrated from the Zustand persist store backed by WebKit localStorage in the pinned profile
1 parent e4ac822 commit 5cd7d7a

3 files changed

Lines changed: 84 additions & 2 deletions

File tree

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { browser, expect } from '@wdio/globals'
2+
import { byTestId, waitForApp } from '../helpers/app'
3+
import { openSettings, reloadRenderer } from '../helpers/settings'
4+
5+
/**
6+
* Settings → Interface theme + font-size persistence. Both stores use
7+
* Zustand `persist` against localStorage, which on Linux lives inside
8+
* the WebKit data dir under our pinned XDG profile — so reloading the
9+
* renderer should re-hydrate the user-selected values.
10+
*
11+
* We read the active value off `data-theme-active` / `data-font-size-active`
12+
* on the dropdown trigger (added in ThemeSwitcher / FontSizeSwitcher)
13+
* rather than visible text so the assertions stay independent of i18n.
14+
*/
15+
16+
describe('Settings: Interface persistence', () => {
17+
before(async () => {
18+
await waitForApp()
19+
})
20+
21+
it('persists theme and font-size selection across renderer reload', async () => {
22+
await openSettings('interface')
23+
24+
// Theme: pick a value distinct from the default ("auto").
25+
const themeTrigger = await byTestId('theme-switcher-trigger')
26+
await themeTrigger.click()
27+
const themeLight = await byTestId('theme-option-light', 5_000)
28+
await themeLight.click()
29+
30+
await browser.waitUntil(
31+
async () =>
32+
(await (await byTestId('theme-switcher-trigger')).getAttribute(
33+
'data-theme-active'
34+
)) === 'light',
35+
{ timeout: 5_000, timeoutMsg: 'theme did not switch to light' }
36+
)
37+
38+
// Font size: pick a value distinct from the default ("16px").
39+
const fontTrigger = await byTestId('font-size-switcher-trigger')
40+
await fontTrigger.click()
41+
const fontLarge = await byTestId('font-size-option-18px', 5_000)
42+
await fontLarge.click()
43+
44+
await browser.waitUntil(
45+
async () =>
46+
(await (await byTestId('font-size-switcher-trigger')).getAttribute(
47+
'data-font-size-active'
48+
)) === '18px',
49+
{ timeout: 5_000, timeoutMsg: 'font size did not switch to 18px' }
50+
)
51+
52+
// Reload the renderer, return to the panel, assert both persisted.
53+
await reloadRenderer()
54+
await openSettings('interface')
55+
56+
const themeAfter = await (await byTestId(
57+
'theme-switcher-trigger'
58+
)).getAttribute('data-theme-active')
59+
const fontAfter = await (await byTestId(
60+
'font-size-switcher-trigger'
61+
)).getAttribute('data-font-size-active')
62+
63+
expect(themeAfter).toBe('light')
64+
expect(fontAfter).toBe('18px')
65+
})
66+
})

web-app/src/containers/FontSizeSwitcher.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,14 @@ export function FontSizeSwitcher({
4949
return (
5050
<DropdownMenu>
5151
<DropdownMenuTrigger asChild>
52-
<Button variant="outline" size="sm" className="w-full justify-between" title={t('common:adjustFontSize')}>
52+
<Button
53+
variant="outline"
54+
size="sm"
55+
className="w-full justify-between"
56+
title={t('common:adjustFontSize')}
57+
data-testid="font-size-switcher-trigger"
58+
data-font-size-active={fontSize}
59+
>
5360
{fontSizeOptions.find(
5461
(item: { value: string; label: string }) => item.value === fontSize
5562
)?.label || t('common:medium')}
@@ -60,6 +67,7 @@ export function FontSizeSwitcher({
6067
{fontSizeOptions.map((item: { value: string; label: string }) => (
6168
<DropdownMenuItem
6269
key={item.value}
70+
data-testid={`font-size-option-${item.value}`}
6371
className={cn(
6472
'cursor-pointer my-0.5',
6573
fontSize === item.value && 'bg-secondary-foreground/8'

web-app/src/containers/ThemeSwitcher.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,14 @@ export function ThemeSwitcher({
5656
return (
5757
<DropdownMenu>
5858
<DropdownMenuTrigger asChild>
59-
<Button variant="outline" size="sm" className="w-full justify-between" title={t('common:editTheme')}>
59+
<Button
60+
variant="outline"
61+
size="sm"
62+
className="w-full justify-between"
63+
title={t('common:editTheme')}
64+
data-testid="theme-switcher-trigger"
65+
data-theme-active={activeTheme}
66+
>
6067
{themeOptions.find(
6168
(item: { value: string; label: string }) => item.value === activeTheme
6269
)?.label || t('common:auto')}
@@ -67,6 +74,7 @@ export function ThemeSwitcher({
6774
{themeOptions.map((item) => (
6875
<DropdownMenuItem
6976
key={item.value}
77+
data-testid={`theme-option-${item.value}`}
7078
className={cn(
7179
'cursor-pointer my-0.5',
7280
activeTheme === item.value && 'bg-secondary-foreground/8'

0 commit comments

Comments
 (0)