Give readable content its own text size (#3637)

* feat(app): separate content typography from interface size

Readable prose benefits from its own scale without inflating navigation and controls. Preserve existing users’ rendered size during migration while giving fresh desktop installs a 15px content default.

* test(app): cover independent content typography

The appearance journey now verifies that changing interface size leaves content size intact. Timeline traversal yields when a test deliberately holds the requested page, so the helper no longer waits on its own gate.

* test(desktop): cover independent content typography

The desktop appearance regression follows the renamed Interface control and verifies it does not alter Content size.
This commit is contained in:
Mohamed Boudra
2026-08-21 12:35:23 +02:00
committed by GitHub
parent c032df5b3d
commit 602860625c
31 changed files with 419 additions and 99 deletions
@@ -45,7 +45,7 @@ test("keeps the selected workspace visible in Pure black", async ({ page }, test
}
});
test("applies the base font size to settings text", async ({ page }) => {
test("applies the interface font size to settings text", async ({ page }) => {
await page.addInitScript(() => {
localStorage.setItem("@paseo:app-settings", JSON.stringify({ uiBaseFontSize: 21 }));
});
@@ -56,11 +56,14 @@ test("applies the base font size to settings text", async ({ page }) => {
const sectionTitle = page.getByText("Theme", { exact: true }).first();
await expect(sectionTitle).toHaveCSS("font-size", "18px");
const fontSizeInput = page.getByLabel("Base font size");
await expect(fontSizeInput).toHaveValue("21");
await fontSizeInput.fill("12");
await fontSizeInput.press("Tab");
const interfaceSizeInput = page.getByLabel("Interface font size");
const contentSizeInput = page.getByLabel("Content font size");
await expect(interfaceSizeInput).toHaveValue("21");
await expect(contentSizeInput).toHaveValue("21");
await interfaceSizeInput.fill("12");
await interfaceSizeInput.press("Tab");
await expect(fontSizeInput).toHaveValue("12");
await expect(interfaceSizeInput).toHaveValue("12");
await expect(contentSizeInput).toHaveValue("21");
await expect(sectionTitle).toHaveCSS("font-size", "10px");
});
@@ -545,15 +545,22 @@ async function returnTimelineToSettledHistoryStart(
page: Page,
moveUp: () => Promise<unknown>,
): Promise<void> {
const loadingSpinner = page.getByTestId("load-older-history-spinner");
// A caller may only start a new history traversal after its prior page has settled.
await expect(loadingSpinner).toBeHidden();
let previous = await readTimelineViewport(page);
while (true) {
await moveUp();
await waitForTimelineGeometryToSettle(page);
let viewport = await readTimelineViewport(page);
// Tests that hold the response need to observe the requested page before releasing it.
if (await loadingSpinner.isVisible()) {
return;
}
if (viewport.scrollTop <= HISTORY_START_THRESHOLD_PX) {
return;
}
await expect(page.getByTestId("load-older-history-spinner")).toBeHidden();
await expect(loadingSpinner).toBeHidden();
await waitForTimelineGeometryToSettle(page);
viewport = await readTimelineViewport(page);
expect(