228 lines
14 KiB
Markdown
228 lines
14 KiB
Markdown
---
|
||
type: test-report
|
||
work_item_id: ET-002
|
||
version: 1
|
||
status: pass
|
||
tester: "agent:tester"
|
||
date: 2026-05-21
|
||
commit_tested: 8c17a4f
|
||
verdict: PASS
|
||
---
|
||
|
||
# Test Report — ET-002
|
||
|
||
## Verdict: **PASS** → `stage:ready-to-deploy`
|
||
|
||
Полный регресс зелёный: **14 passed, 4 skipped, 0 failed**, lint чистый,
|
||
JS-юнит-тесты POI 7/7 pass, тест-окружение отвечает 200. Блокирующих
|
||
багов (P0/P1) не найдено.
|
||
|
||
Тест-кейсы TP-01..TP-04 и TP-08 из `04-test-plan.yaml` исполнены и
|
||
прошли. e2e-кейсы TP-05..TP-07, TP-09 **не исполнялись** — в репозитории
|
||
нет Playwright-инфраструктуры, а `07-infra-requirements.md §6` запрещает
|
||
новые npm-пакеты (конфликт двух approved-артефактов, зафиксирован
|
||
reviewer'ом как R-01/P2). Поведенческая суть этих сценариев покрыта
|
||
unit- и статическими тестами. На merge/деплой ET-002 не влияет.
|
||
|
||
## Окружение
|
||
|
||
- **Дата прогона:** 2026-05-21
|
||
- **Ветка:** `feature/ET-002-poi-toggle`
|
||
- **Коммит:** `8c17a4f` (`feat(web): add POI visibility checkbox to terrain popup`;
|
||
взят из `12-review.md` — `git` в окружении тестера недоступен)
|
||
- **Python:** 3.12.13
|
||
- **pytest:** 8.3.3 (plugins: asyncio-1.3.0, anyio-4.13.0)
|
||
- **Node:** v22.22.2 (`node --test`)
|
||
- **ruff:** 0.15.14
|
||
- **test-env:** https://openclaw.mva154.duckdns.org/enduro/ → HTTP 200
|
||
|
||
## Healthcheck
|
||
|
||
| Среда | URL | Код |
|
||
|---|---|---|
|
||
| local dev | http://localhost:5556/health | connection refused (dev не поднят — ОК, прогон оффлайн) |
|
||
| test | https://openclaw.mva154.duckdns.org/enduro/ | 200 |
|
||
| test API | https://openclaw.mva154.duckdns.org/enduro/api/health | 200 `{"status":"ok","db_exists":true}` |
|
||
|
||
ET-002 — фронтенд-изменение; в test задеплоен `main`, поэтому healthcheck
|
||
подтверждает только живость окружения, а не наличие фичи (фича попадёт
|
||
в test штатной перевыкладкой после merge).
|
||
|
||
## Команды запуска
|
||
|
||
```bash
|
||
# Unit + integration (эквивалент make test)
|
||
python -m pytest tests/ -v
|
||
|
||
# JS behavioral unit-тесты POI (TP-01..TP-04)
|
||
node --test tests/unit/poi_toggle.test.js
|
||
|
||
# Lint
|
||
ruff check src/
|
||
ruff check tests/
|
||
```
|
||
|
||
## Результаты pytest
|
||
|
||
`python -m pytest tests/ -v` → **14 passed, 4 skipped, 1 warning in 0.51s**
|
||
|
||
| # | Тест | Тип | Результат |
|
||
|---|---|---|---|
|
||
| 1 | `test_routing_barriers.py::test_lua_syntax` | unit (структура lua) | **PASS** |
|
||
| 2 | `test_routing_barriers.py::test_blocked_barriers_match_trz` | static AC | **PASS** |
|
||
| 3 | `test_routing_barriers.py::test_excluded_highways_match_trz` | static AC | **PASS** |
|
||
| 4 | `test_routing_barriers.py::test_route_avoids_barrier` | integration | **SKIP** (OSRM недоступен) |
|
||
| 5 | `test_routing_barriers.py::test_route_no_footway` | integration | **SKIP** (OSRM недоступен) |
|
||
| 6 | `test_routing_barriers.py::test_route_allows_cattle_grid` | integration | **SKIP** (OSRM недоступен) |
|
||
| 7 | `test_routing_barriers.py::test_existing_route_works` | regression | **SKIP** (OSRM недоступен) |
|
||
| 8 | `test_health.py::test_health_endpoint` | unit (async) | **PASS** |
|
||
| 9 | `test_poi_toggle.py::test_poi_checkbox_present_in_html` | static (REQ-F-01) | **PASS** |
|
||
| 10 | `test_poi_toggle.py::test_poi_checkbox_checked_by_default` | static (REQ-F-02) | **PASS** |
|
||
| 11 | `test_poi_toggle.py::test_poi_checkbox_placed_after_trails_separated_by_hr` | static (REQ-F-01) | **PASS** |
|
||
| 12 | `test_poi_toggle.py::test_poi_checkbox_uses_shared_style_class` | static (UI-спец) | **PASS** |
|
||
| 13 | `test_poi_toggle.py::test_poi_functions_defined` | static (ADR-0001) | **PASS** |
|
||
| 14 | `test_poi_toggle.py::test_poi_logic_uses_localstorage_key` | static (REQ-F-05) | **PASS** |
|
||
| 15 | `test_poi_toggle.py::test_poi_logic_reuses_layer_state_and_groups` | static (ADR п.3-4) | **PASS** |
|
||
| 16 | `test_poi_toggle.py::test_restore_poi_state_wired_into_init` | static (REQ-F-06) | **PASS** |
|
||
| 17 | `test_poi_toggle.py::test_poi_visibility_toggled_via_set_layout_property` | static (ADR п.1) | **PASS** |
|
||
| 18 | `test_poi_toggle.py::test_js_unit_tests_pass` | behavioral (Node-раннер) | **PASS** |
|
||
|
||
**4 SKIP** — интеграционные тесты роутинга ET-001; требуют поднятого OSRM
|
||
(`OSRM_URL`, по умолчанию `http://172.22.0.1:5559`), который в окружении
|
||
тестера недоступен. Это штатное поведение (`test_routing_barriers.py`
|
||
помечает их `skip`, чтобы CI без инфраструктуры не падал). ET-002 —
|
||
фронтенд-изменение, на роутинг влиять не может; к регрессу не относится.
|
||
|
||
Предупреждение `PendingDeprecationWarning` из `starlette/formparsers.py` —
|
||
внешняя зависимость, к ET-002 отношения не имеет, не блокирует.
|
||
|
||
## Результаты JS unit-тестов (TP-01..TP-04)
|
||
|
||
`node --test tests/unit/poi_toggle.test.js` → **# pass 7, # fail 0**
|
||
|
||
Тесты исполняют **реальный** код POI-блока из `src/web/app.js` (блок
|
||
извлекается по маркерам `ET-002 POI visibility block` и оборачивается
|
||
через `new Function` с инъекцией моков).
|
||
|
||
| Тест | TC | Результат |
|
||
|---|---|---|
|
||
| снятый чекбокс скрывает слои POI и сохраняет `0` | TP-01 | **PASS** |
|
||
| установленный чекбокс показывает слои POI и сохраняет `1` | TP-02 | **PASS** |
|
||
| `restorePoiState()` при `poi-visible=0` скрывает POI | TP-03 | **PASS** |
|
||
| `restorePoiState()` без ключа включает POI по умолчанию | TP-04 | **PASS** |
|
||
| `restorePoiState()` при `poi-visible=1` показывает POI | доп. | **PASS** |
|
||
| `onPoiCheckbox()` меняет только `poi-circles`/`poi-labels` | доп. (дух TP-08) | **PASS** |
|
||
| `applyPoiVisibility()` синхронизирует `layerState` без слоёв | доп. | **PASS** |
|
||
|
||
## Результаты lint
|
||
|
||
| Команда | Результат |
|
||
|---|---|
|
||
| `ruff check src/` | **All checks passed!** |
|
||
| `ruff check tests/` | **All checks passed!** |
|
||
|
||
## Покрытие тест-плана (04-test-plan.yaml)
|
||
|
||
| TC | Тип | Исполнение | Статус |
|
||
|---|---|---|---|
|
||
| **TP-01** | unit | JS-тест «TP-01» (через `test_js_unit_tests_pass`) | **PASS** |
|
||
| **TP-02** | unit | JS-тест «TP-02» | **PASS** |
|
||
| **TP-03** | unit | JS-тест «TP-03» | **PASS** |
|
||
| **TP-04** | unit | JS-тест «TP-04» | **PASS** |
|
||
| **TP-05** | e2e | **BLOCKED** (нет Playwright). Покрыто статически: `test_poi_checkbox_present_in_html`, `test_poi_checkbox_placed_after_trails_separated_by_hr` | COVERED (alt) |
|
||
| **TP-06** | e2e | **BLOCKED** (нет Playwright). Покрыто поведенчески: JS «TP-01»/«TP-02», «меняет только poi-circles/poi-labels» | COVERED (alt) |
|
||
| **TP-07** | e2e | **BLOCKED** (нет Playwright). Покрыто поведенчески: JS «TP-03» (`restorePoiState` при `poi-visible=0`) | COVERED (alt) |
|
||
| **TP-08** | integration | JS «onPoiCheckbox() меняет только слои poi-circles и poi-labels» — изоляция чужих слоёв подтверждена | **PASS** (alt) |
|
||
| **TP-09** | e2e | **BLOCKED** (нет Playwright). Класс `terrain-checkbox` подтверждён статически; по touch-target см. P3-2 | PARTIAL |
|
||
|
||
**Исполнено и пройдено: TP-01..TP-04, TP-08 (5/9).**
|
||
**e2e TP-05..TP-07, TP-09 (4/9) — заблокированы инфраструктурой**, их
|
||
поведение покрыто unit/статикой. Прямой инструментальной проверки в
|
||
реальном браузере не было.
|
||
|
||
## Соответствие Acceptance Criteria
|
||
|
||
| AC | Описание | Источник проверки | Статус |
|
||
|---|---|---|---|
|
||
| AC-01 | Чекбокс в попапе после «Тропы», отделён `<hr>` | `test_poi_checkbox_placed_after_trails_separated_by_hr` | **PASS** |
|
||
| AC-02 | POI включены по умолчанию | `test_poi_checkbox_checked_by_default` + JS «TP-04» | **PASS** |
|
||
| AC-03 | Скрытие POI → `visibility: none` | JS «TP-01» | **PASS** |
|
||
| AC-04 | Показ POI → `visibility: visible` | JS «TP-02» | **PASS** |
|
||
| AC-05 | Состояние сохраняется после перезагрузки | JS «TP-03» (`restorePoiState` при `poi-visible=0`) | **PASS** |
|
||
| AC-06 | Восстановление включённого состояния | JS «restorePoiState при poi-visible=1» | **PASS** |
|
||
| AC-07 | Не ломает существующие чекбоксы | JS «меняет только poi-circles/poi-labels»; HTML-изменения аддитивны | **PASS** |
|
||
| AC-08 | Синхронизация с `layerState.poi` | JS «TP-01»/«TP-02» + «applyPoiVisibility без слоёв» | **PASS** |
|
||
|
||
Все 8 критериев имеют поведенческое покрытие; ни один не нарушен.
|
||
Браузерная (e2e) проверка AC-01/03/04/05 ограничена отсутствием
|
||
Playwright — поведение подтверждено на уровне реального кода POI-блока.
|
||
|
||
## Найденные баги
|
||
|
||
### P0 (блокирующие)
|
||
Нет.
|
||
|
||
### P1 (критические)
|
||
Нет.
|
||
|
||
### P2 (важные)
|
||
|
||
**T-01 (= R-01 из `12-review.md`) — e2e TP-05..TP-09 не исполнимы.**
|
||
`04-test-plan.yaml` определяет TP-05..TP-09 как `type: e2e`, но
|
||
`07-infra-requirements.md §6` запрещает новые npm-пакеты, а
|
||
Playwright-инфраструктуры в репозитории нет (проверено: нет
|
||
`package.json`, `node_modules`, бинаря `playwright`, `npx`). Это конфликт
|
||
двух **approved**-артефактов, а не дефект разработки. Поведение покрыто
|
||
unit/статикой.
|
||
**Действие:** Analyst — согласовать `04-test-plan.yaml` с
|
||
`07-infra-requirements.md` (пометить TP-05..09 как покрытые альтернативно
|
||
либо завести инфра-задачу на Playwright). **Merge/деплой ET-002 не
|
||
блокирует.**
|
||
|
||
### P3 (косметика / наблюдения)
|
||
|
||
1. **(= R-02 из `12-review.md`)** `app.js:2849` —
|
||
`const poiOn = stored === null || stored === '1';`: нештатное значение
|
||
ключа `poi-visible` трактуется как «скрыть». Надёжнее
|
||
`stored !== '0'` (деградация к дефолту «показать», REQ-F-02).
|
||
Крайний кейс — ключ пишет только это приложение. Не блокирует.
|
||
2. **REQ-NF-03 (touch target ≥ 44px)** — `.terrain-checkbox`
|
||
(`app.css:806`) при `padding:8px` и `font-size:15px` даёт высоту
|
||
строки ≈ 35px, что ниже ориентира 44px. Однако чекбокс POI
|
||
использует **тот же** класс, что и все соседние чекбоксы попапа
|
||
(Тени/Перепады/Грунтовки/Тропы) — **регрессии нет**, кликабельна вся
|
||
строка-`<label>`. Точная проверка на реальном устройстве (TP-09)
|
||
невозможна без e2e. Если 44px критичны — это пред-существующий
|
||
UX-вопрос ко всему попапу, отдельной задачей. Не блокирует ET-002.
|
||
3. **Окружение тестера.** Пакеты `shapely`, `mapbox-vector-tile`,
|
||
`httpx` (`requirements.txt`) и `pytest-asyncio`, `ruff`
|
||
(`pyproject.toml [dev]`) не были предустановлены в песочнице — без
|
||
`shapely` падал сбор `test_health.py` (импорт `src.api.main`).
|
||
Тестер доустановил их по манифестам проекта, после чего регресс
|
||
прошёл полностью. Это дефект провижининга окружения, **не дефект
|
||
ET-002**. CI обязан выполнять `pip install -r requirements.txt` и
|
||
`.[dev]` перед `make test`.
|
||
|
||
## Замечания тестера
|
||
|
||
- Прогон выполнен против локального репозитория без поднятого dev-сервера
|
||
(`make test` оффлайн). Backend не затронут (ET-002 — только `src/web/`).
|
||
- Ручная сверка реализации: `index.html:56-60` — `<hr>` + чекбокс
|
||
`poi-visible-cb` (`checked`, класс `terrain-checkbox`) сразу после
|
||
`trails-path-cb`; `app.js:2800-2854` — POI-блок с `applyPoiVisibility`,
|
||
`onPoiCheckbox`, `restorePoiState`; `restorePoiState()` подключён в 3
|
||
точках восстановления (`app.js:131, 2950, 2963`). Соответствует ТЗ,
|
||
ADR-0001 и выводам `12-review.md`.
|
||
- Тесты не подгонялись под код; на prom ничего не запускалось.
|
||
|
||
## Итог
|
||
|
||
**Verdict: PASS** → `stage:ready-to-deploy`.
|
||
|
||
Все исполнимые тест-кейсы (TP-01..04, TP-08), все 8 acceptance-критериев
|
||
и lint — зелёные; блокирующих (P0/P1) багов нет. Незакрытые e2e-кейсы
|
||
(TP-05..07, TP-09) заблокированы инфраструктурным конфликтом
|
||
approved-артефактов (T-01/P2) — действие на стороне Analyst, на ET-002
|
||
не влияет. Готово к штатной перевыкладке фронтенда в test/prom согласно
|
||
`07-infra-requirements.md`.
|