test(tag-input): rename waitForDebounce to waitForFetch and reduce to 50ms

fetchSuggestions has no debounce; the wait is purely for the async mock to
resolve. The old name implied semantics that don't exist and added ~4.5s to
the suite (13 uses × 350ms).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-17 12:11:54 +02:00
parent 1b617aa08b
commit 6b7829d5c8

View File

@@ -3,7 +3,7 @@ import { cleanup, render } from 'vitest-browser-svelte';
import { page, userEvent } from 'vitest/browser';
import TagInput, { type Tag } from './TagInput.svelte';
const waitForDebounce = () => new Promise((r) => setTimeout(r, 350));
const waitForFetch = () => new Promise((r) => setTimeout(r, 50));
const tick = () => new Promise((r) => setTimeout(r, 0));
function mockFetchWithTagObjects(tags: Tag[]) {
@@ -168,7 +168,7 @@ describe('TagInput autocomplete', () => {
render(TagInput, { tags: [], allowCreation: true });
const input = page.getByRole('textbox');
await input.fill('Fa');
await waitForDebounce();
await waitForFetch();
await expect.element(page.getByRole('option', { name: 'Familie' })).toBeInTheDocument();
await expect.element(page.getByRole('option', { name: 'Freunde' })).toBeInTheDocument();
await page.screenshot({ path: 'test-results/screenshots/tag-input-suggestions.png' });
@@ -179,7 +179,7 @@ describe('TagInput autocomplete', () => {
render(TagInput, { tags: [], allowCreation: true });
const input = page.getByRole('textbox');
await input.fill('F');
await waitForDebounce();
await waitForFetch();
expect(fetch).not.toHaveBeenCalled();
});
@@ -188,7 +188,7 @@ describe('TagInput autocomplete', () => {
render(TagInput, { tags: [{ name: 'Familie' }], allowCreation: true });
const input = page.getByRole('textbox');
await input.fill('Fr');
await waitForDebounce();
await waitForFetch();
await expect.element(page.getByRole('option', { name: 'Familie' })).not.toBeInTheDocument();
await expect.element(page.getByRole('option', { name: 'Freunde' })).toBeInTheDocument();
});
@@ -198,7 +198,7 @@ describe('TagInput autocomplete', () => {
render(TagInput, { tags: [], allowCreation: true });
const input = page.getByRole('textbox');
await input.fill('Fa');
await waitForDebounce();
await waitForFetch();
document.querySelector<HTMLElement>('[role="option"]')!.click();
await tick();
await expect.element(page.getByText('Familie')).toBeInTheDocument();
@@ -211,7 +211,7 @@ describe('TagInput autocomplete', () => {
render(TagInput, { tags: [], allowCreation: true });
const input = page.getByRole('textbox');
await input.fill('__');
await waitForDebounce();
await waitForFetch();
await userEvent.keyboard('{ArrowDown}'); // index 0 → Aachen
await userEvent.keyboard('{ArrowDown}'); // index 1 → Berlin
await userEvent.keyboard('{Enter}');
@@ -223,7 +223,7 @@ describe('TagInput autocomplete', () => {
render(TagInput, { tags: [], allowCreation: true });
const input = page.getByRole('textbox');
await input.fill('Fa');
await waitForDebounce();
await waitForFetch();
await expect.element(page.getByRole('option', { name: 'Familie' })).toBeInTheDocument();
document.body.click();
await tick();
@@ -238,7 +238,7 @@ describe('TagInput autocomplete', () => {
render(TagInput, { tags: [], allowCreation: true });
const input = page.getByRole('textbox');
await input.fill('El');
await waitForDebounce();
await waitForFetch();
const options = Array.from(document.querySelectorAll('[role="option"]'));
const texts = options.map((el) => el.textContent?.replace(//g, '').trim() ?? '');
expect(texts.indexOf('Eltern')).toBeLessThan(texts.indexOf('Kind'));
@@ -252,7 +252,7 @@ describe('TagInput autocomplete', () => {
render(TagInput, { tags: [], allowCreation: true });
const input = page.getByRole('textbox');
await input.fill('Fa');
await waitForDebounce();
await waitForFetch();
await expect.element(page.getByRole('listbox')).toBeInTheDocument();
});
});
@@ -269,7 +269,7 @@ describe('TagInput tree-aware ordering', () => {
render(TagInput, { tags: [], allowCreation: true });
const input = page.getByRole('textbox');
await input.fill('Brief');
await waitForDebounce();
await waitForFetch();
const options = Array.from(document.querySelectorAll('[role="option"]'));
const texts = options.map((el) => el.textContent?.replace(//g, '').trim() ?? '');
expect(texts).toContain('Briefe');
@@ -287,7 +287,7 @@ describe('TagInput tree-aware ordering', () => {
render(TagInput, { tags: [], allowCreation: true });
const input = page.getByRole('textbox');
await input.fill('Hochzeit');
await waitForDebounce();
await waitForFetch();
const options = Array.from(document.querySelectorAll('[role="option"]'));
const texts = options.map((el) => el.textContent?.replace(//g, '').trim() ?? '');
expect(texts.indexOf('Briefe')).toBeLessThan(texts.indexOf('Hochzeit'));
@@ -305,7 +305,7 @@ describe('TagInput tree-aware ordering', () => {
render(TagInput, { tags: [], allowCreation: true });
const input = page.getByRole('textbox');
await input.fill('Hochzeit');
await waitForDebounce();
await waitForFetch();
await userEvent.keyboard('{ArrowDown}'); // first item: Briefe (context ancestor)
await userEvent.keyboard('{Enter}');
// successful add clears the input; if .tag unwrap is missing, addTag returns early
@@ -320,7 +320,7 @@ describe('TagInput tree-aware ordering', () => {
render(TagInput, { tags: [{ id: 'p1', name: 'Briefe' }], allowCreation: true });
const input = page.getByRole('textbox');
await input.fill('Fa');
await waitForDebounce();
await waitForFetch();
await expect.element(page.getByRole('option', { name: 'Familienbriefe' })).toBeInTheDocument();
// the already-selected parent must not appear as a suggestion
const optionNames = Array.from(document.querySelectorAll('[role="option"]')).map(
@@ -356,7 +356,7 @@ describe('TagInput onTextInput callback', () => {
render(TagInput, { tags: [], allowCreation: false, onTextInput });
const input = page.getByRole('textbox');
await input.fill('Ka');
await waitForDebounce();
await waitForFetch();
const option = page.getByRole('option', { name: 'Kaufvertrag' });
await option.click();
await expect.poll(() => onTextInput.mock.calls.at(-1)).toEqual(['']);