У меня есть компонент Vue, который отображает терминал Xterm.js.
Terminal.vue
<template>
<div id="terminal"></div>
</template>
<script>
import Vue from 'vue';
import { Terminal } from 'xterm/lib/public/Terminal';
import { ITerminalOptions, ITheme } from 'xterm';
export default Vue.extend({
data() {
return {};
},
mounted() {
Terminal.applyAddon(fit);
this.term = new Terminal(opts);
this.term.open(document.getElementById('terminal'));
},
</script>
Я хочу протестировать этот компонент.
Terminal.test.js
import Terminal from 'components/Terminal'
import { mount } from '@vue/test-utils';
describe('test', ()=>{
const wrapper = mount(App);
});
Когда я запускаю jest
для этого тестового файла, я получаю эту ошибку:
TypeError: Cannot set property 'globalCompositeOperation' of null
45 | this.term = new Terminal(opts);
> 46 | this.term.open(document.getElementById('terminal'));
Копаясь в трассировке стека, я вижу, что это как-то связано с ColorManager Xterm.
at new ColorManager (node_modules/xterm/src/renderer/ColorManager.ts:94:39)
at new Renderer (node_modules/xterm/src/renderer/Renderer.ts:41:25)
Если я посмотрю на их код, я вижу довольно запутанную вещь:
xterm.js / ColorManager.ts
constructor(document: Document, public allowTransparency: boolean) {
const canvas = document.createElement('canvas');
canvas.width = 1;
canvas.height = 1;
const ctx = canvas.getContext('2d');
// I would expect to see the "could not get rendering context"
// error, as "ctx" shows up as "null" later, guessing from the
// error that Jest caught
if (!ctx) {
throw new Error('Could not get rendering context');
}
this._ctx = ctx;
// Somehow this._ctx is null here, but passed a boolean check earlier?
this._ctx.globalCompositeOperation = 'copy';
this._litmusColor = this._ctx.createLinearGradient(0, 0, 1, 1);
this.colors = {
foreground: DEFAULT_FOREGROUND,
background: DEFAULT_BACKGROUND,
cursor: DEFAULT_CURSOR,
cursorAccent: DEFAULT_CURSOR_ACCENT,
selection: DEFAULT_SELECTION,
ansi: DEFAULT_ANSI_COLORS.slice()
};
}
Я не совсем понимаю, как canvas.getContext
, по-видимому, возвратил что-то, прошедшее булеву проверку (на if(!ctx)
), но позже вызвало ошибку cannot set globalCompositeOperation of null
для этой же переменной.
Я очень озадачен тем, как я могу успешно выполнить макет-рендеринг и, следовательно, протестировать этот компонент - в собственных файлах тестирования xterm они, похоже, создают поддельный DOM с использованием jsdom
:
xterm.js / ColorManager.test.ts
beforeEach(() => {
dom = new jsdom.JSDOM('');
window = dom.window;
document = window.document;
(<any>window).HTMLCanvasElement.prototype.getContext = () => ({
createLinearGradient(): any {
return null;
},
fillRect(): void { },
getImageData(): any {
return {data: [0, 0, 0, 0xFF]};
}
});
cm = new ColorManager(document, false);
});
Но я считаю, что под капотом vue-test-utils
также создает поддельный DOM с использованием jsdom
.Кроме того, в документации указано, что функция mount
одновременно подключает и визуализирует компонент vue.
Создает оболочку, содержащую смонтированный и визуализированный компонент Vue.
https://vue -test-utils.vuejs.org / api / # mount
Как я могу успешно смоделировать DOM таким образом, чтобы я мог протестировать компонент Vue, который реализует Xterm.js, с использованием Jest?