我有一个渲染 Xterm.js 终端的 Vue 组件。
终端.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'));
深入堆栈跟踪,我可以看到它与 Xterm 的 ColorManager 有关。
at new ColorManager (node_modules/xterm/src/renderer/ColorManager.ts:94:39)
at new Renderer (node_modules/xterm/src/renderer/Renderer.ts:41:25)
如果我查看他们的代码,我会看到一个相对令人困惑的事情:
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
明显地返回通过布尔检查(at if(!ctx)
)但后来cannot set globalCompositeOperation of null
在同一个变量上导致错误的东西。
我对如何成功进行模拟渲染并因此测试这个组件感到非常困惑——在 xterm 自己的测试文件中,他们似乎正在使用以下方法创建一个假 DOM jsdom
:
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
也在使用jsdom
. 此外,文档表明该mount
函数既附加又呈现 vue 组件。
创建一个包含已安装和渲染的 Vue 组件的 Wrapper。
https://vue-test-utils.vuejs.org/api/#mount
我怎样才能成功地模拟一个 DOM,以便我可以使用 Jest 测试一个实现 Xterm.js 的 Vue 组件?