首页 > 解决方案 > 使用 jsdom 测试 Web 组件

问题描述

我有一个我构建的 Web 组件,它被捆绑(使用Rollup)到 UMD 和 ESM 包中。src/index.js基本上看起来是这样的。

import html from 'template.html';
import css from 'styles.css';

export class MyComponent extends window.HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: 'open' });
  }
}

export default (function() {
  window.customElements.define('my-component', MyComponent);
})()

我很清楚这看起来有多奇怪,并且我愿意接受有关清理它的建议,以便测试真正起作用。

我正在尝试使用mochaand测试我的 Web 组件jsdom-global。问题是我无法安装组件。换句话说,这失败了:

import jsdomGlobal from 'jsdom-global';
import { expect } from 'chai';

import { MyComponent } from '../dist/my-component.esm';

describe('test', function() {
  let jsdom;

  before(function(){
    jsdom = jsdomGlobal('', { runScripts: 'dangerously' });
    const script = document.createElement('script');
    script.textContent = `window.customElements.define('my-component', (${MyComponent}))`;
    document.head.appendChild(script);
  })

  after(function() {
    jsdom();
  });

  it('mounts', async function() {
    await window.customElements.whenDefined('my-component');
    expect(window.customElements.get('my-component')).to.exist;
  })
})

我也尝试过进行新window.customElements.define调用,因为我认为 IIFE 只会在文件被引用后执行,但情况似乎并非如此?

顺便说一句,如果有人知道如何/src直接测试文件而不是测试文件/dist,那就太棒了。我认为有某种方法mocha可以rollup一起工作,以更好地确定覆盖范围。就目前而言,覆盖范围仅显示单行故障,而不是源代码中的任何故障。

标签: javascriptmocha.jsweb-componentrollupnative-web-component

解决方案


好的,在尝试了各种各样的事情后,我取得了一些成功。

import { JSDOM } from 'jsdom';
import { expect } from 'chai';
import fs from 'fs';
import { resolve } from 'path';
import { promisify } from 'util';

const readFile = promisify(fs.readFile);

async function getHTML() {
  const script = await readFile(resolve(__dirname, '..', 'dist', 'my-component.umd.js'));
  return `<html><head><script>${script}</script></head><body></body></html>`;
}

describe('my-component', function () {
  describe('browser context', function() {
    let window, document;

    before(async function() {
      const html = await getHTML();
      const dom = new JSDOM(html, { runScripts: 'dangerously', resources: 'usable' });
      window = dom.window;
      document = window.document;
    });

    it('defines a custom element', async function() {
      await window.customElements.whenDefined('my-component');
      expect(window.customElements.get('my-component')).to.exist;
    })
  })
})

所以这通过了断言,但是因为测试不知道脚本,所以没有覆盖率指标。

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |       0 |        0 |       0 |       0 |                   
----------|---------|----------|---------|---------|-------------------

能够测试报告覆盖率会很好,但现在必须这样做。


推荐阅读