E2E тестирование поведения

Headroom.js — это библиотека на JavaScript, предназначенная для управления поведением заголовков (header) страницы при прокрутке. Основная задача библиотеки — динамическое скрытие и отображение шапки в зависимости от направления и скорости прокрутки. Она позволяет создавать интерфейсы с экономией пространства, улучшая восприятие контента пользователем.

Ключевое поведение реализуется через добавление и удаление CSS-классов в зависимости от состояния прокрутки:

  • headroom--pinned — заголовок закреплён и видим.
  • headroom--unpinned — заголовок скрыт при прокрутке вниз.
  • headroom--top — страница находится в верхней точке.
  • headroom--not-top — страница прокручена вниз.
  • headroom--bottom — страница достигла нижней границы.

Библиотека использует объект Headroom, который принимает DOM-элемент и конфигурацию. Конфигурация включает параметры: tolerance, offset, classes, scroller и события обратного вызова (onPin, onUnpin, onTop, onNotTop).


Настройка и инициализация для тестирования

Для проведения E2E тестирования необходимо подготовить окружение, в котором можно имитировать прокрутку и наблюдать изменения классов. Простейшая инициализация выглядит так:

import Headroom from 'headroom.js';

const header = document.querySelector('header');
const headroom = new Headroom(header, {
  tolerance: 5,
  offset: 100,
  classes: {
    pinned: 'headroom--pinned',
    unpinned: 'headroom--unpinned',
    top: 'headroom--top',
    notTop: 'headroom--not-top'
  }
});

headroom.init();

В E2E тестах важно проверять три ключевых сценария:

  1. Прокрутка вниз скрывает шапку (headroom--unpinned).
  2. Прокрутка вверх показывает шапку (headroom--pinned).
  3. Достижение верхней или нижней границы страницы корректно изменяет классы headroom--top и headroom--bottom.

Использование E2E фреймворков

Для автоматизированного тестирования поведения Headroom.js подходят такие инструменты, как Cypress, Playwright или Selenium. Основная задача — имитация событий прокрутки и проверка динамического изменения DOM.

Пример Cypress-теста:

describe('Headroom.js behavior', () => {
  beforeEach(() => {
    cy.visit('/'); 
    cy.get('header').as('header');
  });

  it('should hide header on scroll down', () => {
    cy.window().then(win => {
      win.scrollTo(0, 200);
    });
    cy.get('@header').should('have.class', 'headroom--unpinned');
  });

  it('should show header on scroll up', () => {
    cy.window().then(win => {
      win.scrollTo(0, 200);
      win.scrollTo(0, 0);
    });
    cy.get('@header').should('have.class', 'headroom--pinned');
  });

  it('should set top class when at top', () => {
    cy.window().then(win => win.scrollTo(0, 0));
    cy.get('@header').should('have.class', 'headroom--top');
  });
});

Ключевые моменты:

  • Имитация прокрутки через scrollTo позволяет проверить реакцию Headroom.js без реального участия пользователя.
  • Проверка классов через should('have.class', …) гарантирует, что библиотека корректно обновляет состояние элемента.
  • Асинхронные вызовы нужно правильно синхронизировать, так как Headroom.js реагирует на события scroll с небольшой задержкой (throttle).

Тестирование событий обратного вызова

Headroom.js поддерживает обратные вызовы, которые удобно использовать для интеграционных проверок:

const headroom = new Headroom(header, {
  onPin: () => console.log('Pinned'),
  onUnpin: () => console.log('Unpinned'),
  onTop: () => console.log('Top'),
  onNotTop: () => console.log('Not top')
});

headroom.init();

В E2E тестах эти события проверяются с помощью spy-функций:

const onPin Spy = cy.spy().as('onPinSpy');
const headroom = new Headroom(header, { onPin: onPinSpy });
headroom.init();

cy.window().then(win => win.scrollTo(0, 0));
cy.get('@onPinSpy').should('have.been.called');

Такой подход позволяет убедиться, что логика библиотеки не нарушена при различных сценариях прокрутки.


Тонкости и рекомендации для тестирования

  • Throttle и Debounce: Headroom.js использует throttling для обработки событий scroll. Тесты должны учитывать небольшую задержку между прокруткой и обновлением классов.
  • Масштабируемость тестов: Для длинных страниц с динамическим контентом следует проверять поведение в разных точках прокрутки, включая промежуточные значения offset.
  • Тестирование на разных браузерах: Важная практика — проверять корректность поведения на Chrome, Firefox, Safari, так как обработка scroll-ивентов может немного отличаться.
  • Скрытие и отображение через CSS: При тестировании стоит убедиться, что классы действительно влияют на визуальное состояние шапки, проверяя свойства transform или top.

Интеграция с CI/CD

Для E2E тестирования Headroom.js в CI/CD стоит:

  1. Поднять окружение с браузером без интерфейса (Headless Chrome / Chromium).
  2. Прогонять тесты с прокруткой через фреймворки типа Cypress или Playwright.
  3. Логировать изменения классов и события обратного вызова.
  4. В случае отказа теста — делать скриншоты состояния DOM для анализа.

Эта стратегия обеспечивает стабильность UI и предотвращает регрессии в поведении заголовков при внесении изменений в фронтенд.