如何用 Jest 测试自定义 Web 组件? [英] How to test custom web component with jest?
问题描述
我想测试一些自定义 Web 组件并使用 jest.js 作为测试运行器(因为它支持 ES6).
I would like to test some custom web components and use jest.js as test runner (due to its support for ES6).
Chromium 支持像
Chromium supports commands like
window.customElements.define('my-custom-element', MyCustomElementClass);
注册自定义 Web 组件.
to register a custom web component.
然而,window.customElements
在玩笑测试的上下文中似乎并不为人所知.
However, window.customElements
does not seem to be known in the context of jest tests.
作为一种解决方法,我尝试将 jest 与 puppeteer 和 express 结合使用 在 Chromium 中运行 customElements
部分.
As a work around I tried to use jest in combination with puppeteer and express to run the customElements
part in Chromium.
但是,我很难在评估代码中注入自定义元素类TreezElement
:
However, I have difficulties to inject the custom element class TreezElement
in the evaluated code:
treezElement.js:
treezElement.js:
class TreezElement extends HTMLElement {
connectedCallback () {
this.innerHTML = 'Hello, World!';
}
}
treezElement.test.js:
treezElement.test.js:
import TreezElement from '../../src/components/treezElement.js';
import puppeteer from 'puppeteer';
import express from 'express';
describe('Construction', ()=>{
let port = 3000;
let browser;
let page;
let element;
const width = 800;
const height = 800;
beforeAll(async () => {
const app = await express()
.use((req, res) => {
res.send(
`<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
</body>
</html>`
)
})
.listen(port);
browser = await puppeteer.launch({
headless: false,
slowMo: 80,
args: [`--window-size=${width},${height}`]
});
var pages = await browser.pages();
page = pages[0];
await page.setViewport({ width, height });
await page.goto('http://localhost:3000');
element = await page.evaluate(({TreezElement}) => {
console.log('TreezElement:')
console.log(TreezElement);
window.customElements.define('treez-element', TreezElement);
var element = document.create('treez-element');
document.body.appendChild(element);
return element;
}, {TreezElement});
});
it('TreezElement', ()=>{
});
afterAll(() => {
browser.close();
});
});
也许 TreezElement
不可序列化,因此 undefined
被传递给函数.
Maybe TreezElement
is not serializable and therefore undefined
is passed to the function.
如果我尝试直接从评估代码中导入自定义元素类 TreezElement
...
If I try to import the custom element class TreezElement
directly from within the evaluated code ...
element = await page.evaluate(() => {
import TreezElement from '../../src/components/treezElement.js';
console.log('TreezElement:')
console.log(TreezElement);
window.customElements.define('treez-element', TreezElement);
var element = document.create('treez-element');
document.body.appendChild(element);
return element;
});
...我收到错误
'import' 和 'export' 只能出现在顶层
'import' and 'export' may only appear at the top level
=> 使用 jest 测试自定义 Web 组件的推荐方法是什么?
一些相关的东西:
无法通过 jest + puppeteer 获得测试覆盖率一个>
https://jestjs.io/docs/en/puppeteer
推荐答案
JSDOM16.2 包括对自定义元素的基本支持,可在 Jest 26.5 及以上.这是一个简单的 Jest 测试,表明它可以正常工作:
JSDOM 16.2 includes basic support for custom elements and is available in Jest 26.5 and above. Here's a simple Jest test that shows it working:
customElements.define('test-component', class extends HTMLElement {
constructor() {
super();
const p = document.createElement('p')
p.textContent = 'It works!'
this.appendChild(p)
}
})
test('custom elements in JSDOM', () => {
document.body.innerHTML = `<h1>Custom element test</h1> <test-component></test-component>`
expect(document.body.innerHTML).toContain('It works!')
})
输出:
$ jest
PASS ./test.js
✓ custom elements in JSDOM (11 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.409 s
Ran all test suites.
请注意,并非所有功能都受支持,特别是 shadow DOM 不起作用.
Note not all features are supported yet, notably shadow DOM does not work.
这篇关于如何用 Jest 测试自定义 Web 组件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!