From 23a666a9dee228d97eb383706b78caea2a744688 Mon Sep 17 00:00:00 2001 From: Zack Date: Wed, 12 Aug 2026 09:04:55 +0200 Subject: [PATCH] Fix notification badge sizing (#34655) * Fix notification badge sizing * Update snapshots * Add space panel badge regression test * Update snapshot * Updated test to test assert screenshot * Update snapshot to look correct * Update playwright test * fix aliased issues --- apps/web/playwright/e2e/spaces/spaces.spec.ts | 60 ++++++++++++++++++ .../space-panel-notification-badge-linux.png | Bin 0 -> 1178 bytes .../Notifications2-test.tsx.snap | 8 +-- .../SpaceTreeLevel-test.tsx.snap | 4 +- .../ThreadsActivityCentre-test.tsx.snap | 20 +++--- .../NotificationBadgeView.module.css | 3 +- 6 files changed, 78 insertions(+), 17 deletions(-) create mode 100644 apps/web/playwright/snapshots/spaces/spaces.spec.ts/space-panel-notification-badge-linux.png diff --git a/apps/web/playwright/e2e/spaces/spaces.spec.ts b/apps/web/playwright/e2e/spaces/spaces.spec.ts index 3bcd244a7e..3aba640a65 100644 --- a/apps/web/playwright/e2e/spaces/spaces.spec.ts +++ b/apps/web/playwright/e2e/spaces/spaces.spec.ts @@ -261,6 +261,66 @@ test.describe("Spaces", () => { await expect(buttons.nth(2)).toHaveAttribute("aria-label", "My Space"); }); + test( + "should render readable notification badges in the space panel", + { tag: "@screenshot" }, + async ({ app, user, bot }) => { + const roomId = await app.client.createRoom({ + name: "Unread Room", + }); + await app.client.createSpace({ + name: "Unread Space", + initial_state: [spaceChildInitialState(user.homeServer, roomId)], + }); + const spaceButton = await app.getSpacePanelButton("Unread Space"); + await expect(spaceButton).toBeVisible(); + + await bot.prepareClient(); + const botUserId = await bot.evaluate((client) => client.getSafeUserId()); + await app.client.evaluate( + async (client, { botUserId, roomId }) => { + await client.invite(roomId, botUserId); + }, + { botUserId, roomId }, + ); + await bot.joinRoom(roomId); + + for (let i = 0; i < 10; i++) { + await bot.sendMessage(roomId, `${user.displayName} unread message ${i}`); + } + + const badge = spaceButton.locator(".mx_SpacePanel_notificationBadge"); + await expect(badge).toHaveText("10"); + + await expect(spaceButton).toMatchScreenshot("space-panel-notification-badge.png", { + css: ` + /* Mask the unstable anti-aliased badge edge at the screenshot crop boundary. */ + .mx_SpacePanel .mx_SpaceButton { + position: relative !important; + } + + .mx_SpacePanel .mx_SpaceButton::before { + content: ""; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 3px; + background: var(--cpd-color-bg-canvas-default); + z-index: 1; + pointer-events: none; + } + + /* Avatar initials can render differently in CI; keep this snapshot focused on the badge. */ + .mx_SpacePanel [role="img"][data-color], + .mx_SpacePanel .mx_BaseAvatar { + color: transparent !important; + } + `, + }); + }, + ); + test("should include rooms in space home", async ({ page, app, user }) => { const roomId1 = await app.client.createRoom({ name: "Music", diff --git a/apps/web/playwright/snapshots/spaces/spaces.spec.ts/space-panel-notification-badge-linux.png b/apps/web/playwright/snapshots/spaces/spaces.spec.ts/space-panel-notification-badge-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..16f16c53d79d921992e27c70e15cddd19dc22bbb GIT binary patch literal 1178 zcmV;L1ZDe)P)A9tE2$Z=pWDLlPn}kVRbs|NaNp-R@w`69~ESVn`uv4+dXFRsO1l&( zDJpxvN4M4~N|MoNgb?C3LPMVrMKKTv@If}P`vuhTL*(5t5TR24K$YpG2Fhf#SS$oV zXt^BN26#%s8LvW+KvO3>grBdA;Sp=|4LAulzYW#d0@b6Xa^2wWI{ zZU?%}y>t%*(3;^YCwsrR`pSos=sU3D6RT@AJnTaVpz}W6rdmM|W`;QP*}0E)9TRyG zsMewq`R(S*y||PHyb}WuZc*-->0Cw}=;5(dkRSC0iF*nu2G;@C{mZPDIQ~XQ+q+$J zBETYb^2+kiKu@u%`^a7Jo{IO0u1|kH@lNNp2?XY-v5OP9WDAy0yA$L`5Sf2Fjc3o~ zFvVtRq+bXP&r~{aNz-%;1onewcgs}p#vU*O#NPpVgo2Xz8{Fu%)^lP>-6D5g=99a! zD*$Tuatg$%G9X7UDhA@)w>l^~$^GKLC`0J0?-eK*N5Osb>fq~MYJi zUE9PN!!bo!Uu(>4dJ$I*1_O2op!u)pZ>@bi$2+#Jyk*O};fhsaXBQmmHx2blB+1%} zinrDhqV?*yX4|l9A(`qLf%7`YQVC(3QO)ea1|r zG(=cwh_KQSVWlC$T6hq8GXyD<-pl|s5H@=*NSX3Vb5%juD+@u&WUpEV)IdB^Urmq% zNQDScyW0uWKo3Ic1*W96=AD>Y18VADSAu5xTnbpD<> zQ}g4OzaDw!Ye`Hdi4!v*A#Fdj$+7v4#M!%9(?vWdv^1UeegD^G--w#jKr{s2jke`h z?1}52uU1weNrHG2jhL}!( sTmA(A0RR8qeo@Z=000I_L_t&o0Hy*uyQKV0qyPW_07*qoM6N<$f@p>`WB>pF literal 0 HcmV?d00001 diff --git a/apps/web/test/unit-tests/components/views/settings/notifications/__snapshots__/Notifications2-test.tsx.snap b/apps/web/test/unit-tests/components/views/settings/notifications/__snapshots__/Notifications2-test.tsx.snap index 9ec5bbd968..167b3b3fdf 100644 --- a/apps/web/test/unit-tests/components/views/settings/notifications/__snapshots__/Notifications2-test.tsx.snap +++ b/apps/web/test/unit-tests/components/views/settings/notifications/__snapshots__/Notifications2-test.tsx.snap @@ -640,13 +640,13 @@ exports[` correctly handles the loading/disabled state 1`] = ` Show a badge
1 @@ -1658,13 +1658,13 @@ exports[` matches the snapshot 1`] = ` Show a badge
1 diff --git a/apps/web/test/unit-tests/components/views/spaces/__snapshots__/SpaceTreeLevel-test.tsx.snap b/apps/web/test/unit-tests/components/views/spaces/__snapshots__/SpaceTreeLevel-test.tsx.snap index 6f9a846f1d..9710e8fae7 100644 --- a/apps/web/test/unit-tests/components/views/spaces/__snapshots__/SpaceTreeLevel-test.tsx.snap +++ b/apps/web/test/unit-tests/components/views/spaces/__snapshots__/SpaceTreeLevel-test.tsx.snap @@ -27,7 +27,7 @@ exports[`SpaceButton metaspace should render notificationState if one is provide > @@ -117,13 +117,13 @@ exports[`ThreadsActivityCentre renders notifications matching the snapshot 1`] = />
@@ -231,13 +231,13 @@ exports[`ThreadsActivityCentre should order the room with the same notification />
@@ -282,13 +282,13 @@ exports[`ThreadsActivityCentre should order the room with the same notification />
@@ -333,13 +333,13 @@ exports[`ThreadsActivityCentre should order the room with the same notification />
diff --git a/packages/shared-components/src/notifications/NotificationBadgeView/NotificationBadgeView.module.css b/packages/shared-components/src/notifications/NotificationBadgeView/NotificationBadgeView.module.css index 158bae064b..a7e72b0b27 100644 --- a/packages/shared-components/src/notifications/NotificationBadgeView/NotificationBadgeView.module.css +++ b/packages/shared-components/src/notifications/NotificationBadgeView/NotificationBadgeView.module.css @@ -6,7 +6,8 @@ */ .notificationBadge { - box-sizing: border-box; + /* App-side badge borders should sit outside the fixed badge size. */ + box-sizing: content-box; padding: 0; border: 0; font: inherit;