test(discussion): atomically clear mention searchbox to kill CI flake
Some checks failed
CI / Unit & Component Tests (pull_request) Successful in 3m21s
CI / OCR Service Tests (pull_request) Successful in 21s
CI / fail2ban Regex (pull_request) Has been cancelled
CI / Semgrep Security Scan (pull_request) Has been cancelled
CI / Compose Bucket Idempotency (pull_request) Has been cancelled
CI / Backend Unit Tests (pull_request) Has been cancelled
Some checks failed
CI / Unit & Component Tests (pull_request) Successful in 3m21s
CI / OCR Service Tests (pull_request) Successful in 21s
CI / fail2ban Regex (pull_request) Has been cancelled
CI / Semgrep Security Scan (pull_request) Has been cancelled
CI / Compose Bucket Idempotency (pull_request) Has been cancelled
CI / Backend Unit Tests (pull_request) Has been cancelled
userEvent.clear deletes per-keystroke, so intermediate values 'Au'/'A'
transit through the bound searchQuery and each schedules a debounced
fetch. When CI keystroke jitter exceeds SEARCH_DEBOUNCE_MS (150 ms), an
intermediate timer fires before the input reaches '' and the count
assertion sees a phantom q=Au call. fill('') drops a single input event
so the empty-query branch wins deterministically — same pattern this
test file already uses for fill('Walter').
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -283,7 +283,15 @@ describe('PersonMentionEditor — AC-2/3: search input drives fetch', () => {
|
||||
|
||||
const fetchesBeforeClear = fetchMock.mock.calls.length;
|
||||
|
||||
await userEvent.clear(page.getByRole('searchbox'));
|
||||
// `fill('')` atomically sets the input value in a single input event —
|
||||
// same rationale as the `fill('Walter')` call above. `userEvent.clear`
|
||||
// deletes per-keystroke, so intermediate values 'Au'/'A' transit through
|
||||
// the bound `searchQuery` and each schedules a debounced fetch. Under
|
||||
// CI-runner jitter, if two consecutive keystrokes land more than
|
||||
// SEARCH_DEBOUNCE_MS (150 ms) apart, an intermediate timer fires before
|
||||
// the input reaches '' and adds a phantom call — unrelated to the
|
||||
// contract under test, which is "empty query => no fetch".
|
||||
await page.getByRole('searchbox').fill('');
|
||||
|
||||
// Negative assertion: wait past the debounce window to confirm no
|
||||
// trailing fetch was scheduled. Removing this wait would mask a
|
||||
|
||||
Reference in New Issue
Block a user