Waypoints — это небольшая, но мощная библиотека для отслеживания прокрутки и выполнения функций при достижении определённых элементов на странице. Для поддержания стабильности и предотвращения регрессий при разработке необходимо применять юнит-тестирование, которое позволяет проверять корректность срабатывания точек и обработчиков событий.
Для тестирования Waypoints чаще всего используют сочетание следующих инструментов:
Пример установки через npm:
npm install --save-dev jest jsdom
Waypoints напрямую зависит от наличия DOM-элементов, поэтому тестовая
среда должна имитировать поведение окна и документа браузера. Настройка
jsdom обычно происходит автоматически через Jest, но при
необходимости можно явно указать окружение в конфигурации:
{
"testEnvironment": "jsdom"
}
Для корректного юнит-тестирования необходимо подготовить эмуляцию HTML, которая включает элементы, на которые будут навешиваться Waypoints:
document.body.innerHTML = `
<div style="height: 2000px;">
<div id="target" style="margin-top: 500px; height: 100px;">Waypoint Target</div>
</div>
`;
Важные моменты:
Waypoints создаются через конструктор Waypoint и требует
объект с конфигурацией:
const waypoint = new Waypoint({
element: document.getElementById('target'),
handler: jest.fn(), // используем jest.fn() для отслеживания вызовов
offset: '50%' // срабатывание в середине окна
});
Ключевые свойства:
element — целевой DOM-элемент.handler — функция, вызываемая при срабатывании.offset — смещение, при котором происходит
активация.Использование jest.fn() позволяет проверять, был
ли вызван обработчик, сколько раз и с какими аргументами.
Для проверки срабатывания Waypoints необходимо вручную изменить
позицию окна и вызвать событие scroll:
window.scrollTo(0, 600); // прокрутка страницы
window.dispatchEvent(new Event('scroll')); // имитация события scroll
После этого можно проверить вызов обработчика:
expect(waypoint.handler).toHaveBeenCalled();
Если требуется протестировать многоступенчатые события (например, активация при входе и выходе элемента), следует учитывать направление прокрутки:
const handler = jest.fn();
const waypoint = new Waypoint({
element: document.getElementById('target'),
handler: handler,
offset: '50%'
});
window.scrollTo(0, 600);
window.dispatchEvent(new Event('scroll'));
expect(handler).toHaveBeenCalledTimes(1);
window.scrollTo(0, 400);
window.dispatchEvent(new Event('scroll'));
expect(handler).toHaveBeenCalledTimes(2);
Если элементы добавляются на страницу динамически после инициализации, Waypoints необходимо реинициализировать. В тестах это проверяется через манипуляции DOM:
const container = document.createElement('div');
container.id = 'dynamic-container';
document.body.appendChild(container);
const newElement = document.createElement('div');
newElement.id = 'new-target';
newElement.style.height = '100px';
container.appendChild(newElement);
const waypoint = new Waypoint({
element: newElement,
handler: jest.fn(),
offset: '50%'
});
window.scrollTo(0, 500);
window.dispatchEvent(new Event('scroll'));
expect(waypoint.handler).toHaveBeenCalled();
Waypoints предоставляет доступ к ряду внутренних свойств, которые можно использовать для валидации в тестах:
waypoint.element — проверка корректности привязанного
элемента.waypoint.offset — проверка смещения активации.waypoint.enabled — состояние точки
(включена/выключена).Пример проверки состояния:
expect(waypoint.element.id).toBe('new-target');
expect(waypoint.offset).toBe('50%');
expect(waypoint.enabled).toBe(true);
Для поддерживаемости рекомендуется:
describe('Waypoints Unit Tests', () => {
let handler;
let waypoint;
beforeEach(() => {
document.body.innerHTML = `
<div style="height: 2000px;">
<div id="target" style="margin-top: 500px; height: 100px;"></div>
</div>
`;
handler = jest.fn();
waypoint = new Waypoint({
element: document.getElementById('target'),
handler: handler,
offset: '50%'
});
});
test('Handler is called on scroll past waypoint', () => {
window.scrollTo(0, 600);
window.dispatchEvent(new Event('scroll'));
expect(handler).toHaveBeenCalled();
});
test('Handler is not called before reaching waypoint', () => {
window.scrollTo(0, 400);
window.dispatchEvent(new Event('scroll'));
expect(handler).not.toHaveBeenCalled();
});
});
Такой подход обеспечивает полное покрытие юнит-тестами поведения Waypoints, проверку корректного срабатывания, динамических изменений DOM и управления состоянием точек.