Haunted — это библиотека для создания веб-компонентов на основе функционального подхода в JavaScript, вдохновлённая React-хуками. Она позволяет описывать поведение компонентов с помощью функций и легко управлять состоянием и эффектами. Для обеспечения качества кода и корректной работы компонентов важно использовать автоматизированное тестирование. Open WC Testing предоставляет набор инструментов для тестирования веб-компонентов, включая поддержку Haunted.
Для начала необходимо установить базовые пакеты:
npm install haunted lit @open-wc/testing mocha chai
haunted — библиотека функциональных
веб-компонентов.lit — необходима для рендеринга шаблонов (Lit-html
используется Haunted для работы с шаблонами).@open-wc/testing — набор утилит для тестирования
веб-компонентов.mocha и chai — фреймворк для запуска
тестов и библиотека для ассертов.Настройка package.json для тестирования:
"scripts": {
"test": "mocha --require @babel/register 'test/**/*.test.js'"
}
При использовании современных синтаксисов ES6/ESM важно настроить транспиляцию через Babel.
Простейший тест компонента включает:
Пример:
import { html, render } from 'haunted';
import { fixture, expect } from '@open-wc/testing';
import { component } from 'haunted';
function counter({ initial = 0 } = {}) {
const [count, setCount] = useState(initial);
return html`
<div>
<span>${count}</span>
<button @click=${() => setCount(count + 1)}>Increment</button>
</div>
`;
}
customElements.define('my-counter', component(counter));
describe('my-counter', () => {
it('отображает начальное значение', async () => {
const el = await fixture(html`<my-counter></my-counter>`);
const span = el.shadowRoot.querySelector('span');
expect(span.textContent).to.equal('0');
});
it('увеличивает значение по клику', async () => {
const el = await fixture(html`<my-counter></my-counter>`);
const button = el.shadowRoot.querySelector('button');
button.click();
await el.updateComplete;
const span = el.shadowRoot.querySelector('span');
expect(span.textContent).to.equal('1');
});
});
Ключевые моменты:
fixture создаёт компонент в DOM и возвращает его для
тестирования.expect позволяет писать читаемые проверки
состояния.await el.updateComplete или
аналогичные методы.Haunted активно использует хуки (useState,
useEffect, useReducer). При тестировании хуков
следует учитывать следующие особенности:
useState требует перерендеринга компонента для проверки
нового состояния.useEffect выполняется после рендера, поэтому тесты
должны ожидать асинхронного завершения.Пример проверки эффекта:
function messageUpdater() {
const [msg, setMsg] = useState('Hello');
useEffect(() => {
const timer = setTimeout(() => setMsg('Updated'), 100);
return () => clearTimeout(timer);
}, []);
return html`<span>${msg}</span>`;
}
customElements.define('message-updater', component(messageUpdater));
it('обновляет сообщение после таймера', async () => {
const el = await fixture(html`<message-updater></message-updater>`);
await new Promise(r => setTimeout(r, 120));
const span = el.shadowRoot.querySelector('span');
expect(span.textContent).to.equal('Updated');
});
Haunted-компоненты часто генерируют кастомные события. Open WC Testing позволяет легко отслеживать их:
it('вызывает событие при клике', async () => {
const el = await fixture(html`<my-counter></my-counter>`);
const spy = sinon.spy();
el.addEventListener('increment', spy);
const button = el.shadowRoot.querySelector('button');
button.click();
expect(spy).to.have.been.calledOnce;
});
sinon для создания шпионов упрощает
проверку событий.dispatchEvent
внутри Haunted-компонента.Open WC Testing поддерживает проверку CSS и структуры DOM. Для Haunted важно:
el.shadowRoot.Пример:
it('имеет красный текст', async () => {
const el = await fixture(html`<my-counter></my-counter>`);
const span = el.shadowRoot.querySelector('span');
const color = getComputedStyle(span).color;
expect(color).to.equal('rgb(255, 0, 0)');
});
Для автоматизации тестов Haunted-компонентов:
npm test для запуска тестов.puppeteer или
playwright) для эмуляции DOM в CI.Пример конфигурации с Puppeteer:
import { setUpPage } from '@open-wc/testing-helpers';
import puppeteer from 'puppeteer';
before(async () => {
global.page = await puppeteer.launch({ headless: true });
global.document = await setUpPage(global.page);
});
Такой подход позволяет тестировать полноценные Haunted-компоненты в среде, приближенной к реальному браузеру.
await для стабильных
тестов.shadowRoot.sinon.spy).Тщательное тестирование с Open WC Testing обеспечивает корректную работу функциональных веб-компонентов Haunted и минимизирует баги при изменении логики.