diff --git a/frontend/src/lib/document/FileSwitcherStrip.svelte.test.ts b/frontend/src/lib/document/FileSwitcherStrip.svelte.test.ts index 3defb75a..7490573c 100644 --- a/frontend/src/lib/document/FileSwitcherStrip.svelte.test.ts +++ b/frontend/src/lib/document/FileSwitcherStrip.svelte.test.ts @@ -120,36 +120,43 @@ describe('FileSwitcherStrip', () => { expect(announcer?.textContent).toContain('Ein Brief.pdf'); }); - it('clicking prev button does not throw with no scroll target available', async () => { + it('prev button on a single-file strip is a no-op (active chip stays)', async () => { + const onSelect = vi.fn(); render(FileSwitcherStrip, { props: { files: [makeEntry('f1', 'A.pdf')], activeId: 'f1', - onSelect: () => {}, + onSelect, onRemove: () => {} } }); - const prevBtn = Array.from(document.querySelectorAll('button')).find((b) => - /vorherige|prev/i.test(b.getAttribute('aria-label') ?? '') - ) as HTMLButtonElement; - expect(() => prevBtn.click()).not.toThrow(); + await page.getByRole('button', { name: /vorherige datei/i }).click(); + + // The active chip is still f1 and onSelect was not invoked with a different id. + expect(document.querySelector('[data-chip-id="f1"]')?.getAttribute('aria-current')).toBe( + 'true' + ); + expect(onSelect).not.toHaveBeenCalled(); }); - it('clicking next button does not throw', async () => { + it('next button on a single-file strip is a no-op (active chip stays)', async () => { + const onSelect = vi.fn(); render(FileSwitcherStrip, { props: { files: [makeEntry('f1', 'A.pdf')], activeId: 'f1', - onSelect: () => {}, + onSelect, onRemove: () => {} } }); - const nextBtn = Array.from(document.querySelectorAll('button')).find((b) => - /nächste|next/i.test(b.getAttribute('aria-label') ?? '') - ) as HTMLButtonElement; - expect(() => nextBtn.click()).not.toThrow(); + await page.getByRole('button', { name: /nächste datei/i }).click(); + + expect(document.querySelector('[data-chip-id="f1"]')?.getAttribute('aria-current')).toBe( + 'true' + ); + expect(onSelect).not.toHaveBeenCalled(); }); it('navigates with ArrowRight key on focused chip', async () => { @@ -166,8 +173,9 @@ describe('FileSwitcherStrip', () => { f1.focus(); f1.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight', bubbles: true })); - await new Promise((r) => setTimeout(r, 30)); - expect(document.activeElement?.getAttribute('data-chip-id')).toBe('f2'); + await vi.waitFor(() => { + expect(document.activeElement?.getAttribute('data-chip-id')).toBe('f2'); + }); }); it('navigates with ArrowLeft key on focused chip (wraps around)', async () => { @@ -184,9 +192,10 @@ describe('FileSwitcherStrip', () => { f1.focus(); f1.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowLeft', bubbles: true })); - await new Promise((r) => setTimeout(r, 30)); - // ArrowLeft from index 0 wraps to last (f2) - expect(document.activeElement?.getAttribute('data-chip-id')).toBe('f2'); + await vi.waitFor(() => { + // ArrowLeft from index 0 wraps to last (f2). + expect(document.activeElement?.getAttribute('data-chip-id')).toBe('f2'); + }); }); it('ArrowDown is treated as ArrowRight (vertical key alias)', async () => { @@ -203,7 +212,8 @@ describe('FileSwitcherStrip', () => { f1.focus(); f1.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true })); - await new Promise((r) => setTimeout(r, 30)); - expect(document.activeElement?.getAttribute('data-chip-id')).toBe('f2'); + await vi.waitFor(() => { + expect(document.activeElement?.getAttribute('data-chip-id')).toBe('f2'); + }); }); });