From bbb804848cb3dd7bad8ba8370830abe64a19b271 Mon Sep 17 00:00:00 2001 From: Valentin Millet Date: Fri, 18 Sep 2026 12:36:53 +0200 Subject: [PATCH] Draw every row of a todo list inside the card that holds it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Growing a row to 24px in #176 pushed the list past the 53 pixels a card leaves it, and .card-items is anchored to the bottom with overflow hidden — so the first row was drawn nine pixels above its own box and cut in half. Measured before anything was touched, and again after. The card does not get taller. folders/board.rs carries CARD_HEIGHT = 150 and every zone frame is computed from it, so raising it crosses the bridge and leaves boards that already exist with zones a row's worth too short. The fourteen pixels come back instead. "+N autres" moves onto the progress line, beside the count that already states the total: nothing disappears, the card does not move, the bridge is untouched. And the assertion that was missing. The suite checked both rows were in the DOM and that the badge agreed, and both passed the whole time the row was cut — neither asks whether a row is drawn inside its container. Co-Authored-By: Claude Opus 5 --- e2e/pageobjects/canvas.page.ts | 27 +++++++++++++++++++ e2e/specs/07-checklists.e2e.ts | 17 +++++++++++- .../canvas/note-card/note-card.component.html | 12 +++++---- .../canvas/note-card/note-card.component.scss | 7 ++--- .../note-card/note-card.component.spec.ts | 2 +- 5 files changed, 55 insertions(+), 10 deletions(-) diff --git a/e2e/pageobjects/canvas.page.ts b/e2e/pageobjects/canvas.page.ts index 3790414..347b728 100644 --- a/e2e/pageobjects/canvas.page.ts +++ b/e2e/pageobjects/canvas.page.ts @@ -137,6 +137,33 @@ export const canvas = { ); }, + /** + * How far each todo row is drawn **outside** the box that holds it, in pixels. ⚠️ Counting + * the rows in the DOM is not the same question: `.card-items` is `overflow: hidden` and + * anchored to the bottom, so a row that no longer fits is still there and simply gets cut + * off the top. + */ + rowOverflow(title: string): Promise { + return browser.execute( + (cardSelector: string, titleSelector: string, rowSelector: string, wanted: string) => { + const shell = [...document.querySelectorAll(cardSelector)].find( + (each) => (each.querySelector(titleSelector)?.textContent ?? '').trim() === wanted, + ); + const list = shell?.querySelector('.card-items')?.getBoundingClientRect(); + if (!list) return null; + + return [...(shell?.querySelectorAll(rowSelector) ?? [])].map((row) => { + const box = row.getBoundingClientRect(); + return Math.max(0, Math.round(list.top - box.top), Math.round(box.bottom - list.bottom)); + }); + }, + testid('note-card'), + testid('note-card-title'), + testid('note-card-item'), + title, + ); + }, + async waitForCard(title: string): Promise { await browser.waitUntil(async () => (await canvas.titles()).includes(title), { timeout: 15_000, diff --git a/e2e/specs/07-checklists.e2e.ts b/e2e/specs/07-checklists.e2e.ts index fa23685..dc5d8c8 100644 --- a/e2e/specs/07-checklists.e2e.ts +++ b/e2e/specs/07-checklists.e2e.ts @@ -145,6 +145,21 @@ describe('Todo lists', () => { expect(smallest.filter(([, side]) => side < 24)).toEqual([]); }); + /** + * ⚠️ The assertion #176 needed and did not have. Growing a row to 24px pushed the list past + * the 53px it gets inside a 150px card, and `.card-items` is anchored to the bottom — so + * the first row was drawn nine pixels above its own box and cut in half. Counting the rows + * and checking the badge both passed the whole time. + */ + it('draws every row it shows inside the box that holds them', async () => { + await canvas.waitForCard(title); + const overflow = await canvas.rowOverflow(title); + + expect(overflow).not.toBeNull(); + expect(overflow?.length).toBeGreaterThan(0); + expect(overflow).toEqual(overflow?.map(() => 0)); + }); + it('still shows the items it counts, rather than clipping one', async () => { const card = await canvas.cardWithTitle(title); const shown = (await card.$$(testid('note-card-item')).getElements()).length; @@ -153,7 +168,7 @@ describe('Todo lists', () => { // Two on a card, and the badge accounts for exactly the rest. expect(shown).toBe(Math.min(2, total)); if (total > shown) { - expect(await card.$('.card-items-more').getText()).toContain(String(total - shown)); + expect(await card.$(testid('note-card-more')).getText()).toContain(String(total - shown)); } }); diff --git a/src/app/notes/canvas/note-card/note-card.component.html b/src/app/notes/canvas/note-card/note-card.component.html index 497f470..2843b12 100644 --- a/src/app/notes/canvas/note-card/note-card.component.html +++ b/src/app/notes/canvas/note-card/note-card.component.html @@ -70,6 +70,13 @@ {{ 'notes.checklistProgress' | transloco: { done: progress().done, total: progress().total } }} + + @if (hiddenItemCount() > 0) { + + {{ 'notes.checklistMore' | transloco: { count: hiddenItemCount() } }} + + }