Headroom.js — библиотека для управления поведением шапки страницы при скролле. Unit-тестирование компонентов, использующих Headroom, позволяет проверять корректность работы скрытия и появления элементов в ответ на события прокрутки. Основной задачей является тестирование поведения без фактической прокрутки страницы в браузере.
Для unit-тестирования компонентов, которые используют Headroom.js, обычно применяются следующие инструменты:
Пример базовой установки в проекте:
npm install --save-dev jest @testing-library/react @testing-library/jest-dom
Для Headroom важно обеспечить корректное поведение scroll-объекта в
тестовой среде. В jsdom отсутствует полноценный скролл, поэтому события
scroll приходится эмулировать вручную.
Headroom.js реагирует на window.scrollY,
window.addEventListener('scroll', ...) и внутренние методы
для вычисления направления прокрутки. Для unit-тестов необходимо
замокировать эти элементы:
beforeEach(() => {
Object.defineProperty(window, 'scrollY', { writable: true, value: 0 });
window.addEventListener = jest.fn((event, cb) => {
if (event === 'scroll') window._scrollCallback = cb;
});
});
function triggerScroll(newScrollY) {
window.scrollY = newScrollY;
if (window._scrollCallback) window._scrollCallback();
}
Этот подход позволяет контролировать события скролла без реального перемещения страницы.
Headroom управляет классами элемента: по умолчанию
headroom--pinned и headroom--unpinned.
Unit-тест должен проверять корректное применение этих классов при
изменении scrollY.
Пример для React-компонента с Headroom:
import { render } from '@testing-library/react';
import Headroom from 'headroom.js';
import MyHeader from './MyHeader';
test('header toggles classes on scroll', () => {
const { container } = render(<MyHeader />);
const header = container.querySelector('header');
const headroomInstance = new Headroom(header);
headroomInstance.init();
expect(header.classList.contains('headroom--pinned')).toBe(true);
triggerScroll(100); // скролл вниз
expect(header.classList.contains('headroom--unpinned')).toBe(true);
triggerScroll(50); // скролл вверх
expect(header.classList.contains('headroom--pinned')).toBe(true);
headroomInstance.destroy();
});
Headroom.js поддерживает события через опции: onPin,
onUnpin, onTop, onNotTop.
Unit-тестирование этих коллбеков выполняется с помощью мок-функций:
const onPinM ock = jest.fn();
const onUnpinM ock = jest.fn();
const headroom = new Headroom(header, {
onPin: onPinMock,
onUnpin: onUnpinMock,
});
headroom.init();
triggerScroll(200); // скролл вниз
expect(onUnpinMock).toHaveBeenCalled();
triggerScroll(100); // скролл вверх
expect(onPinMock).toHaveBeenCalled();
Важно убедиться, что коллбеки вызываются только при изменении состояния, а не при каждом событии scroll.
Headroom.js имеет несколько ключевых опций, влияющих на поведение:
tolerance — минимальное количество пикселей для
срабатывания изменения состояния.offset — расстояние прокрутки перед активацией
Headroom.classes — объект с пользовательскими классами.Unit-тестирование должно проверять корректное применение этих параметров:
const headroom = new Headroom(header, { tolerance: 50, offset: 100 });
headroom.init();
triggerScroll(90);
expect(header.classList.contains('headroom--unpinned')).toBe(false); // не превышен offset
triggerScroll(150);
expect(header.classList.contains('headroom--unpinned')).toBe(true);
В проектах на React или Vue Headroom часто оборачивается в компонент. Unit-тестирование таких компонентов включает проверку:
init, destroy)
при монтировании и размонтировании.Пример для React:
import { render, unmountComponentAtNode } from 'react-dom';
import MyHeader from './MyHeader';
let container = null;
beforeEach(() => {
container = document.createElement('div');
document.body.appendChild(container);
});
afterEach(() => {
unmountComponentAtNode(container);
container.remove();
container = null;
});
test('Headroom init and destroy called', () => {
const initSpy = jest.spyOn(Headroom.prototype, 'init');
const destroySpy = jest.spyOn(Headroom.prototype, 'destroy');
render(<MyHeader />, container);
expect(initSpy).toHaveBeenCalled();
unmountComponentAtNode(container);
expect(destroySpy).toHaveBeenCalled();
});
Unit-тесты для headroom-компонентов должны охватывать все сценарии:
onPin, onUnpin,
onTop, onNotTop).tolerance, offset,
кастомные классы).При этом важна изоляция тестов: состояние scrollY и события должны полностью контролироваться тестовой средой. Это позволяет выявить баги в логике Headroom без зависимости от реального браузера.
AAA —
Arrange, Act, Assert).Такая организация unit-тестов обеспечивает стабильность и предсказуемость поведения компонентов с Headroom.js в любом приложении.