test(document): rewrite FileSwitcherStrip test with behavioral assertions
Replaces 3 setTimeout sleeps with vi.waitFor on document.activeElement during keyboard nav, and converts 2 .not.toThrow smoke tests on the prev/next buttons into no-op assertions: with a single file in the strip the active chip stays selected and onSelect is not invoked. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -120,36 +120,43 @@ describe('FileSwitcherStrip', () => {
|
|||||||
expect(announcer?.textContent).toContain('Ein Brief.pdf');
|
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, {
|
render(FileSwitcherStrip, {
|
||||||
props: {
|
props: {
|
||||||
files: [makeEntry('f1', 'A.pdf')],
|
files: [makeEntry('f1', 'A.pdf')],
|
||||||
activeId: 'f1',
|
activeId: 'f1',
|
||||||
onSelect: () => {},
|
onSelect,
|
||||||
onRemove: () => {}
|
onRemove: () => {}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const prevBtn = Array.from(document.querySelectorAll('button')).find((b) =>
|
await page.getByRole('button', { name: /vorherige datei/i }).click();
|
||||||
/vorherige|prev/i.test(b.getAttribute('aria-label') ?? '')
|
|
||||||
) as HTMLButtonElement;
|
// The active chip is still f1 and onSelect was not invoked with a different id.
|
||||||
expect(() => prevBtn.click()).not.toThrow();
|
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, {
|
render(FileSwitcherStrip, {
|
||||||
props: {
|
props: {
|
||||||
files: [makeEntry('f1', 'A.pdf')],
|
files: [makeEntry('f1', 'A.pdf')],
|
||||||
activeId: 'f1',
|
activeId: 'f1',
|
||||||
onSelect: () => {},
|
onSelect,
|
||||||
onRemove: () => {}
|
onRemove: () => {}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const nextBtn = Array.from(document.querySelectorAll('button')).find((b) =>
|
await page.getByRole('button', { name: /nächste datei/i }).click();
|
||||||
/nächste|next/i.test(b.getAttribute('aria-label') ?? '')
|
|
||||||
) as HTMLButtonElement;
|
expect(document.querySelector('[data-chip-id="f1"]')?.getAttribute('aria-current')).toBe(
|
||||||
expect(() => nextBtn.click()).not.toThrow();
|
'true'
|
||||||
|
);
|
||||||
|
expect(onSelect).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('navigates with ArrowRight key on focused chip', async () => {
|
it('navigates with ArrowRight key on focused chip', async () => {
|
||||||
@@ -166,8 +173,9 @@ describe('FileSwitcherStrip', () => {
|
|||||||
f1.focus();
|
f1.focus();
|
||||||
f1.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight', bubbles: true }));
|
f1.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight', bubbles: true }));
|
||||||
|
|
||||||
await new Promise((r) => setTimeout(r, 30));
|
await vi.waitFor(() => {
|
||||||
expect(document.activeElement?.getAttribute('data-chip-id')).toBe('f2');
|
expect(document.activeElement?.getAttribute('data-chip-id')).toBe('f2');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('navigates with ArrowLeft key on focused chip (wraps around)', async () => {
|
it('navigates with ArrowLeft key on focused chip (wraps around)', async () => {
|
||||||
@@ -184,9 +192,10 @@ describe('FileSwitcherStrip', () => {
|
|||||||
f1.focus();
|
f1.focus();
|
||||||
f1.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowLeft', bubbles: true }));
|
f1.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowLeft', bubbles: true }));
|
||||||
|
|
||||||
await new Promise((r) => setTimeout(r, 30));
|
await vi.waitFor(() => {
|
||||||
// ArrowLeft from index 0 wraps to last (f2)
|
// ArrowLeft from index 0 wraps to last (f2).
|
||||||
expect(document.activeElement?.getAttribute('data-chip-id')).toBe('f2');
|
expect(document.activeElement?.getAttribute('data-chip-id')).toBe('f2');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('ArrowDown is treated as ArrowRight (vertical key alias)', async () => {
|
it('ArrowDown is treated as ArrowRight (vertical key alias)', async () => {
|
||||||
@@ -203,7 +212,8 @@ describe('FileSwitcherStrip', () => {
|
|||||||
f1.focus();
|
f1.focus();
|
||||||
f1.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true }));
|
f1.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true }));
|
||||||
|
|
||||||
await new Promise((r) => setTimeout(r, 30));
|
await vi.waitFor(() => {
|
||||||
expect(document.activeElement?.getAttribute('data-chip-id')).toBe('f2');
|
expect(document.activeElement?.getAttribute('data-chip-id')).toBe('f2');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user