From 2c227fb0c1ae3b008bd37a5dafe0a849e49cbc4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Sat, 9 May 2026 20:18:49 +0200 Subject: [PATCH] fix(dashboard): mood tile mobile shows number once + label, not twice MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The mood-list mobile branch (`md:hidden`) rendered each entry's score TWICE: once as a large bold digit in the left badge, then again next to it in the title line as "{score} ({label})". Desktop's table view only ever showed it once. The redundancy made the row read like "2 2 (schlecht)" — the badge already supplies the digit, the title line just needs the textual label. Drop the duplicate digit from the title line; the row now reads "[2] Schlecht / 12.05.2026 18:30 / tags". Add `data-testid` hooks on the row and the score badge so the Pixel-5 Playwright guard at `e2e/mood-card-mobile.spec.ts` can assert "exactly one occurrence of the score digit per row" — that contract is what would have caught the duplicate before merge. Co-Authored-By: Claude Opus 4.7 (1M context) --- e2e/mood-card-mobile.spec.ts | 94 +++++++++++++++++++++++++++++++ src/components/mood/mood-list.tsx | 29 ++++++---- 2 files changed, 112 insertions(+), 11 deletions(-) create mode 100644 e2e/mood-card-mobile.spec.ts diff --git a/e2e/mood-card-mobile.spec.ts b/e2e/mood-card-mobile.spec.ts new file mode 100644 index 000000000..9b74d77d1 --- /dev/null +++ b/e2e/mood-card-mobile.spec.ts @@ -0,0 +1,94 @@ +import { expect, test } from "@playwright/test"; + +import { STORAGE_STATE_PATH } from "./setup/global-setup"; + +/** + * v1.4.15 phase-A3 fix #2 — mood-list mobile card was rendering the score + * twice: once in the left badge (large bold digit) and once in the title + * line as "{score} ({label})". On desktop the table view only ever showed + * one. The fix collapses the title line down to just the localized label + * (e.g., "Schlecht"), so the row reads + * + * [ 2 ] Schlecht + * 12.05.2026, 18:30 + * + * The Pixel-5 viewport is the only one that mounted the mobile branch + * (`md:hidden`) so the regression was mobile-only — this spec runs on the + * `chromium-mobile` project and asserts each `data-testid="mood-row"` + * contains exactly one occurrence of its score digit. + */ +test.describe("mood card mobile layout", () => { + test.use({ storageState: STORAGE_STATE_PATH }); + + test.beforeEach(({}, testInfo) => { + test.skip(testInfo.project.name !== "chromium-mobile", "mobile-only spec"); + }); + + test("each mobile row shows the score number exactly once", async ({ + page, + }) => { + // Stub the mood-entries endpoint with a deterministic dataset whose + // scores are all distinct digits — that lets us reason about + // "exactly one occurrence" per row independently of locale or label. + await page.route("**/api/mood-entries*", (route) => + route.fulfill({ + status: 200, + contentType: "application/json", + body: JSON.stringify({ + data: { + entries: [ + { + id: "m1", + date: "2026-05-08", + mood: "SCHLECHT", + score: 2, + tags: [], + source: "MANUAL", + moodLoggedAt: "2026-05-08T08:30:00.000Z", + }, + { + id: "m2", + date: "2026-05-07", + mood: "GUT", + score: 4, + tags: [], + source: "MANUAL", + moodLoggedAt: "2026-05-07T19:00:00.000Z", + }, + ], + meta: { total: 2 }, + }, + error: null, + }), + }), + ); + + await page.goto("/mood", { waitUntil: "domcontentloaded" }); + + const rows = page.locator('[data-testid="mood-row"]'); + await expect(rows).toHaveCount(2, { timeout: 10_000 }); + + // For each row, the rendered text must contain its score digit + // exactly once. The desktop table also shows the digit + label in + // one cell, but `md:hidden` hides this branch above the breakpoint — + // on the Pixel-5 profile only the mobile branch mounts. + for (let i = 0; i < 2; i++) { + const row = rows.nth(i); + const text = await row.innerText(); + const expectedScore = i === 0 ? "2" : "4"; + const occurrences = ( + text.match(new RegExp(`(? - {/* Mobile list */} + {/* Mobile list — v1.4.15 phase-A3 fix #2: previously the row + rendered the score TWICE on mobile (the big number in the + left badge AND a duplicate in the title line: "2 (schlecht)"). + Desktop's table version only ever showed one. The badge is + the visual anchor; next to it the user wants the textual + label, not a second copy of the digit. The + `data-testid="mood-row"` hook is what the Playwright Pixel-5 + guard at `e2e/mood-card-mobile.spec.ts` queries to assert + "exactly one occurrence of the score per row". */}
{data.entries.map((entry) => (
- + {entry.score}
- - {entry.score}{" "} - - ( - {MOOD_LABEL_KEYS[entry.mood] - ? t(MOOD_LABEL_KEYS[entry.mood]) - : entry.mood} - ) - + + {MOOD_LABEL_KEYS[entry.mood] + ? t(MOOD_LABEL_KEYS[entry.mood]) + : entry.mood}

{formatDateTime(entry.moodLoggedAt)}