【发布时间】:2019-10-19 12:47:53
【问题描述】:
我有一个渲染 Xterm.js 终端的 Vue 组件。
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'));
深入堆栈跟踪,我可以看到它与 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 是如何返回通过布尔检查(if(!ctx))但后来在同一变量上导致cannot set globalCompositeOperation of null 错误的。
我对如何成功进行模拟渲染并因此测试这个组件感到非常困惑 - 在 xterm 自己的测试文件中,他们似乎正在使用 jsdom 创建一个假 DOM:
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 创建一个假 DOM。此外,文档表明 mount 函数既附加又呈现 vue 组件。
创建一个包含已安装和渲染的 Vue 组件的 Wrapper。
https://vue-test-utils.vuejs.org/api/#mount
我怎样才能成功地模拟 DOM,以便我可以使用 Jest 测试实现 Xterm.js 的 Vue 组件?
【问题讨论】:
标签: javascript vue.js jestjs vue-test-utils xtermjs