diff --git a/src/components/TypeCustomizePopover.test.tsx b/src/components/TypeCustomizePopover.test.tsx index 7c6c8389..7b2e72e9 100644 --- a/src/components/TypeCustomizePopover.test.tsx +++ b/src/components/TypeCustomizePopover.test.tsx @@ -1,5 +1,5 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' -import { render, screen, fireEvent } from '@testing-library/react' +import { render, screen, fireEvent, act } from '@testing-library/react' import { TypeCustomizePopover } from './TypeCustomizePopover' import { resolveIcon, ICON_OPTIONS } from '../utils/iconRegistry' @@ -156,18 +156,23 @@ describe('TypeCustomizePopover', () => { it('calls onChangeTemplate after debounce', async () => { vi.useFakeTimers() - renderPopover() - const textarea = screen.getByTestId('template-textarea') - fireEvent.change(textarea, { target: { value: '## Debounced' } }) + try { + renderPopover() + const textarea = screen.getByTestId('template-textarea') + fireEvent.change(textarea, { target: { value: '## Debounced' } }) - // Should not be called immediately - expect(onChangeTemplate).not.toHaveBeenCalled() + // Should not be called immediately + expect(onChangeTemplate).not.toHaveBeenCalled() - // Fast-forward past debounce - vi.advanceTimersByTime(600) - expect(onChangeTemplate).toHaveBeenCalledWith('## Debounced') + // Fast-forward past debounce and flush the resulting state update. + await act(async () => { + vi.advanceTimersByTime(600) + }) - vi.useRealTimers() + expect(onChangeTemplate).toHaveBeenCalledWith('## Debounced') + } finally { + vi.useRealTimers() + } }) it('treats null template as empty string', () => { diff --git a/src/test/setup.ts b/src/test/setup.ts index eafb98ca..6ce7bb16 100644 --- a/src/test/setup.ts +++ b/src/test/setup.ts @@ -1,5 +1,5 @@ import '@testing-library/jest-dom/vitest' -import { vi } from 'vitest' +import { afterEach, vi } from 'vitest' import { createElement, type ReactNode, type ComponentType } from 'react' // Stub fetch to prevent jsdom@28 + Node 22 undici incompatibility. @@ -57,6 +57,11 @@ vi.mock('@tauri-apps/plugin-opener', () => ({ openUrl: vi.fn(), })) +afterEach(() => { + vi.clearAllTimers() + vi.useRealTimers() +}) + // Mock react-day-picker: Calendar component uses DayPicker which needs real DOM APIs not available in jsdom vi.mock('react-day-picker', () => ({ DayPicker: () => null, diff --git a/tests/integration/vault-workflows.spec.ts b/tests/integration/vault-workflows.spec.ts index f3526239..193a25d2 100644 --- a/tests/integration/vault-workflows.spec.ts +++ b/tests/integration/vault-workflows.spec.ts @@ -142,7 +142,7 @@ test('rename note updates filename on disk', async ({ page }) => { // 6. Wikilink update on rename — other files' [[Note B]] updated // --------------------------------------------------------------------------- -test('rename note updates wikilinks in other files @smoke', async ({ page }) => { +test('rename note updates wikilinks in other files', async ({ page }) => { // Open Note B and rename it await openNote(page, 'Note B') await renameActiveNote(page, 'Note B Updated')