Files
enduro-trails/docs/work-items/ET-002/13-test-report.md
claude-bot c36ee9d39e
All checks were successful
CI / lint (push) Successful in 4s
CI / test (push) Successful in 5s
CI / lint (pull_request) Successful in 3s
CI / test (pull_request) Successful in 4s
CI / build (push) Successful in 3s
CI / build (pull_request) Successful in 1s
test(ET-002): test report PASS - all tests green, ready to deploy
2026-05-21 19:29:40 +03:00

228 lines
14 KiB
Markdown
Raw Permalink 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.
---
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`.