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

Архитектура E2E тестирования картографических приложений

E2E-тестирование веб-карт строится вокруг проверки полного пользовательского сценария: от загрузки страницы до взаимодействия с картой, слоями, объектами и сервисами геокодирования. При использовании HERE Technologies ключевыми становятся корректность отображения тайлов, работа WebGL-рендеринга, асинхронная загрузка данных и стабильность взаимодействия с API.

Картографические приложения принципиально отличаются от классических UI-систем высокой степенью асинхронности и визуальной зависимостью. Карта не является статичным DOM-деревом: значительная часть сцены формируется внутри canvas/WebGL контекста, что требует специализированного подхода к проверке.


Основные уровни E2E проверки карт

Полноценный тест карты включает несколько слоёв проверки:

  • загрузка и инициализация карты
  • корректность базового тайлового слоя
  • работа маркеров и объектов (markers, polygons, polylines)
  • взаимодействие пользователя (zoom, pan, rotate)
  • загрузка внешних данных (GeoJSON, WMS, vector tiles)
  • корректность событий API (tap, pointer events)
  • визуальная целостность сцены

Каждый уровень требует отдельной стратегии валидации, так как DOM не отражает всю структуру карты.


Особенности тестирования HERE Maps API в браузере

JavaScript SDK HERE Maps строится вокруг WebGL-рендеринга и тайловой системы. Это создаёт ряд особенностей:

  • асинхронная подгрузка слоёв
  • зависимость от сетевых тайловых сервисов
  • использование canvas вместо DOM-элементов
  • наличие WebGL-специфичных артефактов
  • нестабильность при headless-рендеринге

Из-за этого стандартные проверки через селекторы DOM оказываются недостаточными. Проверка должна комбинировать API-состояние карты и визуальные методы контроля.


Инструменты для E2E тестирования

На практике используются следующие стековые решения:

Playwright

  • стабильная работа с canvas
  • встроенные скриншот-тесты
  • контроль сетевых запросов
  • эмуляция устройств и геолокации

Cypress

  • удобная отладка UI-сценариев
  • перехват HTTP-запросов
  • ограниченная работа с WebGL, но достаточная для базовых сценариев

Selenium WebDriver

  • кросс-браузерная проверка
  • высокая гибкость окружений
  • более сложная настройка синхронизации

Дополнительно применяются инструменты визуального сравнения (Percy, Applitools) для регрессионной проверки картографического рендеринга.


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

Ключевой проблемой становится детерминированная инициализация карты. В отличие от UI-компонентов, карта требует загрузки внешних ресурсов.

Типовой сценарий включает:

  • ожидание загрузки SDK
  • инициализация карты с фиксированными координатами
  • отключение анимаций
  • фиксация уровня zoom
  • замена реальных тайлов на мок-сервер

Пример базовой структуры теста:

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

test('карта инициализируется и отображает центр', async ({ page }) => {
  await page.goto('http://localhost:3000');

  // ожидание canvas карты
  const canvas = await page.waitForSelector('canvas');

  // проверка загрузки API состояния
  await page.waitForFunction(() => window.mapReady === true);

  expect(canvas).toBeTruthy();
});

Работа с асинхронной загрузкой тайлов

Основная сложность заключается в том, что карта может считаться “загруженной”, но тайлы продолжают подгружаться.

Для стабилизации тестов применяются стратегии:

  • перехват HTTP запросов к tile-серверам
  • ожидание завершения сетевой активности
  • фиксация mock-ответов
  • отключение live traffic через staging API ключ

Пример перехвата запросов:

await page.route('**/maptile/**', route => {
  route.fulfill({
    status: 200,
    body: mockTileResponse,
  });
});

Это позволяет добиться воспроизводимости визуального состояния карты.


Тестирование взаимодействий пользователя

Карта активно использует жесты и pointer events:

  • drag (pan)
  • wheel (zoom)
  • pinch (mobile)
  • double click zoom

Эти сценарии тестируются через эмуляцию событий браузера.

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

test('zoom изменяет масштаб карты', async ({ page }) => {
  await page.goto('http://localhost:3000');

  const canvas = await page.locator('canvas');

  const before = await page.evaluate(() => window.map.getZoom());

  await canvas.hover();
  await page.mouse.wheel(0, -500);

  const after = await page.evaluate(() => window.map.getZoom());

  expect(after).toBeGreaterThan(before);
});

Проверка объектов на карте

Маркеры и графические объекты часто не представлены в DOM, поэтому проверка идёт через API карты.

Типовые стратегии:

  • хранение ссылок на созданные объекты
  • экспорт состояния карты в window
  • проверка геометрии через SDK
  • анализ слоёв (layers)

Пример:

const markersCount = await page.evaluate(() => {
  return window.mapObjects.markers.length;
});

expect(markersCount).toBe(3);

Визуальное регрессионное тестирование

Наиболее надёжный способ проверки карт — snapshot testing.

Подход включает:

  • фиксированную камеру (lat/lng/zoom)
  • отключение анимаций
  • одинаковый viewport
  • сравнение скриншотов
test('визуальная стабильность карты', async ({ page }) => {
  await page.goto('http://localhost:3000');

  await page.waitForFunction(() => window.mapReady);

  expect(await page.screenshot()).toMatchSnapshot('map.png');
});

Основная проблема — чувствительность к антиалиасингу и рендеринг WebGL. Поэтому часто применяют пороговые сравнения diff-изображений.


Мокирование геокодинга и внешних API

Картографические приложения часто зависят от:

  • геокодинга
  • маршрутизации
  • поиска POI
  • traffic layers

В E2E тестах такие сервисы заменяются стабильными фикстурами.

await page.route('**/geocode', route => {
  route.fulfill({
    contentType: 'application/json',
    body: JSON.stringify({
      items: [{ title: 'Test Location', position: { lat: 10, lng: 10 } }]
    })
  });
});

Это исключает флуктуации сети и внешних данных.


Стабилизация WebGL-рендеринга в тестах

WebGL создаёт дополнительные проблемы:

  • различия между GPU
  • headless rendering artifacts
  • отсутствие контекста в CI

Решения:

  • запуск Chromium с флагами --use-gl=swiftshader
  • отключение аппаратного ускорения
  • фиксированные версии драйверов в Docker
  • использование software rendering

В CI окружениях часто применяются контейнеры с преднастроенным браузером.


Организация тестовой архитектуры

Масштабируемая структура E2E тестов для карт включает:

  • слой инициализации карты (map bootstrap)
  • слой mock-сервисов
  • слой сценариев взаимодействия
  • слой визуальных проверок
  • слой аналитики результатов

Такое разделение позволяет минимизировать дублирование и повысить стабильность тестов при изменении API.


Обработка нестабильности тестов (flaky tests)

Flaky-тесты в картографических системах возникают из-за:

  • сетевых задержек тайлов
  • асинхронной отрисовки
  • различий в WebGL
  • анимаций камеры

Методы борьбы:

  • отключение анимаций карты
  • фиксированные координаты
  • ожидание idle-состояния
  • повторная проверка состояния после задержки
  • строгий контроль сетевых моков

CI/CD интеграция E2E карт

При интеграции в CI учитываются:

  • headless браузеры
  • ограниченные ресурсы CPU/GPU
  • параллельный запуск тестов
  • кеширование тайлов

Часто применяют стратегию:

  • unit тесты — быстрые проверки логики
  • integration — API карты
  • E2E — полный сценарий с визуальной проверкой

Такое разделение позволяет контролировать стоимость и стабильность тестирования без деградации качества.