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