|
1 | 1 | import { forceParsing } from '@codemirror/language';
|
2 | 2 | import { EditorState } from '@codemirror/state';
|
3 | 3 | import { act, waitFor } from '@testing-library/react';
|
| 4 | +import userEvent from '@testing-library/user-event'; |
4 | 5 |
|
5 | 6 | import { renderCodeEditor } from '../testing/testUtils';
|
6 | 7 |
|
@@ -669,4 +670,135 @@ describe('packages/code-editor', () => {
|
669 | 670 | }
|
670 | 671 | });
|
671 | 672 | });
|
| 673 | + |
| 674 | + describe('Keybindings', () => { |
| 675 | + test('Pressing ESC key unfocuses the editor', async () => { |
| 676 | + const { editor, container } = renderCodeEditor({ |
| 677 | + defaultValue: 'console.log("test");', |
| 678 | + }); |
| 679 | + |
| 680 | + await editor.waitForEditorView(); |
| 681 | + |
| 682 | + // Focus the editor by clicking on the content area |
| 683 | + const contentElement = editor.getBySelector(CodeEditorSelectors.Content); |
| 684 | + userEvent.click(contentElement); |
| 685 | + |
| 686 | + // Verify the editor is focused |
| 687 | + await waitFor(() => { |
| 688 | + expect( |
| 689 | + container.querySelector(CodeEditorSelectors.Focused), |
| 690 | + ).toBeInTheDocument(); |
| 691 | + }); |
| 692 | + |
| 693 | + // Press the ESC key |
| 694 | + userEvent.keyboard('{Escape}'); |
| 695 | + |
| 696 | + // Verify the editor is no longer focused |
| 697 | + await waitFor(() => { |
| 698 | + expect( |
| 699 | + container.querySelector(CodeEditorSelectors.Focused), |
| 700 | + ).not.toBeInTheDocument(); |
| 701 | + }); |
| 702 | + }); |
| 703 | + |
| 704 | + test('Pressing CMD+F brings up the search menu', async () => { |
| 705 | + const { editor, container } = renderCodeEditor({ |
| 706 | + defaultValue: 'console.log("hello world");\nconsole.log("test");', |
| 707 | + }); |
| 708 | + |
| 709 | + await editor.waitForEditorView(); |
| 710 | + |
| 711 | + // Focus the editor first |
| 712 | + const contentElement = editor.getBySelector(CodeEditorSelectors.Content); |
| 713 | + userEvent.click(contentElement); |
| 714 | + |
| 715 | + // Verify editor is focused |
| 716 | + await waitFor(() => { |
| 717 | + expect(container.querySelector('.cm-focused')).toBeInTheDocument(); |
| 718 | + }); |
| 719 | + |
| 720 | + // Press Ctrl+F to open search (works on most platforms) |
| 721 | + userEvent.keyboard('{Control>}f{/Control}'); |
| 722 | + |
| 723 | + // Check if the search panel appears |
| 724 | + await waitFor(() => { |
| 725 | + // CodeMirror 6 search creates a panel with specific classes |
| 726 | + const searchPanel = container.querySelector( |
| 727 | + CodeEditorSelectors.SearchPanel, |
| 728 | + ); |
| 729 | + expect(searchPanel).toBeInTheDocument(); |
| 730 | + }); |
| 731 | + |
| 732 | + // Verify search input field is present and can be typed in |
| 733 | + await waitFor(() => { |
| 734 | + const searchInput = container.querySelector( |
| 735 | + CodeEditorSelectors.SearchInput, |
| 736 | + ); |
| 737 | + expect(searchInput).toBeInTheDocument(); |
| 738 | + }); |
| 739 | + }); |
| 740 | + |
| 741 | + test('Pressing TAB enters correct tab', async () => { |
| 742 | + const { editor } = renderCodeEditor({ |
| 743 | + defaultValue: 'console.log("test");', |
| 744 | + indentUnit: 'tab', |
| 745 | + }); |
| 746 | + |
| 747 | + await editor.waitForEditorView(); |
| 748 | + |
| 749 | + // Focus the editor and position cursor at the start of the line |
| 750 | + const contentElement = editor.getBySelector(CodeEditorSelectors.Content); |
| 751 | + userEvent.click(contentElement); |
| 752 | + |
| 753 | + // Position cursor at the beginning of the line |
| 754 | + userEvent.keyboard('{Home}'); |
| 755 | + |
| 756 | + // Get initial content |
| 757 | + const initialContent = editor.getContent(); |
| 758 | + |
| 759 | + // Press TAB |
| 760 | + userEvent.keyboard('{Tab}'); |
| 761 | + |
| 762 | + // Verify that indentation was inserted |
| 763 | + await waitFor(() => { |
| 764 | + const newContent = editor.getContent(); |
| 765 | + // Should insert a tab character at the beginning |
| 766 | + expect(newContent).toBe('\tconsole.log("test");'); |
| 767 | + expect(newContent).not.toBe(initialContent); |
| 768 | + expect(newContent.length).toBeGreaterThan(initialContent.length); |
| 769 | + }); |
| 770 | + }); |
| 771 | + |
| 772 | + test('Pressing SHIFT+TAB lessens line indentation', async () => { |
| 773 | + const { editor } = renderCodeEditor({ |
| 774 | + defaultValue: '\tconsole.log("test");', // Start with indented content |
| 775 | + indentUnit: 'tab', |
| 776 | + }); |
| 777 | + |
| 778 | + await editor.waitForEditorView(); |
| 779 | + |
| 780 | + // Focus the editor and position cursor on the indented line |
| 781 | + const contentElement = editor.getBySelector(CodeEditorSelectors.Content); |
| 782 | + userEvent.click(contentElement); |
| 783 | + |
| 784 | + // Position cursor at the beginning of the line |
| 785 | + userEvent.keyboard('{Home}'); |
| 786 | + |
| 787 | + // Get initial content (should have tab indentation) |
| 788 | + const initialContent = editor.getContent(); |
| 789 | + expect(initialContent).toBe('\tconsole.log("test");'); |
| 790 | + |
| 791 | + // Press SHIFT+TAB to reduce indentation |
| 792 | + userEvent.keyboard('{Shift>}{Tab}{/Shift}'); |
| 793 | + |
| 794 | + // Verify that indentation was reduced |
| 795 | + await waitFor(() => { |
| 796 | + const newContent = editor.getContent(); |
| 797 | + // Should remove the tab indentation |
| 798 | + expect(newContent).toBe('console.log("test");'); |
| 799 | + expect(newContent).not.toBe(initialContent); |
| 800 | + expect(newContent.length).toBeLessThan(initialContent.length); |
| 801 | + }); |
| 802 | + }); |
| 803 | + }); |
672 | 804 | });
|
0 commit comments