test(transcription): polish @mention test docstrings and tighten clip assert
Round-4 polish from Sara (#11199) and Felix (#11186): - Replace setTimeout(50) in stale-response race with tick() — matches round-3 pattern Sara verified in the sticky-takeover test. - Add intent comment above the "clear input" wait — it is a negative assertion that must not be optimised away. - Tighten displayName-clip assert from <=100 to ===100 so the test discriminates "clip works" from "clip works AND nothing weakened it". - JSDoc POST_DEBOUNCE_SLACK_MS with the calibration rationale. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
import { describe, it, expect, vi, afterEach } from 'vitest';
|
import { describe, it, expect, vi, afterEach } from 'vitest';
|
||||||
import { cleanup, render } from 'vitest-browser-svelte';
|
import { cleanup, render } from 'vitest-browser-svelte';
|
||||||
import { page, userEvent } from 'vitest/browser';
|
import { page, userEvent } from 'vitest/browser';
|
||||||
|
import { tick } from 'svelte';
|
||||||
import PersonMentionEditorHost from './PersonMentionEditor.test-fixture.svelte';
|
import PersonMentionEditorHost from './PersonMentionEditor.test-fixture.svelte';
|
||||||
import type { components } from '$lib/generated/api';
|
import type { components } from '$lib/generated/api';
|
||||||
import { m } from '$lib/paraglide/messages.js';
|
import { m } from '$lib/paraglide/messages.js';
|
||||||
@@ -18,7 +19,12 @@ import { SEARCH_DEBOUNCE_MS } from './mentionConstants';
|
|||||||
type Person = components['schemas']['Person'];
|
type Person = components['schemas']['Person'];
|
||||||
type PersonMention = components['schemas']['PersonMention'];
|
type PersonMention = components['schemas']['PersonMention'];
|
||||||
|
|
||||||
// Slack on top of the debounce to absorb CI jitter (total 500 ms is generous).
|
/**
|
||||||
|
* Headroom above SEARCH_DEBOUNCE_MS for the debounce-window wait
|
||||||
|
* assertions in this file. 350 ms is calibrated against CI-runner jitter
|
||||||
|
* we observed pre-#629; dropping it below ~200 ms reintroduces flake.
|
||||||
|
* See PR #629 round-2 review comment #10935 (Sara).
|
||||||
|
*/
|
||||||
const POST_DEBOUNCE_SLACK_MS = 350;
|
const POST_DEBOUNCE_SLACK_MS = 350;
|
||||||
|
|
||||||
const AUGUSTE: Person = {
|
const AUGUSTE: Person = {
|
||||||
@@ -275,6 +281,9 @@ describe('PersonMentionEditor — AC-2/3: search input drives fetch', () => {
|
|||||||
|
|
||||||
await userEvent.clear(page.getByRole('searchbox'));
|
await userEvent.clear(page.getByRole('searchbox'));
|
||||||
|
|
||||||
|
// Negative assertion: wait past the debounce window to confirm no
|
||||||
|
// trailing fetch was scheduled. Removing this wait would mask a
|
||||||
|
// re-introduction of the keystroke-driven items() fetch.
|
||||||
await new Promise((r) => setTimeout(r, SEARCH_DEBOUNCE_MS + POST_DEBOUNCE_SLACK_MS));
|
await new Promise((r) => setTimeout(r, SEARCH_DEBOUNCE_MS + POST_DEBOUNCE_SLACK_MS));
|
||||||
|
|
||||||
expect(fetchMock.mock.calls.length).toBe(fetchesBeforeClear);
|
expect(fetchMock.mock.calls.length).toBe(fetchesBeforeClear);
|
||||||
@@ -332,7 +341,10 @@ describe('PersonMentionEditor — stale-response race', () => {
|
|||||||
|
|
||||||
// The stale fetch now resolves with persons. The dropdown must stay empty.
|
// The stale fetch now resolves with persons. The dropdown must stay empty.
|
||||||
resolveFetch({ ok: true, json: () => Promise.resolve([AUGUSTE]) });
|
resolveFetch({ ok: true, json: () => Promise.resolve([AUGUSTE]) });
|
||||||
await new Promise((r) => setTimeout(r, 50));
|
// Flush pending Svelte reactivity so any (non-)update from the stale
|
||||||
|
// fetch resolution has landed before we assert. expect.element already
|
||||||
|
// polls, so no fixed-timeout fallback is needed. Sara on PR #629 round 4.
|
||||||
|
await tick();
|
||||||
|
|
||||||
await expect.element(page.getByText('Auguste Raddatz')).not.toBeInTheDocument();
|
await expect.element(page.getByText('Auguste Raddatz')).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
@@ -528,7 +540,10 @@ describe('PersonMentionEditor — AC-1: typed text as displayName', () => {
|
|||||||
|
|
||||||
await vi.waitFor(() => {
|
await vi.waitFor(() => {
|
||||||
expect(host.snapshot.mentionedPersons).toHaveLength(1);
|
expect(host.snapshot.mentionedPersons).toHaveLength(1);
|
||||||
expect(host.snapshot.mentionedPersons[0].displayName.length).toBeLessThanOrEqual(100);
|
// Tight assertion: input is 105 chars, cap is exactly 100. Using
|
||||||
|
// `toHaveLength(100)` discriminates "clip works" from "clip works
|
||||||
|
// AND nothing weakened it to e.g. 95". Sara on PR #629 round 4.
|
||||||
|
expect(host.snapshot.mentionedPersons[0].displayName).toHaveLength(100);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user