Pop-up dictionary browser extension for language learning. Successor to Yomichan. (PERSONAL FORK)
at lambda-fork/main 78 lines 2.9 kB view raw
1/* 2 * Copyright (C) 2023-2025 Yomitan Authors 3 * Copyright (C) 2020-2022 Yomichan Authors 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <https://www.gnu.org/licenses/>. 17 */ 18 19import fs from 'fs'; 20import {test} from 'vitest'; 21import {builtinEnvironments} from 'vitest/environments'; 22 23/** 24 * @param {import('jsdom').DOMWindow} window 25 */ 26function prepareWindow(window) { 27 const {document} = window; 28 29 // Define innerText setter as an alias for textContent setter 30 Object.defineProperty(window.HTMLDivElement.prototype, 'innerText', { 31 /** @returns {string} */ 32 get() { return this.textContent; }, 33 /** @param {string} value */ 34 set(value) { this.textContent = value; }, 35 }); 36 37 // Placeholder for feature detection 38 document.caretRangeFromPoint = () => null; 39} 40 41/** 42 * 43 * @param {string} [htmlFilePath] 44 * @returns {Promise<{window: import('jsdom').DOMWindow; teardown: (global: unknown) => import('vitest').Awaitable<void>}>} 45 */ 46export async function setupDomTest(htmlFilePath) { 47 const html = typeof htmlFilePath === 'string' ? fs.readFileSync(htmlFilePath, {encoding: 'utf8'}) : '<!DOCTYPE html>'; 48 const env = builtinEnvironments.jsdom; 49 const environment = await env.setup(global, {jsdom: {html}}); 50 const window = /** @type {import('jsdom').DOMWindow} */ (/** @type {unknown} */ (global.window)); 51 prepareWindow(window); 52 return { 53 window, 54 teardown: (global) => environment.teardown(global), 55 }; 56} 57 58/** 59 * @param {string} [htmlFilePath] 60 * @returns {import('vitest').TestAPI<{window: import('jsdom').DOMWindow}>} 61 */ 62export function createDomTest(htmlFilePath) { 63 const html = typeof htmlFilePath === 'string' ? fs.readFileSync(htmlFilePath, {encoding: 'utf8'}) : '<!DOCTYPE html>'; 64 return test.extend({ 65 // eslint-disable-next-line no-empty-pattern 66 window: async ({}, use) => { 67 const env = builtinEnvironments.jsdom; 68 const environment = await env.setup(global, {jsdom: {html}}); 69 const window = /** @type {import('jsdom').DOMWindow} */ (/** @type {unknown} */ (global.window)); 70 prepareWindow(window); 71 try { 72 await use(window); 73 } finally { 74 await environment.teardown(global); 75 } 76 }, 77 }); 78}