Pop-up dictionary browser extension for language learning. Successor to Yomichan. (PERSONAL FORK)
at lambda-fork/main 104 lines 4.7 kB view raw
1/* 2 * Copyright (C) 2023-2025 Yomitan Authors 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <https://www.gnu.org/licenses/>. 16 */ 17 18import {describe, expect, afterAll, test, vi} from 'vitest'; 19import {setupDomTest} from './fixtures/dom-test.js'; 20import {querySelectorNotNull} from '../ext/js/dom/query-selector.js'; 21import {SearchDisplayController} from '../ext/js/display/search-display-controller.js'; 22import {Display} from '../ext/js/display/display.js'; 23import {DisplayAudio} from '../ext/js/display/display-audio.js'; 24import {SearchPersistentStateController} from '../ext/js/display/search-persistent-state-controller.js'; 25import {Application} from '../ext/js/application.js'; 26import {CrossFrameAPI} from '../ext/js/comm/cross-frame-api.js'; 27import {API} from '../ext/js/comm/api.js'; 28import {DocumentFocusController} from '../ext/js/dom/document-focus-controller.js'; 29import {HotkeyHandler} from '../ext/js/input/hotkey-handler.js'; 30import {WebExtension} from '../ext/js/extension/web-extension.js'; 31 32const documentSearchDisplayControllerEnv = await setupDomTest('ext/search.html'); 33 34const {window, teardown} = documentSearchDisplayControllerEnv; 35 36const {document} = window; 37 38const frameId = 1; 39const tabId = 1; 40const webExtension = new WebExtension(); 41const hotkeyHandler = new HotkeyHandler(); 42const documentFocusController = new DocumentFocusController(); 43const displayPageType = 'search'; 44const api = new API(webExtension); 45const crossFrameAPI = new CrossFrameAPI(api, tabId, frameId); 46const application = new Application(api, crossFrameAPI); 47const display = new Display(application, displayPageType, documentFocusController, hotkeyHandler); 48const displayAudio = new DisplayAudio(display); 49const searchPersistentStateController = new SearchPersistentStateController(); 50 51const searchDisplayController = new SearchDisplayController(display, displayAudio, searchPersistentStateController); 52 53// eslint-disable-next-line no-underscore-dangle 54const onKeyDownMethod = searchDisplayController._onKeyDown.bind(searchDisplayController); 55 56/** 57 * @type {HTMLInputElement} 58 */ 59const queryInput = querySelectorNotNull(document, '#search-textbox'); 60 61const focusSpy = vi.spyOn(queryInput, 'focus'); 62 63describe('Keyboard Event Handling', () => { 64 afterAll(() => teardown(global)); 65 66 const validKeypressEvents = [ 67 new KeyboardEvent('keydown', {key: 'a', ctrlKey: false, metaKey: false, altKey: false}), 68 new KeyboardEvent('keydown', {key: 'Backspace'}), 69 new KeyboardEvent('keydown', {key: 'Backspace', ctrlKey: true, metaKey: false, altKey: false}), 70 ]; 71 72 const invalidKeypressEvents = [ 73 new KeyboardEvent('keydown', {key: '', ctrlKey: true, metaKey: false, altKey: false}), 74 new KeyboardEvent('keydown', {key: '', ctrlKey: false, metaKey: true, altKey: false}), 75 new KeyboardEvent('keydown', {key: '', ctrlKey: false, metaKey: false, altKey: true}), 76 new KeyboardEvent('keydown', {key: ' ', ctrlKey: false, metaKey: false, altKey: false}), 77 new KeyboardEvent('keydown', {key: 'a', ctrlKey: true, metaKey: false, altKey: false}), 78 new KeyboardEvent('keydown', {key: 'a', ctrlKey: false, metaKey: true, altKey: false}), 79 new KeyboardEvent('keydown', {key: 'a', ctrlKey: false, metaKey: false, altKey: true}), 80 new KeyboardEvent('keydown', {key: 'Backspace', ctrlKey: false, metaKey: true, altKey: false}), 81 new KeyboardEvent('keydown', {key: 'Backspace', ctrlKey: false, metaKey: false, altKey: true}), 82 new KeyboardEvent('keydown', {key: 'ArrowDown'}), 83 ]; 84 85 test('should test that onKeyDown function focuses input for valid keys', () => { 86 for (const event of validKeypressEvents) { 87 queryInput.blur(); 88 onKeyDownMethod(event); 89 } 90 91 expect(focusSpy.mock.calls.length).toBe(validKeypressEvents.length); 92 focusSpy.mockReset(); 93 }); 94 95 96 test('should test that onKeyDown function does not focus input for invalid keys', () => { 97 for (const event of invalidKeypressEvents) { 98 queryInput.blur(); 99 onKeyDownMethod(event); 100 } 101 102 expect(focusSpy.mock.calls.length).toBe(0); 103 }); 104});