test(document): expand FileSwitcherStrip coverage
Adds prev/next button click safety, ArrowRight + ArrowLeft + ArrowDown keyboard navigation through chips with wrap-around. 5 new tests covering ~10 branches. Refs #496. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -119,4 +119,91 @@ describe('FileSwitcherStrip', () => {
|
||||
const announcer = document.querySelector('[aria-live="polite"]');
|
||||
expect(announcer?.textContent).toContain('Ein Brief.pdf');
|
||||
});
|
||||
|
||||
it('clicking prev button does not throw with no scroll target available', async () => {
|
||||
render(FileSwitcherStrip, {
|
||||
props: {
|
||||
files: [makeEntry('f1', 'A.pdf')],
|
||||
activeId: 'f1',
|
||||
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();
|
||||
});
|
||||
|
||||
it('clicking next button does not throw', async () => {
|
||||
render(FileSwitcherStrip, {
|
||||
props: {
|
||||
files: [makeEntry('f1', 'A.pdf')],
|
||||
activeId: 'f1',
|
||||
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();
|
||||
});
|
||||
|
||||
it('navigates with ArrowRight key on focused chip', async () => {
|
||||
render(FileSwitcherStrip, {
|
||||
props: {
|
||||
files: [makeEntry('f1', 'A'), makeEntry('f2', 'B'), makeEntry('f3', 'C')],
|
||||
activeId: 'f1',
|
||||
onSelect: () => {},
|
||||
onRemove: () => {}
|
||||
}
|
||||
});
|
||||
|
||||
const f1 = document.querySelector('[data-chip-id="f1"]') as HTMLElement;
|
||||
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');
|
||||
});
|
||||
|
||||
it('navigates with ArrowLeft key on focused chip (wraps around)', async () => {
|
||||
render(FileSwitcherStrip, {
|
||||
props: {
|
||||
files: [makeEntry('f1', 'A'), makeEntry('f2', 'B')],
|
||||
activeId: 'f1',
|
||||
onSelect: () => {},
|
||||
onRemove: () => {}
|
||||
}
|
||||
});
|
||||
|
||||
const f1 = document.querySelector('[data-chip-id="f1"]') as HTMLElement;
|
||||
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');
|
||||
});
|
||||
|
||||
it('ArrowDown is treated as ArrowRight (vertical key alias)', async () => {
|
||||
render(FileSwitcherStrip, {
|
||||
props: {
|
||||
files: [makeEntry('f1', 'A'), makeEntry('f2', 'B')],
|
||||
activeId: 'f1',
|
||||
onSelect: () => {},
|
||||
onRemove: () => {}
|
||||
}
|
||||
});
|
||||
|
||||
const f1 = document.querySelector('[data-chip-id="f1"]') as HTMLElement;
|
||||
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');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user