У кого-нибудь есть хорошая установка для тестирования пользовательских элементов с помощью jest, jsdom или подобных? Я использовал Puppeteer и Selenium, но они слишком сильно замедляют выполнение тестов. Любые другие альтернативы или исправления для jsdom, которые делают приведенный ниже тест работоспособным?
import {LitElement} from 'lit-element';
import {html} from 'lit-html';
export class Counter extends LitElement {
static get properties() {
return Object.assign({}, super.properties, {
count: {type: Number}
});
}
render() {
return html`Count is ${this.count}`;
}
}
customElements.define('c-counter', Counter);
С тестовым файлом:
import './counter';
describe('c-counter', () => {
it('should be registered', () => {
expect(customElements.get('c-counter')).toBeDefined();
});
it('render', async () => {
const element = window.document.createElement('c-counter');
window.document.body.appendChild(element);
await element.updateComplete;
expect(element.innerHTML).toContain('Count is undefined');
element.count = 3;
await element.updateComplete;
expect(element.innerHTML).toContain('Count is 3');
});
});
И, наконец, это текущая настройка среды jest:
const {installCommonGlobals} = require('jest-util');
const {JSDOM, VirtualConsole} = require('jsdom');
const JSDOMEnvironment = require('jest-environment-jsdom');
const installCE = require('document-register-element/pony');
class JSDOMCustomElementsEnvironment extends JSDOMEnvironment {
constructor(config, context) {
super(config, context);
this.dom = new JSDOM('<!DOCTYPE html>', {
runScripts: 'dangerously',
pretendToBeVisual: true,
VirtualConsole: new VirtualConsole().sendTo(context.console || console),
url: 'http://jsdom'
});
/* eslint-disable no-multi-assign */
const global = (this.global = this.dom.window.document.defaultView);
installCommonGlobals(global, config.globals);
installCE(global.window, {
type: 'force',
noBuiltIn: false
});
}
teardown() {
this.global = null;
this.dom = null;
return Promise.resolve();
}
}
module.exports = JSDOMCustomElementsEnvironment;
Я не ожидаю, что это будет здорово, пока jsdom не будет поддерживать пользовательские элементы и модули JS. Учитывая большое количество API-интерфейсов DOM, которые используют веб-компоненты, я думаю, что тестирование в реальном браузере — гораздо более разумный подход. Вы должны протестировать во всех реальных браузерах, которые вы поддерживаете.
Я полностью согласен с Джастином в этом... если вам нужна помощь в настройке тестирования в реальном браузере, посмотрите здесь open-wc.org/тестирование - это должно быть довольно прямолинейно и дает вам большинство функций, которые вы знаете из Jest, в реальном браузере.
@JustinFagnani, я ищу хороший стек для тестирования ванильных веб-компонентов (здесь вы найдете несколько вопросов от меня по этой теме). Вы сказали: «Немногие люди тестируют веб-компоненты в Jest». Знаете ли вы сторонников и противников использования Jest для тестирования веб-компонентов? Не поймите меня неправильно, но простое высказывание «немногие используют...» мало чем поможет (вы обнаружите, что многие люди говорят, что мало кто использует веб-компоненты. Я использую Polymer со значительным успехом, и теперь я пытаюсь ванильные веб-компоненты). «Немного/много/много/и т. д. не добавляет многого, но если вы можете кратко указать, почему это не так,
сам испытываю с этим проблемы
@Josh Проект, в котором я использовал это, движется к использованию open-wc.org вместо этого, поскольку этот проект активен и имеет готовое тестирование с настройкой покрытия и по-прежнему использует LitElement для веб-компонентов. Вероятно, это лучший способ тестирования с помощью LitElement.





Это возможно с небольшой дополнительной настройкой.
Если вы посмотрите на документы open wc, они рекомендуют тестировать ваши веб-компоненты в браузере, что они уже делают с Karma и Headless Chrome. Как вы уже заметили, Puppeteer и Selenium слишком медленны для этого, и единственная жизнеспособная альтернатива браузеру — это ElectronJS. Для Jest доступен бегун.
https://github.com/hustcc/jest-электрон
Это позволит вам отображать ваши веб-компоненты в реальном браузере с доступом к Shadow DOM, и ваши тесты по-прежнему будут быстрыми. Примерно так я использую Webpack для обработки своего кода.
// button.ts
import {html, customElement, LitElement, property} from "lit-element";
@customElement('awesome-button')
export class Button extends LitElement {
@property()
buttonText = '';
render() {
return html`<button id = "custom-button"
@click = "${() => {}}">${this.buttonText}</button>`;
}
}
Конфигурация веб-пакета
const path = require('path');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
module.exports = {
mode: 'development',
entry: './index.ts',
module: {
rules: [
{
test: /\.ts?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
plugins: [
new CleanWebpackPlugin()
],
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
};
Конфигурация шутки
module.exports = {
preset: 'ts-jest',
runner: 'jest-electron/runner',
testEnvironment: 'jest-electron/environment',
setupFiles: ['./dist/main.js'],
};
И, наконец, наш тест.
import {LitElement} from 'lit-element';
describe('awesome-button', () => {
const AWESOME_BUTTON_TAG = 'awesome-button';
const ELEMENT_ID = 'custom-button';
let buttonElement: LitElement;
const getShadowRoot = (tagName: string): ShadowRoot => {
return document.body.getElementsByTagName(tagName)[0].shadowRoot;
}
beforeEach(() => {
buttonElement = window.document.createElement(AWESOME_BUTTON_TAG) as LitElement;
document.body.appendChild(buttonElement);
});
afterEach(() => {
document.body.getElementsByTagName(AWESOME_BUTTON_TAG)[0].remove();
});
it('displays button text', async () => {
const dummyText = 'Web components & Jest with Electron';
buttonElement.setAttribute('buttonText', dummyText);
await buttonElement.updateComplete;
const renderedText = getShadowRoot(AWESOME_BUTTON_TAG).getElementById(ELEMENT_ID).innerText;
expect(renderedText).toEqual(dummyText);
});
it('handles clicks', async () => {
const mockClickFunction = jest.fn();
buttonElement.addEventListener('click', () => {mockClickFunction()});
getShadowRoot(AWESOME_BUTTON_TAG).getElementById(ELEMENT_ID).click();
getShadowRoot(AWESOME_BUTTON_TAG).getElementById(ELEMENT_ID).click();
expect(mockClickFunction).toHaveBeenCalledTimes(2);
});
});
Я даже написал об этом в блоге, и там вы можете найти репозитории с полной настройкой и т. д.
https://www.ninkovic.dev/blog/2020/testing-web-components-with-jest-and-lit-element
Как мне добавить журналы покрытия кода, например карму?
У @MatheusRibeiro Jest есть множество вариантов настройки покрытия кода разными репортерами. Пожалуйста, ознакомьтесь с документацией. jestjs.io/docs/configuration#collectcoverage-boolean
Было бы полезно, если бы вы поделились, что это за ошибка. А так как так мало людей, если они вообще есть, запускают тесты веб-компонентов в Jest, я, вероятно, попытаюсь создать репродукцию в репозитории или суть, чтобы люди могли попробовать.