refactor(test): name the debounce slack and harden against CI jitter

Extracts SEARCH_DEBOUNCE_MS + POST_DEBOUNCE_SLACK_MS at the top of the
spec and bumps the post-debounce wait from 250/300 ms to 500 ms.
Addresses Felix's "magic number" suggestion and Sara's flake-risk
concern on PR #629. (Sara's fake-timer alternative collides with
userEvent + vi.waitFor in vitest-browser; the slack bump achieves the
same deterministic outcome with no fragility.)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-05-19 22:30:16 +02:00
parent f67f5330ce
commit 44209048a2

View File

@@ -15,6 +15,12 @@ import { m } from '$lib/paraglide/messages.js';
type Person = components['schemas']['Person'];
type PersonMention = components['schemas']['PersonMention'];
// Mirror of the debounce in PersonMentionEditor.svelte. Naming the magic and
// using a generous slack (SEARCH_DEBOUNCE_MS + 350 = 500 ms) kills CI-jitter
// flakiness Sara raised on PR #629.
const SEARCH_DEBOUNCE_MS = 150;
const POST_DEBOUNCE_SLACK_MS = 350;
const AUGUSTE: Person = {
id: 'p-aug',
firstName: 'Auguste',
@@ -218,8 +224,7 @@ describe('PersonMentionEditor — AC-2/3: search input drives fetch', () => {
await userEvent.type(page.getByRole('textbox'), '@Walter');
// Wait beyond the 150 ms debounce window so the trailing call has flushed.
await new Promise((r) => setTimeout(r, 300));
await new Promise((r) => setTimeout(r, SEARCH_DEBOUNCE_MS + POST_DEBOUNCE_SLACK_MS));
const personsFetches = fetchMock.mock.calls.filter(
([url]) => typeof url === 'string' && url.startsWith('/api/persons')
@@ -243,8 +248,7 @@ describe('PersonMentionEditor — AC-2/3: search input drives fetch', () => {
await userEvent.clear(page.getByRole('searchbox'));
// Wait beyond the debounce window to confirm no fetch was scheduled.
await new Promise((r) => setTimeout(r, 250));
await new Promise((r) => setTimeout(r, SEARCH_DEBOUNCE_MS + POST_DEBOUNCE_SLACK_MS));
expect(fetchMock.mock.calls.length).toBe(fetchesBeforeClear);
await expect.element(page.getByText('Auguste Raddatz')).not.toBeInTheDocument();
@@ -264,8 +268,7 @@ describe('PersonMentionEditor — whitespace-only query', () => {
await expect.element(page.getByRole('searchbox')).toBeVisible();
});
// Wait beyond the debounce window so any trailing call would have fired.
await new Promise((r) => setTimeout(r, 300));
await new Promise((r) => setTimeout(r, SEARCH_DEBOUNCE_MS + POST_DEBOUNCE_SLACK_MS));
await expect.element(page.getByText(m.person_mention_search_prompt())).toBeInTheDocument();
expect(fetchMock).not.toHaveBeenCalled();