Lexical: Added some test coverage for shortcut handling

Updates existing keydown test helper to accept other event options.
This commit is contained in:
Dan Brown
2026-05-06 00:25:43 +01:00
parent b794f749dd
commit d6b114de74
2 changed files with 103 additions and 3 deletions

View File

@@ -837,22 +837,31 @@ function formatHtml(s: string): string {
return s.replace(/>\s+</g, '><').replace(/\s*\n\s*/g, ' ').trim();
}
export function dispatchKeydownEventForNode(node: LexicalNode, editor: LexicalEditor, key: string) {
interface TestKeyboardEventOptions {
ctrlKey?: boolean;
altKey?: boolean;
shiftKey?: boolean;
metaKey?: boolean;
keyCode?: number;
}
export function dispatchKeydownEventForNode(node: LexicalNode, editor: LexicalEditor, key: string, options: TestKeyboardEventOptions = {}) {
const nodeDomEl = editor.getElementByKey(node.getKey());
const event = new KeyboardEvent('keydown', {
bubbles: true,
cancelable: true,
key,
...options,
});
nodeDomEl?.dispatchEvent(event);
editor.commitUpdates();
}
export function dispatchKeydownEventForSelectedNode(editor: LexicalEditor, key: string) {
export function dispatchKeydownEventForSelectedNode(editor: LexicalEditor, key: string, options: TestKeyboardEventOptions = {}) {
editor.getEditorState().read((): void => {
const node = $getSelection()?.getNodes()[0] || null;
if (node) {
dispatchKeydownEventForNode(node, editor, key);
dispatchKeydownEventForNode(node, editor, key, options);
}
});
}

View File

@@ -0,0 +1,91 @@
import {
createTestContext, destroyFromContext,
dispatchKeydownEventForSelectedNode, expectEditorStateJSONPropToEqual,
} from "lexical/__tests__/utils";
import {
$createParagraphNode, $createTextNode,
$getRoot, IS_BOLD, LexicalEditor,
} from "lexical";
import {registerRichText} from "@lexical/rich-text";
import {EditorUiContext} from "../../ui/framework/core";
import {registerShortcuts} from "../shortcuts";
describe('Keyboard-handling service tests', () => {
let context!: EditorUiContext;
let editor!: LexicalEditor;
beforeEach(() => {
context = createTestContext();
editor = context.editor;
registerRichText(editor);
registerShortcuts(context, true);
});
afterEach(() => {
destroyFromContext(context);
});
test('Basic block format shortcuts works', () => {
editor.updateAndCommit(() => {
const p = $createParagraphNode();
p.append($createTextNode('Hello World'))
$getRoot().append(p);
p.select();
});
dispatchKeydownEventForSelectedNode(editor, '1', {ctrlKey: true});
expectEditorStateJSONPropToEqual(editor, '0.type', 'heading');
expectEditorStateJSONPropToEqual(editor, '0.tag', 'h2');
dispatchKeydownEventForSelectedNode(editor, '2', {ctrlKey: true});
expectEditorStateJSONPropToEqual(editor, '0.type', 'heading');
expectEditorStateJSONPropToEqual(editor, '0.tag', 'h3');
dispatchKeydownEventForSelectedNode(editor, 'd', {ctrlKey: true});
expectEditorStateJSONPropToEqual(editor, '0.type', 'paragraph');
expectEditorStateJSONPropToEqual(editor, '0.0.text', 'Hello World');
});
test('Basic bold format shortcut works', () => {
editor.updateAndCommit(() => {
const p = $createParagraphNode();
const text = $createTextNode('Hello World');
p.append(text)
$getRoot().append(p);
text.select(0, 5);
});
// Toggle bold for selection
dispatchKeydownEventForSelectedNode(editor, 'b', {ctrlKey: true});
expectEditorStateJSONPropToEqual(editor, '0.0.format', IS_BOLD);
expectEditorStateJSONPropToEqual(editor, '0.1.format', 0);
// Untoggle bold for selection
dispatchKeydownEventForSelectedNode(editor, 'b', {ctrlKey: true});
expectEditorStateJSONPropToEqual(editor, '0.0.format', 0);
});
test('Basic bold format shortcut works when using cyrillic equivalent keys', () => {
editor.updateAndCommit(() => {
const p = $createParagraphNode();
const text = $createTextNode('Hello World');
p.append(text)
$getRoot().append(p);
text.select(0, 5);
});
// Toggle bold for selection
dispatchKeydownEventForSelectedNode(editor, 'и', {ctrlKey: true, keyCode: 66});
expectEditorStateJSONPropToEqual(editor, '0.0.format', IS_BOLD);
expectEditorStateJSONPropToEqual(editor, '0.1.format', 0);
// Untoggle bold for selection
dispatchKeydownEventForSelectedNode(editor, 'и', {ctrlKey: true, keyCode: 66});
expectEditorStateJSONPropToEqual(editor, '0.0.format', 0);
});
});