diff --git a/frontend/src/lib/components/TranscriptionReadView.svelte.test.ts b/frontend/src/lib/components/TranscriptionReadView.svelte.test.ts index 5b849ed7..31e62d47 100644 --- a/frontend/src/lib/components/TranscriptionReadView.svelte.test.ts +++ b/frontend/src/lib/components/TranscriptionReadView.svelte.test.ts @@ -280,12 +280,13 @@ describe('TranscriptionReadView — person-mention rendering', () => { const link = document.querySelector('a.person-mention')!; link.dispatchEvent(new MouseEvent('mouseenter', { bubbles: true })); - await new Promise((r) => setTimeout(r, 10)); - const personFetches = fetchMock.mock.calls.filter((c) => - String(c[0]).includes(`/api/persons/${PERSON_ID}`) - ); - expect(personFetches.length).toBeGreaterThanOrEqual(1); + await vi.waitFor(() => { + const personFetches = fetchMock.mock.calls.filter((c) => + String(c[0]).includes(`/api/persons/${PERSON_ID}`) + ); + expect(personFetches.length).toBeGreaterThanOrEqual(1); + }); }); it('deduplicates fetches for the same personId across multiple mouseenter events (B15.5)', async () => { @@ -308,12 +309,12 @@ describe('TranscriptionReadView — person-mention rendering', () => { // Plus a re-hover on the first links[0].dispatchEvent(new MouseEvent('mouseenter', { bubbles: true })); - await new Promise((r) => setTimeout(r, 10)); - - const personFetches = fetchMock.mock.calls.filter( - (c) => String(c[0]) === `/api/persons/${PERSON_ID}` - ); - expect(personFetches.length).toBe(1); + await vi.waitFor(() => { + const personFetches = fetchMock.mock.calls.filter( + (c) => String(c[0]) === `/api/persons/${PERSON_ID}` + ); + expect(personFetches.length).toBe(1); + }); }); it('mounts the hover card on mouseenter when the fetch loads', async () => { @@ -349,9 +350,10 @@ describe('TranscriptionReadView — person-mention rendering', () => { const link = document.querySelector('a.person-mention')!; link.dispatchEvent(new MouseEvent('mouseenter', { bubbles: true })); - await new Promise((r) => setTimeout(r, 50)); - const card = document.querySelector('[data-testid="person-hover-card"]'); - expect(card).not.toBeNull(); + await vi.waitFor(() => { + const card = document.querySelector('[data-testid="person-hover-card"]'); + expect(card).not.toBeNull(); + }); }); it('unmounts the hover card on mouseleave', async () => { @@ -362,12 +364,12 @@ describe('TranscriptionReadView — person-mention rendering', () => { const link = document.querySelector('a.person-mention')!; link.dispatchEvent(new MouseEvent('mouseenter', { bubbles: true })); - await new Promise((r) => setTimeout(r, 5)); link.dispatchEvent(new MouseEvent('mouseleave', { bubbles: true })); - await new Promise((r) => setTimeout(r, 5)); - const card = document.querySelector('[data-testid="person-hover-card"]'); - expect(card).toBeNull(); + await vi.waitFor(() => { + const card = document.querySelector('[data-testid="person-hover-card"]'); + expect(card).toBeNull(); + }); }); it('mounts the hover card on focusin so keyboard users see the preview (WCAG 2.1.1)', async () => { @@ -468,13 +470,15 @@ describe('TranscriptionReadView — person-mention rendering', () => { const link = document.querySelector('a.person-mention')!; link.dispatchEvent(new MouseEvent('mouseenter', { bubbles: true })); - await new Promise((r) => setTimeout(r, 50)); + + await vi.waitFor(() => { + // Anchor is marked as deleted so subsequent hovers/clicks treat it as plain text + const stillLink = document.querySelector('a.person-mention')!; + expect(stillLink.getAttribute('data-person-deleted')).toBe('true'); + }); // 404 → no card mounted const card = document.querySelector('[data-testid="person-hover-card"]'); expect(card).toBeNull(); - // Anchor is marked as deleted so subsequent hovers/clicks treat it as plain text - const stillLink = document.querySelector('a.person-mention')!; - expect(stillLink.getAttribute('data-person-deleted')).toBe('true'); }); });