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

261 lines
9.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`.