auto-sync: 2026-05-13 00:50:01
296
tasks/enduro-trails/DEV_TASK_TERRAIN_JS.md
Normal file
@@ -0,0 +1,296 @@
|
||||
# DEV TASK: Terrain JS-логика (баг — функции отсутствуют в app.js)
|
||||
|
||||
**Статус:** Ready for dev
|
||||
**Проект:** enduro-trails
|
||||
**Фаза:** 5.4 (фикс)
|
||||
|
||||
---
|
||||
|
||||
## Цель
|
||||
|
||||
> Добавить JS-функции `toggleTerrainPopup()` и `onTerrainCheckbox()` в app.js. Кнопка рельеф должна открывать попап, чекбоксы — включать/выключать слои гипсометрии и отмывки на карте.
|
||||
|
||||
## Архитектура
|
||||
|
||||
HTML-разметка (кнопка `#terrain-toggle`, попап `#terrain-popup`, чекбоксы) и CSS уже на месте. Нужно только JS:
|
||||
- `toggleTerrainPopup()` — показать/скрыть попап, toggle класс `.active` на кнопке
|
||||
- `onTerrainCheckbox()` — добавить/удалить raster source+layer для hypso и hillshade
|
||||
- `updateHillshadeAvailability()` — disable чекбокс hillshade на зуме < 10
|
||||
- Персистентность через localStorage
|
||||
|
||||
## Стек
|
||||
|
||||
- MapLibre GL JS (уже подключён, доступен как `window._map`)
|
||||
- Тайлы terrain: `https://openclaw.mva154.duckdns.org/enduro/terrain/hypso/{z}/{x}/{y}.png` и `.../hillshade/{z}/{x}/{y}.png`
|
||||
- Формат тайлов: TMS (нужен `scheme: 'tms'` в source)
|
||||
- Bounds: `[35, 45, 55, 62]`
|
||||
|
||||
---
|
||||
|
||||
## Инфраструктура
|
||||
|
||||
| Параметр | Значение |
|
||||
|----------|----------|
|
||||
| Сервер | `slin@82.22.50.71` (пароль: `motoZ@yaz2010`) |
|
||||
| Контейнер | `prototype-enduro-trails-1` |
|
||||
| Файл | `/home/slin/enduro-trails/prototype/static/app.js` (2625 строк) |
|
||||
| URL | `https://openclaw.mva154.duckdns.org/enduro/` |
|
||||
| Деплой | SSH → docker cp (БЕЗ рестарта!) |
|
||||
|
||||
---
|
||||
|
||||
## Файловая карта
|
||||
|
||||
| Действие | Файл | Ответственность |
|
||||
|----------|------|-----------------|
|
||||
| Изменить | `static/app.js` (добавить в конец) | Terrain JS-логика |
|
||||
|
||||
---
|
||||
|
||||
## Задачи
|
||||
|
||||
### Task 1: Добавить terrain JS-функции в app.js
|
||||
|
||||
**Файлы:**
|
||||
- Изменить: `/home/slin/enduro-trails/prototype/static/app.js` — добавить в конец файла
|
||||
|
||||
**Шаги:**
|
||||
|
||||
- [ ] **1.1** Скачать актуальный app.js с сервера в workspace:
|
||||
|
||||
```bash
|
||||
# Через ssh2 — скопировать /home/slin/enduro-trails/prototype/static/app.js
|
||||
# в /home/node/.openclaw/workspace/tasks/enduro-trails/prototype/static/app.js
|
||||
```
|
||||
|
||||
- [ ] **1.2** Добавить в конец app.js следующий код:
|
||||
|
||||
```javascript
|
||||
// ═══════════════════════════════════════════
|
||||
// TERRAIN LAYERS (Phase 5.4)
|
||||
// ═══════════════════════════════════════════
|
||||
|
||||
const TERRAIN_BASE_URL = window.location.pathname.replace(/\/[^/]*$/, '') + '/terrain';
|
||||
|
||||
function toggleTerrainPopup() {
|
||||
const popup = document.getElementById('terrain-popup');
|
||||
const btn = document.getElementById('terrain-toggle');
|
||||
if (!popup || !btn) return;
|
||||
|
||||
const isVisible = popup.style.display !== 'none';
|
||||
popup.style.display = isVisible ? 'none' : 'block';
|
||||
btn.classList.toggle('active', !isVisible);
|
||||
|
||||
// Close on outside click
|
||||
if (!isVisible) {
|
||||
setTimeout(() => {
|
||||
document.addEventListener('click', closeTerrainOnOutside);
|
||||
}, 10);
|
||||
} else {
|
||||
document.removeEventListener('click', closeTerrainOnOutside);
|
||||
}
|
||||
}
|
||||
|
||||
function closeTerrainOnOutside(e) {
|
||||
const popup = document.getElementById('terrain-popup');
|
||||
const btn = document.getElementById('terrain-toggle');
|
||||
if (!popup.contains(e.target) && e.target !== btn && !btn.contains(e.target)) {
|
||||
popup.style.display = 'none';
|
||||
btn.classList.remove('active');
|
||||
document.removeEventListener('click', closeTerrainOnOutside);
|
||||
}
|
||||
}
|
||||
|
||||
function onTerrainCheckbox() {
|
||||
const map = window._map;
|
||||
if (!map) return;
|
||||
|
||||
const hypsoChecked = document.getElementById('terrain-hypso-cb').checked;
|
||||
const hillshadeChecked = document.getElementById('terrain-hillshade-cb').checked;
|
||||
|
||||
// Save state
|
||||
localStorage.setItem('terrain-hypso', hypsoChecked ? '1' : '0');
|
||||
localStorage.setItem('terrain-hillshade', hillshadeChecked ? '1' : '0');
|
||||
|
||||
// Update button active state
|
||||
const btn = document.getElementById('terrain-toggle');
|
||||
btn.classList.toggle('active', hypsoChecked || hillshadeChecked);
|
||||
|
||||
// Apply layers
|
||||
applyTerrainLayer('terrain-hypso', TERRAIN_BASE_URL + '/hypso/{z}/{x}/{y}.png', hypsoChecked, 0.55, 5, 15);
|
||||
applyTerrainLayer('terrain-hillshade', TERRAIN_BASE_URL + '/hillshade/{z}/{x}/{y}.png', hillshadeChecked, 0.40, 10, 15);
|
||||
}
|
||||
|
||||
function applyTerrainLayer(id, tileUrl, enabled, opacity, minzoom, maxzoom) {
|
||||
const map = window._map;
|
||||
if (!map) return;
|
||||
|
||||
const sourceId = id + '-source';
|
||||
|
||||
if (enabled) {
|
||||
// Add source if not exists
|
||||
if (!map.getSource(sourceId)) {
|
||||
map.addSource(sourceId, {
|
||||
type: 'raster',
|
||||
tiles: [tileUrl],
|
||||
tileSize: 256,
|
||||
scheme: 'tms',
|
||||
bounds: [35, 45, 55, 62],
|
||||
minzoom: minzoom,
|
||||
maxzoom: maxzoom
|
||||
});
|
||||
}
|
||||
// Add layer if not exists
|
||||
if (!map.getLayer(id)) {
|
||||
// Insert before first road/trail layer for correct z-order
|
||||
const firstTrailLayer = map.getStyle().layers.find(l =>
|
||||
l.id.startsWith('trails-') || l.id.startsWith('poi-')
|
||||
);
|
||||
map.addLayer({
|
||||
id: id,
|
||||
type: 'raster',
|
||||
source: sourceId,
|
||||
paint: {
|
||||
'raster-opacity': opacity
|
||||
},
|
||||
minzoom: minzoom,
|
||||
maxzoom: maxzoom
|
||||
}, firstTrailLayer ? firstTrailLayer.id : undefined);
|
||||
}
|
||||
} else {
|
||||
// Remove layer and source
|
||||
if (map.getLayer(id)) map.removeLayer(id);
|
||||
if (map.getSource(sourceId)) map.removeSource(sourceId);
|
||||
}
|
||||
}
|
||||
|
||||
function updateHillshadeAvailability() {
|
||||
const map = window._map;
|
||||
if (!map) return;
|
||||
|
||||
const zoom = map.getZoom();
|
||||
const cb = document.getElementById('terrain-hillshade-cb');
|
||||
const hint = document.getElementById('terrain-hillshade-hint');
|
||||
const label = cb ? cb.closest('.terrain-checkbox') : null;
|
||||
|
||||
if (zoom < 10) {
|
||||
if (cb) cb.disabled = true;
|
||||
if (label) label.classList.add('disabled');
|
||||
if (hint) hint.style.display = 'inline';
|
||||
} else {
|
||||
if (cb) cb.disabled = false;
|
||||
if (label) label.classList.remove('disabled');
|
||||
if (hint) hint.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
function restoreTerrainState() {
|
||||
const hypso = localStorage.getItem('terrain-hypso') === '1';
|
||||
const hillshade = localStorage.getItem('terrain-hillshade') === '1';
|
||||
|
||||
const hypsoCb = document.getElementById('terrain-hypso-cb');
|
||||
const hillshadeCb = document.getElementById('terrain-hillshade-cb');
|
||||
|
||||
if (hypsoCb) hypsoCb.checked = hypso;
|
||||
if (hillshadeCb) hillshadeCb.checked = hillshade;
|
||||
|
||||
if (hypso || hillshade) {
|
||||
onTerrainCheckbox();
|
||||
}
|
||||
|
||||
// Update button active state
|
||||
const btn = document.getElementById('terrain-toggle');
|
||||
if (btn) btn.classList.toggle('active', hypso || hillshade);
|
||||
}
|
||||
|
||||
// Hook into map load and zoom changes
|
||||
(function initTerrain() {
|
||||
const map = window._map;
|
||||
if (map) {
|
||||
map.on('zoomend', updateHillshadeAvailability);
|
||||
map.on('style.load', () => {
|
||||
// Re-apply terrain after style change (theme switch)
|
||||
setTimeout(restoreTerrainState, 100);
|
||||
});
|
||||
// Initial state
|
||||
updateHillshadeAvailability();
|
||||
restoreTerrainState();
|
||||
} else {
|
||||
// Map not ready yet, wait
|
||||
const interval = setInterval(() => {
|
||||
if (window._map) {
|
||||
clearInterval(interval);
|
||||
window._map.on('zoomend', updateHillshadeAvailability);
|
||||
window._map.on('style.load', () => {
|
||||
setTimeout(restoreTerrainState, 100);
|
||||
});
|
||||
updateHillshadeAvailability();
|
||||
restoreTerrainState();
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
})();
|
||||
```
|
||||
|
||||
- [ ] **1.3** Загрузить на сервер и docker cp:
|
||||
|
||||
```bash
|
||||
# SFTP upload app.js → /home/slin/enduro-trails/prototype/static/app.js
|
||||
# Затем:
|
||||
docker cp /home/slin/enduro-trails/prototype/static/app.js prototype-enduro-trails-1:/app/static/app.js
|
||||
```
|
||||
|
||||
⚠️ НЕ рестартовать контейнер!
|
||||
|
||||
- [ ] **1.4** Проверить что функции на месте:
|
||||
|
||||
```bash
|
||||
docker exec prototype-enduro-trails-1 grep -c "toggleTerrainPopup\|onTerrainCheckbox\|applyTerrainLayer" /app/static/app.js
|
||||
# Ожидаемый результат: >= 3
|
||||
```
|
||||
|
||||
**Критерий готовности:** Функции `toggleTerrainPopup`, `onTerrainCheckbox`, `applyTerrainLayer`, `updateHillshadeAvailability`, `restoreTerrainState` присутствуют в app.js на сервере.
|
||||
|
||||
---
|
||||
|
||||
## Проверка (Acceptance)
|
||||
|
||||
| # | Проверка | Команда / Действие | Ожидаемый результат |
|
||||
|---|----------|-------------------|---------------------|
|
||||
| 1 | Функции в app.js | `grep -c toggleTerrainPopup` | >= 1 |
|
||||
| 2 | Кнопка открывает попап | Клик по 🏔️ | Попап виден |
|
||||
| 3 | Чекбокс hypso | Включить «Гипсометрия» | Цветной слой на карте |
|
||||
| 4 | Чекбокс hillshade | Включить «Отмывка» (зум >= 10) | Тени рельефа |
|
||||
| 5 | Hillshade disabled | Зум < 10 | Чекбокс неактивен, hint «Зум 10+» |
|
||||
| 6 | Попап закрывается | Клик вне попапа | Попап скрыт |
|
||||
| 7 | Персистентность | Перезагрузить страницу | Состояние чекбоксов сохранено |
|
||||
| 8 | Смена темы | Переключить тему | Terrain слои остаются |
|
||||
|
||||
---
|
||||
|
||||
## Ограничения и контекст
|
||||
|
||||
- ⚠️ docker cp БЕЗ рестарта — рестарт перезапишет статику
|
||||
- ⚠️ SSH через Node.js ssh2 модуль
|
||||
- ⚠️ Тайлы в формате TMS — обязателен `scheme: 'tms'` в source
|
||||
- ⚠️ `bounds: [35, 45, 55, 62]` — без этого MapLibre запрашивает тайлы за пределами региона
|
||||
- ⚠️ Terrain слои должны быть ПОД дорогами/POI (beforeId = первый trails/poi layer)
|
||||
- ⚠️ После `map.setStyle()` (смена темы) все кастомные source/layer слетают — `restoreTerrainState()` вызывается на `style.load`
|
||||
- ⚠️ Hillshade тайлы существуют только для зумов 10-15
|
||||
- 🚫 НЕ трогать index.html и app.css — они уже корректны
|
||||
|
||||
---
|
||||
|
||||
## Деплой-чеклист
|
||||
|
||||
- [ ] app.js скачан с сервера (актуальная версия)
|
||||
- [ ] Terrain-код добавлен в конец
|
||||
- [ ] Загружен обратно на сервер
|
||||
- [ ] docker cp выполнен
|
||||
- [ ] `grep toggleTerrainPopup` — найдено
|
||||
- [ ] Кнопка рельеф работает (попап открывается)
|
||||
- [ ] Гипсометрия включается (цветной слой виден)
|
||||
|
||||
---
|
||||
|
||||
*Создано: 2026-05-12 | Автор ТЗ: Стрим | Исполнитель: Dev-агент*
|
||||
126
tasks/enduro-trails/TEST_CASES_UI_TERRAIN.md
Normal file
@@ -0,0 +1,126 @@
|
||||
# UI Test Cases: Terrain (Фаза 5.4)
|
||||
|
||||
### TC-T-01 — Кнопка рельеф видна
|
||||
**Тип:** ui
|
||||
**Viewport:** both
|
||||
**URL:** https://openclaw.mva154.duckdns.org/enduro/
|
||||
|
||||
**Шаги:**
|
||||
1. navigate: https://openclaw.mva154.duckdns.org/enduro/
|
||||
2. wait: 3000
|
||||
3. screenshot: "terrain-btn-visible"
|
||||
4. check-visual: "Кнопка рельеф (иконка горы) видна в правой панели кнопок. Не обрезана, достаточного размера для тапа."
|
||||
|
||||
**Визуальные критерии:**
|
||||
- Кнопка с иконкой горы видна
|
||||
- Не перекрыта другими элементами
|
||||
- Достаточный размер (>44px на мобильном)
|
||||
|
||||
---
|
||||
|
||||
### TC-T-02 — Попап рельеф открывается
|
||||
**Тип:** ui
|
||||
**Viewport:** both
|
||||
**URL:** https://openclaw.mva154.duckdns.org/enduro/
|
||||
|
||||
**Шаги:**
|
||||
1. navigate: https://openclaw.mva154.duckdns.org/enduro/
|
||||
2. wait: 3000
|
||||
3. click: "#terrain-toggle"
|
||||
4. wait: 500
|
||||
5. screenshot: "terrain-popup-open"
|
||||
6. check-visual: "Попап рельеф открылся. Видны два чекбокса: Гипсометрия и Отмывка. Попап не обрезан, текст читаем."
|
||||
|
||||
**Визуальные критерии:**
|
||||
- Попап виден полностью
|
||||
- Два чекбокса с подписями
|
||||
- Текст читаем, контраст достаточный
|
||||
- Попап не перекрывает критичные элементы карты
|
||||
|
||||
---
|
||||
|
||||
### TC-T-03 — Включение гипсометрии
|
||||
**Тип:** ui
|
||||
**Viewport:** desktop
|
||||
**URL:** https://openclaw.mva154.duckdns.org/enduro/
|
||||
|
||||
**Шаги:**
|
||||
1. navigate: https://openclaw.mva154.duckdns.org/enduro/
|
||||
2. wait: 3000
|
||||
3. click: "#terrain-toggle"
|
||||
4. wait: 500
|
||||
5. click: "#terrain-hypso-cb"
|
||||
6. wait: 3000
|
||||
7. screenshot: "hypso-enabled"
|
||||
8. check-visual: "Гипсометрия включена: на карте виден цветной полупрозрачный слой рельефа (зелёные/жёлтые/коричневые тона поверх базовой карты)."
|
||||
|
||||
**Визуальные критерии:**
|
||||
- Виден цветной overlay поверх карты
|
||||
- Карта под overlay всё ещё читаема
|
||||
- Нет артефактов (чёрные/белые блоки)
|
||||
|
||||
---
|
||||
|
||||
### TC-T-04 — Включение отмывки (hillshade)
|
||||
**Тип:** ui
|
||||
**Viewport:** desktop
|
||||
**URL:** https://openclaw.mva154.duckdns.org/enduro/
|
||||
|
||||
**Шаги:**
|
||||
1. navigate: https://openclaw.mva154.duckdns.org/enduro/
|
||||
2. wait: 3000
|
||||
3. click: "#terrain-toggle"
|
||||
4. wait: 500
|
||||
5. click: "#terrain-hypso-cb"
|
||||
6. wait: 1000
|
||||
7. click: "#terrain-hillshade-cb"
|
||||
8. wait: 3000
|
||||
9. screenshot: "hillshade-enabled"
|
||||
10. check-visual: "Отмывка включена: видны тени рельефа (затемнение на склонах). Если зум < 10 — чекбокс hillshade должен быть disabled с подсказкой 'Зум 10+'."
|
||||
|
||||
**Визуальные критерии:**
|
||||
- Если зум >= 10: видны тени на рельефе
|
||||
- Если зум < 10: чекбокс hillshade неактивен, подсказка видна
|
||||
- Нет чёрных/белых артефактов
|
||||
|
||||
---
|
||||
|
||||
### TC-T-05 — Попап закрывается по повторному клику
|
||||
**Тип:** ui
|
||||
**Viewport:** desktop
|
||||
**URL:** https://openclaw.mva154.duckdns.org/enduro/
|
||||
|
||||
**Шаги:**
|
||||
1. navigate: https://openclaw.mva154.duckdns.org/enduro/
|
||||
2. wait: 3000
|
||||
3. click: "#terrain-toggle"
|
||||
4. wait: 500
|
||||
5. screenshot: "popup-open"
|
||||
6. click: "#terrain-toggle"
|
||||
7. wait: 500
|
||||
8. screenshot: "popup-closed"
|
||||
9. check-visual: "Попап закрылся после повторного клика на кнопку рельеф. Попап не виден на экране."
|
||||
|
||||
**Визуальные критерии:**
|
||||
- Попап не виден на втором скриншоте
|
||||
- Карта видна полностью без перекрытий
|
||||
|
||||
---
|
||||
|
||||
### TC-T-06 — Мобильный попап не обрезан
|
||||
**Тип:** ui
|
||||
**Viewport:** mobile
|
||||
**URL:** https://openclaw.mva154.duckdns.org/enduro/
|
||||
|
||||
**Шаги:**
|
||||
1. navigate: https://openclaw.mva154.duckdns.org/enduro/
|
||||
2. wait: 3000
|
||||
3. click: "#terrain-toggle"
|
||||
4. wait: 500
|
||||
5. screenshot: "terrain-popup-mobile"
|
||||
6. check-visual: "Попап terrain полностью виден на мобильном экране. Не обрезан снизу/справа. Чекбоксы достаточного размера для тапа (>44px)."
|
||||
|
||||
**Визуальные критерии:**
|
||||
- Попап целиком в viewport
|
||||
- Чекбоксы кликабельного размера
|
||||
- Текст читаем на маленьком экране
|
||||
148
tasks/enduro-trails/reports/results.json
Normal file
@@ -0,0 +1,148 @@
|
||||
{
|
||||
"timestamp": "2026-05-12T21:44:53.908Z",
|
||||
"testFile": "TEST_CASES_UI_TERRAIN.md",
|
||||
"results": [
|
||||
{
|
||||
"id": "TC-T-01",
|
||||
"name": "Кнопка рельеф видна",
|
||||
"viewport": "desktop",
|
||||
"status": "completed",
|
||||
"screenshots": [
|
||||
"TC-T-01-desktop-terrain-btn-visible.png",
|
||||
"TC-T-01-desktop-check-1778622228148.png"
|
||||
],
|
||||
"checks": [
|
||||
{
|
||||
"description": "Кнопка рельеф (иконка горы) видна в правой панели кнопок. Не обрезана, достаточного размера для тапа.",
|
||||
"screenshot": "TC-T-01-desktop-check-1778622228148.png"
|
||||
}
|
||||
],
|
||||
"errors": []
|
||||
},
|
||||
{
|
||||
"id": "TC-T-01",
|
||||
"name": "Кнопка рельеф видна",
|
||||
"viewport": "mobile",
|
||||
"status": "completed",
|
||||
"screenshots": [
|
||||
"TC-T-01-mobile-terrain-btn-visible.png",
|
||||
"TC-T-01-mobile-check-1778622233547.png"
|
||||
],
|
||||
"checks": [
|
||||
{
|
||||
"description": "Кнопка рельеф (иконка горы) видна в правой панели кнопок. Не обрезана, достаточного размера для тапа.",
|
||||
"screenshot": "TC-T-01-mobile-check-1778622233547.png"
|
||||
}
|
||||
],
|
||||
"errors": []
|
||||
},
|
||||
{
|
||||
"id": "TC-T-02",
|
||||
"name": "Попап рельеф открывается",
|
||||
"viewport": "desktop",
|
||||
"status": "completed",
|
||||
"screenshots": [
|
||||
"TC-T-02-desktop-terrain-popup-open.png",
|
||||
"TC-T-02-desktop-check-1778622239862.png"
|
||||
],
|
||||
"checks": [
|
||||
{
|
||||
"description": "Попап рельеф открылся. Видны два чекбокса: Гипсометрия и Отмывка. Попап не обрезан, текст читаем.",
|
||||
"screenshot": "TC-T-02-desktop-check-1778622239862.png"
|
||||
}
|
||||
],
|
||||
"errors": []
|
||||
},
|
||||
{
|
||||
"id": "TC-T-02",
|
||||
"name": "Попап рельеф открывается",
|
||||
"viewport": "mobile",
|
||||
"status": "completed",
|
||||
"screenshots": [
|
||||
"TC-T-02-mobile-terrain-popup-open.png",
|
||||
"TC-T-02-mobile-check-1778622245753.png"
|
||||
],
|
||||
"checks": [
|
||||
{
|
||||
"description": "Попап рельеф открылся. Видны два чекбокса: Гипсометрия и Отмывка. Попап не обрезан, текст читаем.",
|
||||
"screenshot": "TC-T-02-mobile-check-1778622245753.png"
|
||||
}
|
||||
],
|
||||
"errors": []
|
||||
},
|
||||
{
|
||||
"id": "TC-T-03",
|
||||
"name": "Включение гипсометрии",
|
||||
"viewport": "desktop",
|
||||
"status": "completed_with_errors",
|
||||
"screenshots": [
|
||||
"TC-T-03-desktop-hypso-enabled.png",
|
||||
"TC-T-03-desktop-check-1778622259991.png"
|
||||
],
|
||||
"checks": [
|
||||
{
|
||||
"description": "Гипсометрия включена: на карте виден цветной полупрозрачный слой рельефа (зелёные/жёлтые/коричневые тона поверх базовой карты).",
|
||||
"screenshot": "TC-T-03-desktop-check-1778622259991.png"
|
||||
}
|
||||
],
|
||||
"errors": [
|
||||
"Click failed on \"#terrain-hypso-cb\": page.click: Timeout 5000ms exceeded.\nCall log:\n - waiting for locator('#terrain-hypso-cb')\n - lo"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "TC-T-04",
|
||||
"name": "Включение отмывки (hillshade)",
|
||||
"viewport": "desktop",
|
||||
"status": "completed_with_errors",
|
||||
"screenshots": [
|
||||
"TC-T-04-desktop-hillshade-enabled.png",
|
||||
"TC-T-04-desktop-check-1778622280567.png"
|
||||
],
|
||||
"checks": [
|
||||
{
|
||||
"description": "Отмывка включена: видны тени рельефа (затемнение на склонах). Если зум < 10 — чекбокс hillshade должен быть disabled с подсказкой 'Зум 10+'.",
|
||||
"screenshot": "TC-T-04-desktop-check-1778622280567.png"
|
||||
}
|
||||
],
|
||||
"errors": [
|
||||
"Click failed on \"#terrain-hypso-cb\": page.click: Timeout 5000ms exceeded.\nCall log:\n - waiting for locator('#terrain-hypso-cb')\n - lo",
|
||||
"Click failed on \"#terrain-hillshade-cb\": page.click: Timeout 5000ms exceeded.\nCall log:\n - waiting for locator('#terrain-hillshade-cb')\n "
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "TC-T-05",
|
||||
"name": "Попап закрывается по повторному клику",
|
||||
"viewport": "desktop",
|
||||
"status": "completed",
|
||||
"screenshots": [
|
||||
"TC-T-05-desktop-popup-open.png",
|
||||
"TC-T-05-desktop-popup-closed.png",
|
||||
"TC-T-05-desktop-check-1778622287510.png"
|
||||
],
|
||||
"checks": [
|
||||
{
|
||||
"description": "Попап закрылся после повторного клика на кнопку рельеф. Попап не виден на экране.",
|
||||
"screenshot": "TC-T-05-desktop-check-1778622287510.png"
|
||||
}
|
||||
],
|
||||
"errors": []
|
||||
},
|
||||
{
|
||||
"id": "TC-T-06",
|
||||
"name": "Мобильный попап не обрезан",
|
||||
"viewport": "mobile",
|
||||
"status": "completed",
|
||||
"screenshots": [
|
||||
"TC-T-06-mobile-terrain-popup-mobile.png",
|
||||
"TC-T-06-mobile-check-1778622293523.png"
|
||||
],
|
||||
"checks": [
|
||||
{
|
||||
"description": "Попап terrain полностью виден на мобильном экране. Не обрезан снизу/справа. Чекбоксы достаточного размера для тапа (>44px).",
|
||||
"screenshot": "TC-T-06-mobile-check-1778622293523.png"
|
||||
}
|
||||
],
|
||||
"errors": []
|
||||
}
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 829 KiB |
|
After Width: | Height: | Size: 829 KiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 829 KiB |
|
After Width: | Height: | Size: 829 KiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 829 KiB |
|
After Width: | Height: | Size: 829 KiB |