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() } }} + + }