Files
wiki/tasks/enduro-trails/TEST_CASES_PHASE3.md
2026-05-04 10:20:01 +03:00

704 lines
24 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.
# Test Cases: Enduro Trails — Фаза 3 «Умный маршрут»
**Версия:** 1.0
**Дата:** 2026-05-04
**Автор:** Стрим 🌊
**Статус:** Готов к ревью
**Связан с:** BRD_PHASE3.md
---
## Соглашения
- **Precondition** — состояние системы до теста
- **Steps** — шаги воспроизведения
- **Expected** — ожидаемый результат
- **Priority:** P1 (блокер) / P2 (важный) / P3 (желательный)
- **URL:** `https://openclaw.mva154.duckdns.org/enduro/`
---
## TC-F03: Человекочитаемое время
### TC-F03-01 — Время меньше часа
**Priority:** P1
**Precondition:** Маршрут построен, OSRM вернул duration
**Input:** `duration_s = 2700` (45 минут)
**Expected:** отображается `45 мин`
**Not expected:** `2700`, `45`, `0 ч 45 мин`
---
### TC-F03-02 — Ровно час
**Priority:** P1
**Input:** `duration_s = 3600`
**Expected:** `1 ч`
**Not expected:** `1 ч 0 мин`, `60 мин`
---
### TC-F03-03 — Часы и минуты
**Priority:** P1
**Input:** `duration_s = 9300` (155 минут)
**Expected:** `2 ч 35 мин`
**Not expected:** `155 мин`, `2.58 ч`
---
### TC-F03-04 — Ровно сутки
**Priority:** P2
**Input:** `duration_s = 86400`
**Expected:** `1 дн`
**Not expected:** `24 ч`, `1 дн 0 ч`
---
### TC-F03-05 — Больше суток
**Priority:** P2
**Input:** `duration_s = 93600` (26 часов)
**Expected:** `1 дн 2 ч`
**Not expected:** `26 ч`, `1 дн 2 ч 0 мин`
---
### TC-F03-06 — Дни, часы и минуты
**Priority:** P2
**Input:** `duration_s = 165000` (2750 минут = 1 дн 21 ч 50 мин)
**Expected:** `1 дн 21 ч 50 мин`
**Not expected:** `2750 мин`, `45 ч 50 мин`
---
### TC-F03-07 — Ноль секунд (граничный случай)
**Priority:** P3
**Input:** `duration_s = 0`
**Expected:** `0 мин`
**Not expected:** ошибка, пустая строка, `NaN`
---
### TC-F03-08 — Время применено везде
**Priority:** P1
**Steps:**
1. Построить маршрут A→B
2. Проверить компактную карточку маршрута
3. Раскрыть карточку «Подробнее»
4. Проверить развёрнутую карточку
**Expected:** во всех местах время в формате `X ч Y мин`, нигде нет «минут» как числа > 60
---
## TC-F01: Альтернативные маршруты
### TC-F01-01 — Базовое построение альтернатив
**Priority:** P1
**Precondition:** Карта открыта, маркеры A и B не установлены
**Steps:**
1. Кликнуть на карте — установить точку A (например, Москва)
2. Кликнуть на карте — установить точку B (например, Тверь, ~170 км)
3. Нажать кнопку «Дикий путь» 🗺️
**Expected:**
- На карте появляются 25 маршрутов разными цветами
- Каждый маршрут имеет свой уникальный цвет из палитры (синий, зелёный, фиолетовый, оранжевый, серый)
- Появляется панель с карточками вариантов
- Каждая карточка содержит: номер варианта, цветную точку, дистанцию, время, полоску покрытия
---
### TC-F01-02 — Визуальное различие маршрутов
**Priority:** P1
**Precondition:** Построены 3+ маршрута
**Expected:**
- Все маршруты видны на карте одновременно
- Цвета не повторяются
- Маршруты не сливаются визуально (разная толщина или прозрачность для неактивных)
---
### TC-F01-03 — Hover на карточке подсвечивает маршрут
**Priority:** P2
**Precondition:** Построены 3+ маршрута
**Steps:**
1. Навести мышь на карточку «Вариант 2»
**Expected:**
- Маршрут варианта 2 на карте становится жирнее/ярче
- Остальные маршруты становятся тусклее
- При уходе мыши — возврат к исходному состоянию
---
### TC-F01-04 — Выбор маршрута кликом на карточку
**Priority:** P1
**Steps:**
1. Построить маршруты
2. Кликнуть на карточку «Вариант 3»
**Expected:**
- Вариант 3 выделен в панели (рамка/фон)
- На карте вариант 3 отображается жирнее остальных
- Кнопка «Скачать GPX» становится активной
---
### TC-F01-05 — Выбор маршрута кликом на линию карты
**Priority:** P2
**Steps:**
1. Построить маршруты
2. Кликнуть на линию маршрута на карте
**Expected:**
- Соответствующая карточка в панели выделяется
- Маршрут становится активным
---
### TC-F01-06 — Только один маршрут (нет альтернатив)
**Priority:** P2
**Precondition:** Точки A и B очень близко (< 5 км) или OSRM вернул 1 маршрут
**Expected:**
- Показывается 1 карточка
- Нет сообщения об ошибке
- Опционально: подпись «Альтернативных маршрутов не найдено»
---
### TC-F01-07 — Кнопка «Сбросить»
**Priority:** P1
**Precondition:** Построены маршруты, установлены маркеры A и B
**Steps:**
1. Нажать кнопку «Сбросить»
**Expected:**
- Все маршруты исчезают с карты
- Маркеры A и B удалены
- Панель карточек скрывается
- Карта возвращается в исходное состояние
---
### TC-F01-08 — Повторное построение маршрута
**Priority:** P1
**Steps:**
1. Построить маршруты
2. Переставить точку B в другое место
3. Нажать «Дикий путь» снова
**Expected:**
- Старые маршруты исчезают
- Появляются новые маршруты для новых точек
- Нет задвоения линий на карте
---
### TC-F01-09 — Максимум 5 вариантов
**Priority:** P2
**Expected:**
- Никогда не показывается больше 5 карточек
- Если OSRM вернул 5 — показываем 5
---
## TC-F02: Статистика маршрута
### TC-F02-01 — Компактная карточка содержит все элементы
**Priority:** P1
**Precondition:** Маршрут построен
**Expected:** каждая карточка содержит:
- [ ] Цветную точку (совпадает с цветом маршрута на карте)
- [ ] Номер варианта («Вариант 1»)
- [ ] Дистанцию в км (`142 км`)
- [ ] Время в читаемом формате (`4 ч 35 мин`)
- [ ] Цветную полоску покрытия
- [ ] Процент грунта и асфальта (`86% грунт · 14% асфальт`)
- [ ] Кнопку «Подробнее»
---
### TC-F02-02 — Полоска покрытия пропорциональна
**Priority:** P2
**Precondition:** Маршрут с известной статистикой (например, 50% Lev1-2, 30% Lev3-5, 20% асфальт)
**Expected:**
- Жёлтый сегмент занимает ~50% ширины полоски
- Красный — ~30%
- Серый — ~20%
- Ни один сегмент не исчезает полностью если > 0%
---
### TC-F02-03 — Цвета полоски совпадают с картой
**Priority:** P2
**Expected:**
- Lev1-2 в полоске — тот же жёлтый (#FFD700) что на карте
- Lev3-5 — тот же красный (#FF4400)
- Тропы — тот же красный пунктир (#cc0000) или близкий
- Асфальт — серый
---
### TC-F02-04 — Развёрнутая карточка
**Priority:** P1
**Steps:**
1. Построить маршрут
2. Нажать «Подробнее» на карточке
**Expected:**
- Карточка разворачивается
- Показаны строки: Lev1-2, Lev3-5, Тропы, Асфальт
- Каждая строка: иконка цвета + название + км + %
- Итоговые строки: «Итого грунт» и «Итого асфальт»
- Кнопки «📥 GPX» и «Выбрать маршрут»
---
### TC-F02-05 — Сумма процентов = 100%
**Priority:** P1
**Expected:** track_lev12_pct + track_lev345_pct + path_pct + asphalt_pct = 100 (±1% погрешность округления)
---
### TC-F02-06 — Статистика не ломает UI при ошибке бэкенда
**Priority:** P1
**Precondition:** Бэкенд вернул маршрут без поля `stats` (или stats = null)
**Expected:**
- Маршрут отображается на карте
- Карточка показывает дистанцию и время
- Полоска покрытия отсутствует или показывает «нет данных»
- Нет JS-ошибок в консоли, UI не ломается
---
### TC-F02-07 — Карточки не перекрывают карту
**Priority:** P2
**Steps:**
1. Построить 5 маршрутов
2. Проверить что карта за панелью кликабельна
**Expected:**
- Панель карточек расположена сбоку (десктоп) или снизу (мобиле)
- Карта за панелью остаётся интерактивной
---
## TC-F04: Промежуточные точки
### TC-F04-01 — Добавление промежуточной точки
**Priority:** P1
**Precondition:** Маршрут A→B построен
**Steps:**
1. Нажать кнопку «+ Точка»
2. Кликнуть на карте в произвольном месте между A и B
**Expected:**
- На карте появляется маркер промежуточной точки (визуально отличается от A/B)
- В панели точек появляется строка «1» с координатами и кнопкой ✕
- Маршрут перестраивается через новую точку: A→C→B
- Режим «добавить точку» деактивируется
---
### TC-F04-02 — Маркер промежуточной точки отличается от A/B
**Priority:** P2
**Expected:**
- Маркер A — зелёный с буквой A
- Маркер B — красный с буквой B
- Промежуточные — белые с цветной обводкой и номером (1, 2, ...)
---
### TC-F04-03 — Несколько промежуточных точек
**Priority:** P1
**Steps:**
1. Добавить 3 промежуточные точки последовательно
**Expected:**
- Маршрут строится A→C1→C2→C3→B
- В панели точек 5 строк: A, 1, 2, 3, B
- Все маркеры видны на карте
---
### TC-F04-04 — Перетаскивание промежуточной точки
**Priority:** P1
**Steps:**
1. Добавить промежуточную точку
2. Перетащить её маркер на карте в другое место
**Expected:**
- Во время перетаскивания маршрут перестраивается (с debounce ~300ms)
- После отпускания маршрут зафиксирован в новом положении
- Координаты в панели точек обновляются
---
### TC-F04-05 — Удаление промежуточной точки
**Priority:** P1
**Steps:**
1. Добавить 2 промежуточные точки
2. Нажать ✕ рядом с точкой «1» в панели
**Expected:**
- Точка «1» удалена из панели
- Маркер исчез с карты
- Маршрут перестроился: A→C2→B
- Нумерация обновилась
---
### TC-F04-06 — Изменение порядка точек
**Priority:** P2
**Steps:**
1. Добавить 2 промежуточные точки C1 и C2
2. Перетащить строку C2 выше C1 в панели точек
**Expected:**
- Порядок в панели: A, C2, C1, B
- Маршрут перестроился: A→C2→C1→B
---
### TC-F04-07 — Лимит промежуточных точек
**Priority:** P2
**Steps:**
1. Добавить 8 промежуточных точек (максимум)
2. Попытаться добавить 9-ю
**Expected:**
- Кнопка «+ Точка» неактивна или показывает предупреждение
- 9-я точка не добавляется
- Сообщение: «Максимум 8 промежуточных точек»
---
### TC-F04-08 — Перестройка маршрута не блокирует UI
**Priority:** P2
**Steps:**
1. Добавить промежуточную точку
2. Быстро перетащить её несколько раз подряд
**Expected:**
- UI не зависает
- Карта остаётся интерактивной во время перестройки
- Финальный маршрут соответствует последней позиции точки
---
## TC-F05: Экспорт GPX
### TC-F05-01 — Кнопка GPX неактивна без маршрута
**Priority:** P1
**Precondition:** Маршрут не построен
**Expected:** кнопка «Скачать GPX» задизейблена или скрыта
---
### TC-F05-02 — Базовый экспорт GPX
**Priority:** P1
**Steps:**
1. Построить маршрут A→B
2. Выбрать вариант
3. Нажать «Скачать GPX»
**Expected:**
- Браузер скачивает файл
- Имя файла: `enduro-YYYYMMDD-HHMMSS.gpx`
- Файл открывается без ошибок в текстовом редакторе
---
### TC-F05-03 — GPX содержит трек
**Priority:** P1
**Steps:**
1. Скачать GPX
2. Открыть файл, проверить структуру
**Expected:**
```xml
<gpx version="1.1" ...>
<metadata>
<name>Enduro route YYYY-MM-DD</name>
<desc>142 км · 86% грунт</desc>
<time>...</time>
</metadata>
<trk>
<trkseg>
<trkpt lat="..." lon="..."/>
<!-- все точки геометрии маршрута -->
</trkseg>
</trk>
...
</gpx>
```
---
### TC-F05-04 — GPX содержит waypoints (точки маршрута)
**Priority:** P1
**Precondition:** Маршрут с промежуточными точками
**Expected:** в GPX присутствуют `<wpt>` для точек A, промежуточных и B с именами («Старт», «Точка 1», «Финиш»)
---
### TC-F05-05 — GPX содержит флажки/метки
**Priority:** P1
**Precondition:** На карте расставлены метки (F-06)
**Expected:** в GPX присутствуют `<wpt>` для каждой метки с её именем и иконкой
---
### TC-F05-06 — Уникальное имя файла
**Priority:** P2
**Steps:**
1. Скачать GPX
2. Подождать 1 секунду
3. Скачать GPX снова
**Expected:** два файла с разными именами (разный timestamp), не перезаписывают друг друга
---
### TC-F05-07 — GPX валиден для OsmAnd
**Priority:** P2
**Steps:**
1. Скачать GPX
2. Загрузить в OsmAnd (или валидатор gpx.studio)
**Expected:**
- Трек отображается на карте OsmAnd
- Waypoints видны как точки
- Нет ошибок парсинга
---
### TC-F05-08 — Метаданные GPX корректны
**Priority:** P2
**Expected:**
- `<name>` содержит дату в формате YYYY-MM-DD
- `<desc>` содержит дистанцию и % грунта
- `<time>` — валидный ISO 8601 timestamp
---
## TC-F06: Флажки / именованные метки
### TC-F06-01 — Добавление метки с именем
**Priority:** P1
**Steps:**
1. Нажать кнопку 🚩
2. Кликнуть на карте
3. Ввести название «Заправка»
4. Нажать «Сохранить»
**Expected:**
- Метка появляется на карте с иконкой 🚩
- Метка отображается поверх всех слоёв
- Диалог закрывается
---
### TC-F06-02 — Добавление метки без имени
**Priority:** P2
**Steps:**
1. Нажать 🚩, кликнуть на карте
2. Оставить поле имени пустым, нажать Enter или «Сохранить»
**Expected:**
- Метка сохраняется с автоименем «Метка 1» (или «Метка N» по счётчику)
- Нет ошибки
---
### TC-F06-03 — Выбор иконки метки
**Priority:** P2
**Steps:**
1. Добавить метку, выбрать иконку ⛺
2. Сохранить
**Expected:** на карте отображается иконка ⛺, не 🚩
---
### TC-F06-04 — Клик по метке — попап
**Priority:** P1
**Steps:**
1. Кликнуть по существующей метке на карте
**Expected:**
- Попап с: названием, координатами (lat/lon), кнопками «Редактировать», «Удалить», «Сделать точкой A», «Сделать точкой B»
---
### TC-F06-05 — Редактирование метки
**Priority:** P2
**Steps:**
1. Открыть попап метки
2. Нажать «Редактировать»
3. Изменить название на «Ночёвка»
4. Сохранить
**Expected:**
- Метка на карте обновляет название
- В попапе при следующем клике — новое название
---
### TC-F06-06 — Удаление метки
**Priority:** P1
**Steps:**
1. Открыть попап метки
2. Нажать «Удалить»
**Expected:**
- Метка исчезает с карты
- Из localStorage удалена запись
---
### TC-F06-07 — Метки сохраняются после перезагрузки
**Priority:** P1
**Steps:**
1. Добавить 3 метки
2. Закрыть вкладку браузера
3. Открыть снова
**Expected:** все 3 метки на месте, с теми же именами и иконками
---
### TC-F06-08 — Метка как точка маршрута
**Priority:** P2
**Steps:**
1. Добавить метку «Старт»
2. Открыть попап метки
3. Нажать «Сделать точкой A»
**Expected:**
- Маркер A перемещается на координаты метки
- Если маршрут был построен — перестраивается
---
### TC-F06-09 — Лимит меток
**Priority:** P3
**Steps:**
1. Добавить 50 меток
2. Попытаться добавить 51-ю
**Expected:**
- Предупреждение: «Достигнут лимит 50 меток»
- 51-я метка не добавляется
---
### TC-F06-10 — Очистить все метки
**Priority:** P2
**Steps:**
1. Добавить несколько меток
2. Нажать «Очистить все метки»
3. Подтвердить в диалоге
**Expected:**
- Все метки исчезают с карты
- localStorage очищен
- Без подтверждения — ничего не происходит
---
## TC-NFR: Нефункциональные требования
### TC-NFR-01 — Время построения маршрута
**Priority:** P1
**Steps:**
1. Установить точки A и B (~150 км)
2. Нажать «Дикий путь», засечь время
**Expected:** маршруты появляются не позднее чем через 5 секунд
---
### TC-NFR-02 — Спиннер при загрузке
**Priority:** P2
**Steps:**
1. Нажать «Дикий путь»
**Expected:**
- Кнопка показывает спиннер или меняет текст на «Строю...»
- Карта остаётся интерактивной (можно зумировать, двигать)
- После получения ответа — кнопка возвращается в исходное состояние
---
### TC-NFR-03 — Мобильный экран (< 768px)
**Priority:** P2
**Steps:**
1. Открыть в браузере с шириной 375px (iPhone)
2. Построить маршруты
**Expected:**
- Панель карточек расположена снизу, не перекрывает карту полностью
- Карточки скроллируются горизонтально
- Кнопки управления доступны
---
### TC-NFR-04 — Touch-перетаскивание точек (мобиле)
**Priority:** P2
**Steps:**
1. На мобиле добавить промежуточную точку
2. Перетащить пальцем
**Expected:** точка перемещается, маршрут перестраивается
---
### TC-NFR-05 — OSRM недоступен
**Priority:** P1
**Precondition:** OSRM контейнер остановлен
**Steps:**
1. Нажать «Дикий путь»
**Expected:**
- Сообщение об ошибке: «Не удалось построить маршрут. Попробуйте позже.»
- UI не ломается, карта остаётся рабочей
- Нет необработанных JS-ошибок в консоли
---
### TC-NFR-06 — localStorage недоступен
**Priority:** P3
**Precondition:** localStorage заблокирован (приватный режим Firefox)
**Expected:**
- Метки работают в рамках сессии
- Нет JS-ошибок
- Предупреждение: «Метки не будут сохранены после закрытия браузера»
---
## Матрица покрытия
| Фича | Кол-во TC | P1 | P2 | P3 |
|------|-----------|----|----|-----|
| F-03 Время | 8 | 4 | 3 | 1 |
| F-01 Альтернативы | 9 | 5 | 4 | 0 |
| F-02 Статистика | 7 | 4 | 3 | 0 |
| F-04 Промежуточные точки | 8 | 4 | 4 | 0 |
| F-05 GPX | 8 | 4 | 4 | 0 |
| F-06 Флажки | 10 | 4 | 5 | 1 |
| NFR | 6 | 2 | 3 | 1 |
| **Итого** | **56** | **27** | **26** | **3** |
---
## Порядок прогона
**Smoke (P1 only, ~15 мин):**
TC-F03-01, TC-F03-03, TC-F03-08 → TC-F01-01, TC-F01-04, TC-F01-07 → TC-F02-01, TC-F02-05, TC-F02-06 → TC-F04-01, TC-F04-04, TC-F04-05 → TC-F05-01, TC-F05-02, TC-F05-03, TC-F05-04 → TC-F06-01, TC-F06-04, TC-F06-06, TC-F06-07 → TC-NFR-01, TC-NFR-05
**Full regression (~60 мин):** все 56 тест-кейсов в порядке нумерации
---
*Документ готов. После реализации — прогнать Smoke перед передачей Славе.*