Files
markdown-converter/tests/component/modals/CommandPalette.test.tsx
T
amitwh f2398e6e1a feat: enhance WelcomeDialog, export dialogs, GitStatusPanel, add CommandPalette, FindReplaceBar, and new converter dialogs
- WelcomeDialog: add quick start, feature showcase, keyboard shortcuts, recent files, version display
- ExportDocxDialog/ExportHtmlDialog/ExportPdfDialog: add header/footer, paper size, margin controls
- GitStatusPanel: full staging/unstaging, discard, commit workflow
- CommandPalette: fuzzy command search with keyboard navigation
- FindReplaceBar: find/replace with regex, case, whole-word options
- New dialogs: BatchMediaConverterDialog, HeaderFooterDialog, PdfEditorDialog, UniversalConverterDialog
- Tests: comprehensive coverage for all new/updated components
2026-06-13 19:34:42 +05:30

91 lines
3.7 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { CommandPalette } from '@/components/modals/CommandPalette';
import { useCommandStore } from '@/stores/command-store';
beforeEach(() => {
localStorage.clear();
useCommandStore.setState({ handlers: {}, userBindings: {} } as any);
useCommandStore.getState().register('file.open', vi.fn());
useCommandStore.getState().register('file.save', vi.fn());
useCommandStore.getState().register('file.new', vi.fn());
useCommandStore.getState().register('file.exportPdf', vi.fn());
useCommandStore.getState().register('settings.open', vi.fn());
});
describe('CommandPalette', () => {
it('does not render when closed', () => {
render(<CommandPalette />);
expect(screen.queryByPlaceholderText(/type a command/i)).not.toBeInTheDocument();
});
it('opens on Ctrl+Shift+P', async () => {
render(<CommandPalette />);
await userEvent.keyboard('{Control>}{Shift>}{p}{/Shift}{/Control}');
expect(screen.getByPlaceholderText(/type a command/i)).toBeInTheDocument();
});
it('closes on Escape', async () => {
render(<CommandPalette />);
await userEvent.keyboard('{Control>}{Shift>}{p}{/Shift}{/Control}');
await waitFor(() => expect(screen.getByPlaceholderText(/type a command/i)).toBeInTheDocument());
const input = screen.getByPlaceholderText(/type a command/i);
await userEvent.type(input, '{Escape}');
expect(screen.queryByPlaceholderText(/type a command/i)).not.toBeInTheDocument();
});
it('filters commands based on query', async () => {
render(<CommandPalette />);
await userEvent.keyboard('{Control>}{Shift>}{p}{/Shift}{/Control}');
const input = screen.getByPlaceholderText(/type a command/i);
await userEvent.type(input, 'open');
const items = screen.getAllByRole('option');
expect(items.length).toBeGreaterThan(0);
items.forEach((item) => {
expect(item.textContent?.toLowerCase()).toContain('open');
});
});
it('navigates with arrow keys', async () => {
render(<CommandPalette />);
await userEvent.keyboard('{Control>}{Shift>}{p}{/Shift}{/Control}');
const input = screen.getByPlaceholderText(/type a command/i);
await userEvent.type(input, '{ArrowDown}{ArrowDown}');
const items = screen.getAllByRole('option');
const selected = items.find((el) => el.getAttribute('aria-selected') === 'true');
expect(selected).toBe(items[2]);
});
it('executes command on Enter', async () => {
const handler = vi.fn();
useCommandStore.getState().register('test.command', handler);
render(<CommandPalette />);
await userEvent.keyboard('{Control>}{Shift>}{p}{/Shift}{/Control}');
const input = screen.getByPlaceholderText(/type a command/i);
await userEvent.type(input, 'test');
await userEvent.keyboard('{Enter}');
expect(handler).toHaveBeenCalled();
});
it('shows no results message for non-matching query', async () => {
render(<CommandPalette />);
await userEvent.keyboard('{Control>}{Shift>}{p}{/Shift}{/Control}');
const input = screen.getByPlaceholderText(/type a command/i);
await userEvent.type(input, 'zzznonexistent');
expect(screen.getByText(/no matching commands/i)).toBeInTheDocument();
});
it('limits results to 8', async () => {
for (let i = 0; i < 20; i++) {
useCommandStore.getState().register(`test.command.${i}`, vi.fn());
}
render(<CommandPalette />);
await userEvent.keyboard('{Control>}{Shift>}{p}{/Shift}{/Control}');
await waitFor(() => {
const items = screen.queryAllByRole('option');
expect(items.length).toBeLessThanOrEqual(8);
});
});
});