E2E-тестирование скролла

Locomotive Scroll — это современная библиотека для плавного и управляемого скроллинга, которая позволяет реализовать параллакс-эффекты, фиксированные элементы и кастомную прокрутку. Для E2E-тестирования необходимо сначала корректно интегрировать библиотеку в проект.

import LocomotiveScroll from 'locomotive-scroll';

const scroll = new LocomotiveScroll({
  el: document.querySelector('[data-scroll-container]'),
  smooth: true,
  multiplier: 1,
  smartphone: { smooth: true },
  tablet: { smooth: true }
});

Ключевые параметры:

  • el — контейнер, на который распространяется кастомный скролл. Обычно это главный блок страницы.
  • smooth — включает плавную прокрутку.
  • multiplier — коэффициент скорости прокрутки.
  • smartphone и tablet — настройки для мобильных устройств, важно учитывать их при тестировании адаптивности.

Для E2E-тестов важно убедиться, что инициализация проходит до начала взаимодействия с элементами страницы.


События и методы для тестирования

Locomotive Scroll генерирует ряд событий, которые критичны для проверки корректной работы скролла.

Основные события

  • scroll — срабатывает при любой прокрутке.
  • call — позволяет отслеживать вызовы кастомных функций при достижении определённых точек.
  • resize — событие при изменении размера окна, необходимо для проверки адаптивного поведения.
  • scrollTo — метод для программного перемещения к элементу.

Пример подписки на события:

scroll.on('scroll', (obj) => {
  console.log('Текущая позиция скролла:', obj.scroll.y);
});

scroll.on('call', (func, dir, obj) => {
  console.log(`Вызов функции ${func} при прокрутке ${dir}`);
});

Для E2E-тестирования удобно замещать функции console.log на assert или expect в тестовом фреймворке.


Интеграция с Cypress и Playwright

E2E-тестирование скролла требует работы с асинхронными событиями и ожиданиями. Наиболее распространённые подходы включают использование Cypress или Playwright.

Пример Cypress

describe('Тест скролла Locomotive', () => {
  it('Прокрутка к элементу работает корректно', () => {
    cy.visit('/test-page');
    
    cy.window().then((win) => {
      const scroll = win.scroll; // предполагается, что scroll глобально доступен
      scroll.scrollTo(document.querySelector('#target-element'));
    });

    cy.get('#target-element').should('be.visible');
  });
});

Особенности:

  • Locomotive Scroll использует transform для прокрутки, поэтому стандартные методы .scrollIntoView() могут не сработать.
  • В E2E-тестах нужно опираться на события библиотеки (scroll, call) или проверять позицию через getBoundingClientRect().

Пример Playwright

import { test, expect } from '@playwright/test';

test('Проверка скролла Locomotive', async ({ page }) => {
  await page.goto('/test-page');
  
  const target = await page.$('#target-element');
  await page.evaluate((el) => {
    window.scroll.scrollTo(el);
  }, target);

  const box = await target.boundingBox();
  expect(box.y).toBeLessThan(100); // элемент в верхней части окна
});

Проверка анимаций и параллакса

Locomotive Scroll часто используется вместе с анимациями через GSAP или Intersection Observer. Для E2E-тестов важно убедиться, что все анимации запускаются и завершаются корректно.

scroll.on('scroll', (obj) => {
  const elements = document.querySelectorAll('.animate-on-scroll');
  elements.forEach(el => {
    const rect = el.getBoundingClientRect();
    if (rect.top < window.innerHeight && rect.bottom > 0) {
      el.classList.add('active');
    }
  });
});

В тестах можно проверять наличие класса active или значение CSS-свойств через getComputedStyle.


Тестирование на разных устройствах и разрешениях

Locomotive Scroll имеет отдельные настройки для смартфонов и планшетов. E2E-тесты должны учитывать:

  • разную плотность пикселей (devicePixelRatio);
  • высоту и ширину экрана;
  • включение или отключение smooth для мобильных.

Пример проверки с Cypress:

cy.viewport('iphone-12');
cy.visit('/test-page');
cy.window().then((win) => {
  const scroll = win.scroll;
  expect(scroll.options.smartphone.smooth).to.be.true;
});

Рекомендации по стабильности тестов

  • Ждать окончания анимаций: использовать scroll.once('scroll', ...) или await для асинхронных операций.
  • Использовать уникальные селекторы: при работе с параллакс-элементами трансформы меняют позицию, стандартные селекторы могут быть ненадёжными.
  • Сохранять ссылку на объект scroll: повторная инициализация может привести к конфликтам.
  • Логирование событий: временное логирование помогает понять, какие события вызываются в тесте.

Проверка scrollTo и кастомных вызовов

Метод scrollTo является основным инструментом для управления прокруткой в тестах:

scroll.scrollTo('#section-3', {
  offset: -100,
  duration: 800,
  easing: [0.25, 0.0, 0.35, 1.0]
});

Проверки:

  • Элемент достигает правильной позиции (top + offset).
  • Продолжительность анимации соответствует ожиданиям.
  • Кастомные easing-функции корректно применяются (можно проверить промежуточные позиции через requestAnimationFrame).