Kaynağa Gözat

test(search-provider): enhance command palette shortcut and cover Cmd+K

Replace double requestAnimationFrame with vi.waitFor retries before
asserting the palette opens; exercise Ctrl+K and Meta+K via it.each
satnaing 2 ay önce
ebeveyn
işleme
d30e058cf8
1 değiştirilmiş dosya ile 42 ekleme ve 34 silme
  1. 42 34
      src/context/search-provider.test.tsx

+ 42 - 34
src/context/search-provider.test.tsx

@@ -22,34 +22,36 @@ vi.mock('@/context/theme-provider', () => ({
   useTheme: () => ({ setTheme: mocks.setTheme }),
 }))
 
-/**
- * Matches SearchProvider (`metaKey || ctrlKey` + `key === 'k'`).
- * Use real key delivery via `userEvent.keyboard` so the document listener sees a trusted-like sequence (see Vitest browser interactivity).
- */
-async function toggleCommandPaletteShortcut() {
-  await userEvent.keyboard('{Control>}k{/Control}')
-}
-
-async function flushEffects() {
-  await new Promise<void>((resolve) => {
-    requestAnimationFrame(() => {
-      requestAnimationFrame(() => resolve())
-    })
-  })
-}
+type ShortcutModifier = 'Control' | 'Meta'
 
 async function renderWithSearchProvider() {
-  const screen = await render(<SearchProvider>{null}</SearchProvider>)
-  await flushEffects()
-  return screen
+  return await render(<SearchProvider>{null}</SearchProvider>)
 }
 
-async function openCommandPalette(screen: RenderResult) {
-  await toggleCommandPaletteShortcut()
-  await vi.waitFor(() =>
-    expect(
-      screen.getByPlaceholder(COMMAND_MENU_PLACEHOLDER)
-    ).toBeInTheDocument()
+/**
+ * Open the palette by shortcut, retrying while the keydown listener may not be mounted yet.
+ * Waits between attempts so a successful toggle is not immediately undone by a second chord.
+ */
+async function openCommandPalette(
+  screen: RenderResult,
+  modifier: ShortcutModifier = 'Control'
+) {
+  await vi.waitFor(
+    async () => {
+      const isCommandPaletteOpen =
+        document.querySelector(
+          `[placeholder="${COMMAND_MENU_PLACEHOLDER}"]`
+        ) !== null
+
+      if (!isCommandPaletteOpen) {
+        await userEvent.keyboard(`{${modifier}>}k{/${modifier}}`)
+      }
+
+      expect(
+        screen.getByPlaceholder(COMMAND_MENU_PLACEHOLDER)
+      ).toBeInTheDocument()
+    },
+    { interval: 50, timeout: 5000 }
   )
 }
 
@@ -78,19 +80,25 @@ describe('SearchProvider and CommandMenu', () => {
     expect(getByPlaceholder(COMMAND_MENU_PLACEHOLDER)).not.toBeInTheDocument()
   })
 
-  it('opens the command menu when the Cmd/Ctrl + K shortcut is pressed', async () => {
-    const screen = await renderWithSearchProvider()
+  it.each([
+    ['Ctrl', 'Control'],
+    ['Cmd', 'Meta'],
+  ] as const)(
+    'opens the command menu when %s + K is pressed',
+    async (_label, modifier) => {
+      const screen = await renderWithSearchProvider()
 
-    expect(
-      screen.getByPlaceholder(COMMAND_MENU_PLACEHOLDER)
-    ).not.toBeInTheDocument()
+      expect(
+        screen.getByPlaceholder(COMMAND_MENU_PLACEHOLDER)
+      ).not.toBeInTheDocument()
 
-    await openCommandPalette(screen)
+      await openCommandPalette(screen, modifier)
 
-    expect(
-      screen.getByPlaceholder(COMMAND_MENU_PLACEHOLDER)
-    ).toBeInTheDocument()
-  })
+      expect(
+        screen.getByPlaceholder(COMMAND_MENU_PLACEHOLDER)
+      ).toBeInTheDocument()
+    }
+  )
 
   it('navigates to a top-level route and closes the palette when a nav item is selected', async () => {
     const screen = await renderWithSearchProvider()