Files
enduro-trails/docs/work-items/ET-014/04b-ui-test-cases.md
claude-bot e796a6cb03
All checks were successful
CI / lint (push) Successful in 5s
CI / test (push) Successful in 10s
CI / build (push) Successful in 2s
analyst(ET): auto-commit from analyst run_id=87
2026-06-04 11:03:45 +00:00

9.5 KiB
Raw Blame History

UI Test Cases — ET-014

Playwright UI тест-кейсы для визуальной приёмки фикса z-index. Все тесты выполняются на test-среде https://openclaw.mva154.duckdns.org/enduro/.

Общие соображения:

  • Карта инициализируется ~24 секунды (MapLibre + загрузка стилей/тайлов). Везде где идёт первый navigate — пауза 4000 мс перед действиями.
  • Селекторы взяты из src/web/index.html.

TC-UI-01 — Mobile: фильтры открываются ПОВЕРХ панели слоёв

  • type: ui
  • viewport: mobile
  • viewport-size: 390 × 844
  • theme: dark (по умолчанию)

Шаги:

  1. navigate: https://openclaw.mva154.duckdns.org/enduro/
  2. wait: 4000
  3. screenshot: 01-map-loaded
  4. click: #terrain-toggle
  5. wait: 400
  6. screenshot: 02-terrain-popup-open
  7. check-visual: видна панель #terrain-popup с чекбоксами; visible(#public-tracks-cb) === true
  8. click: #public-tracks-cb
  9. wait: 300
  10. check-visual: visible(#public-tracks-filters-btn) === true (кнопка «Фильтры…» появилась)
  11. click: #public-tracks-filters-btn
  12. wait: 600
  13. screenshot: 03-filters-sheet-opened
  14. check-visual: #sheet-gps-filters имеет класс open; заголовок «Фильтры публичных треков», секции «ТИП АКТИВНОСТИ», «ИСТОЧНИК», «ЦВЕТ ЛИНИЙ» и кнопка полностью видны в viewport
  15. check-visual: document.elementFromPoint(195, 600) принадлежит #sheet-gps-filters или его потомкам (НЕ #terrain-popup)
  16. check-visual: bounding box #sheet-gps-filters не пересекается с видимой частью #terrain-popup, либо если пересекается — sheet поверх (через elementFromPoint в центрах пересечения)

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


TC-UI-02 — Desktop: фильтры открываются ПОВЕРХ панели слоёв

  • type: ui
  • viewport: desktop
  • viewport-size: 1440 × 900
  • theme: dark

Шаги:

  1. navigate: https://openclaw.mva154.duckdns.org/enduro/
  2. wait: 4000
  3. click: #terrain-toggle
  4. wait: 400
  5. click: #public-tracks-cb
  6. wait: 300
  7. click: #public-tracks-filters-btn
  8. wait: 600
  9. screenshot: desktop-filters-opened
  10. check-visual: #sheet-gps-filters виден слева (получить bbox через getBoundingClientRect, ожидание: left ≤ 80, right ≥ 380)
  11. check-visual: document.elementFromPoint(bbox.left + bbox.width/2, bbox.top + bbox.height/2) принадлежит #sheet-gps-filters или его потомкам

Ожидаемый результат: на desktop sheet открыт как боковая панель, terrain-popup не перекрывает.


TC-UI-03 — Закрытие фильтров кнопкой ✕

  • type: ui
  • viewport: mobile
  • viewport-size: 390 × 844

Шаги:

  1. navigate: https://openclaw.mva154.duckdns.org/enduro/
  2. wait: 4000
  3. click: #terrain-toggle
  4. wait: 300
  5. click: #public-tracks-cb
  6. wait: 300
  7. click: #public-tracks-filters-btn
  8. wait: 500
  9. click: #sheet-gps-filters .sheet-close
  10. wait: 600
  11. screenshot: after-close
  12. check-visual: #sheet-gps-filters НЕ имеет класса open
  13. check-visual: #sheet-backdrop НЕ имеет класса visible
  14. check-visual: document.elementFromPoint(195, 600) принадлежит #map или его canvas-потомку (карта снова интерактивна)

Ожидаемый результат: возврат к карте, никаких артефактов.


TC-UI-04 — Повторное открытие/закрытие фильтров

  • type: ui
  • viewport: mobile
  • viewport-size: 390 × 844

Шаги:

  1. navigate: https://openclaw.mva154.duckdns.org/enduro/
  2. wait: 4000
  3. click: #terrain-toggle
  4. wait: 300
  5. click: #public-tracks-cb
  6. wait: 300
  7. click: #public-tracks-filters-btn
  8. wait: 500
  9. click: #sheet-gps-filters .sheet-close
  10. wait: 500
  11. click: #terrain-toggle
  12. wait: 300
  13. click: #public-tracks-filters-btn
  14. wait: 500
  15. screenshot: second-open
  16. check-visual: #sheet-gps-filters имеет класс open, виден полностью, элемент в центре sheet'а через elementFromPoint принадлежит sheet'у
  17. click: #sheet-gps-filters .sheet-close
  18. wait: 500
  19. click: #terrain-toggle
  20. wait: 300
  21. click: #public-tracks-filters-btn
  22. wait: 500
  23. check-visual: третий цикл — sheet снова открыт корректно

Ожидаемый результат: 3 цикла open/close без деградации.


TC-UI-05 — Регрессия остальных bottom-sheets

  • type: ui
  • viewport: mobile
  • viewport-size: 390 × 844

Шаги:

  1. navigate: https://openclaw.mva154.duckdns.org/enduro/

  2. wait: 4000

  3. click: #tb-route

  4. wait: 400

  5. check-visual: #sheet-route имеет класс open, заголовок «Маршрут» виден

  6. screenshot: sheet-route

  7. click: #sheet-route .sheet-close

  8. wait: 400

  9. click: #tb-recon

  10. wait: 400

  11. check-visual: #sheet-recon имеет класс open

  12. screenshot: sheet-recon

  13. click: #sheet-recon .sheet-close

  14. wait: 400

  15. click: #tb-scenic

  16. wait: 400

  17. check-visual: #sheet-scenic имеет класс open

  18. screenshot: sheet-scenic

  19. click: #sheet-scenic .sheet-close

  20. wait: 400

  21. click: #tb-link

  22. wait: 400

  23. check-visual: #sheet-link имеет класс open

  24. screenshot: sheet-link

  25. click: #sheet-link .sheet-close

  26. wait: 400

  27. click: #tb-gpx

  28. wait: 400

  29. check-visual: #sheet-gpx имеет класс open

  30. screenshot: sheet-gpx

  31. click: #sheet-gpx .sheet-close

  32. wait: 400

Ожидаемый результат: все sheet'ы открываются и закрываются без артефактов и не «застревают».


TC-UI-06 — Светлая тема: фильтры поверх

  • type: ui
  • viewport: mobile
  • viewport-size: 390 × 844
  • theme: light

Шаги:

  1. navigate: https://openclaw.mva154.duckdns.org/enduro/
  2. wait: 4000
  3. click: #btn-theme
  4. wait: 500
  5. check-visual: document.body НЕ содержит класса theme-dark (или содержит theme-light)
  6. screenshot: 01-light-theme
  7. click: #terrain-toggle
  8. wait: 300
  9. click: #public-tracks-cb
  10. wait: 300
  11. click: #public-tracks-filters-btn
  12. wait: 500
  13. screenshot: 02-light-filters-open
  14. check-visual: #sheet-gps-filters имеет класс open, текст читаем (контраст), sheet полностью виден
  15. check-visual: elementFromPoint в центре sheet'а возвращает элемент внутри #sheet-gps-filters

Ожидаемый результат: поведение полностью аналогично тёмной теме, без визуальных дефектов на светлом фоне.


TC-UI-07 — Регрессия: terrain-popup сам по себе работает

  • type: ui
  • viewport: mobile
  • viewport-size: 390 × 844

Шаги:

  1. navigate: https://openclaw.mva154.duckdns.org/enduro/
  2. wait: 4000
  3. click: #terrain-toggle
  4. wait: 300
  5. screenshot: terrain-popup
  6. check-visual: #terrain-popup style.display !== 'none'; #terrain-toggle имеет класс active
  7. click: #terrain-hillshade-cb
  8. wait: 300
  9. check-visual: popup всё ещё открыт; чекбокс перешёл в состояние checked
  10. click: #base-btn-satellite
  11. wait: 600
  12. check-visual: popup всё ещё открыт; кнопка #base-btn-satellite имеет класс active
  13. click: #map // клик по карте вне popup
  14. wait: 400
  15. check-visual: #terrain-popup style.display === 'none'; #terrain-toggle БЕЗ класса active

Ожидаемый результат: без регрессий — popup ведёт себя как раньше.


TC-UI-08 — Регрессия: marker-dialog поверх

  • type: ui
  • viewport: mobile
  • viewport-size: 390 × 844

Шаги:

  1. navigate: https://openclaw.mva154.duckdns.org/enduro/
  2. wait: 4000
  3. click: #tb-marker
  4. wait: 400
  5. click: #map // тап по карте чтобы открыть dialog выбора типа метки
  6. wait: 500
  7. screenshot: marker-dialog
  8. check-visual: #marker-dialog виден (computed style: opacity > 0)
  9. check-visual: elementFromPoint в центре dialog'а возвращает элемент внутри #marker-dialog

Ожидаемый результат: marker-dialog корректно поверх всего.


Helpers / Assertions

Для check-visual использовать:

  • await page.locator(selector).isVisible() для базовой видимости.
  • await page.evaluate(() => document.elementFromPoint(x, y)?.closest('#sheet-gps-filters')?.id) для проверки stacking.
  • await page.locator('#sheet-gps-filters').evaluate(el => el.classList.contains('open')) для DOM-классов.
  • await expect(page).toHaveScreenshot(...) если используется baseline-сравнение.

Скриншоты сохранять в tests/e2e/__screenshots__/ET-014/<TC-UI-XX>/<step>.png.