Снэпшот-тестирование позволяет зафиксировать текущее состояние компонента и автоматически проверять, не изменился ли его вывод при последующих изменениях кода. В контексте Haunted это особенно важно, поскольку библиотека построена на Web Components и реактивных хуках, а визуальное представление компонента часто зависит от состояния и пропсов.
Для снэпшот-тестирования компонентов Haunted чаще всего используют комбинацию:
Пример установки необходимых пакетов:
npm install --save-dev @open-wc/testing mocha chai
Для Jest потребуется также настроить поддержку Web
Components через jsdom.
Haunted-компонент определяется функцией и регистрируется как кастомный элемент:
import { html, component } from 'haunted';
function MyButton({ label }) {
return html`<button>${label}</button>`;
}
customElements.define('my-button', component(MyButton));
Важно, чтобы компонент был полностью чистым, без побочных эффектов при рендере. Любые асинхронные операции или обращения к внешним ресурсам следует мокировать или обрабатывать отдельно.
import { fixture, html } from '@open-wc/testing';
import { expect } from 'chai';
import './my-button.js';
describe('MyButton', () => {
it('должен совпадать со снэпшотом', async () => {
const el = await fixture(html`<my-button label="Нажми"></my-button>`);
expect(el).shadowDom.to.equalSnapshot();
});
});
Ключевые моменты:
fixture создаёт изолированную среду для
компонента.shadowDom.to.equalSnapshot() сохраняет и сравнивает
текущее состояние Shadow DOM с предыдущим снэпшотом.Haunted использует хуки, такие как useState и
useEffect. Для тестирования состояния важно правильно
обновлять пропсы и имитировать взаимодействие:
import { useState } from 'haunted';
function Counter() {
const [count, setCount] = useState(0);
return html`
<button @click=${() => setCount(count + 1)}>${count}</button>
`;
}
customElements.define('my-counter', component(Counter));
Тестирование снэпшота с изменением состояния:
it('снэпшот после клика', async () => {
const el = await fixture(html`<my-counter></my-counter>`);
el.shadowRoot.querySelector('button').click();
await el.updateComplete; // ожидание обновления компонента
expect(el).shadowDom.to.equalSnapshot();
});
Особенности Haunted:
updateComplete не является встроенным API, но можно
использовать промис на requestUpdate или
Promise.resolve() для ожидания следующего рендера.setState инициирует повторный рендер
компонента, который должен быть зафиксирован в снэпшоте.Для компонентов, взаимодействующих с внешними API, рекомендуется:
Пример подмены данных:
function UserCard({ user }) {
return html`<div>${user.name}</div>`;
}
const mockUser = { name: 'Иван' };
const el = await fixture(html`<user-card .user=${mockUser}></user-card>`);
expect(el).shadowDom.to.equalSnapshot();
Снэпшот-тестирование в Haunted позволяет обеспечить стабильность UI, отлавливать непреднамеренные изменения в Shadow DOM и работать с реактивными хуками без сложной мок-среды. Оно становится эффективным инструментом при разработке сложных компонентов с состоянием и взаимодействием.