auto-sync: 2026-05-13 01:00:01

This commit is contained in:
Stream
2026-05-13 01:00:01 +03:00
parent 2fb2063a40
commit 4bc48dbcb3
25 changed files with 224 additions and 122 deletions

View File

@@ -0,0 +1,45 @@
# UI Test Cases: Terrain — Расширенные
### TC-T-07 — Гипсометрия на зуме 10
**Тип:** ui
**Viewport:** desktop
**URL:** https://openclaw.mva154.duckdns.org/enduro/#10/55.75/37.6
**Шаги:**
1. navigate: https://openclaw.mva154.duckdns.org/enduro/#10/55.75/37.6
2. wait: 5000
3. click: "#terrain-toggle"
4. wait: 500
5. click: "#terrain-hypso-cb"
6. wait: 5000
7. screenshot: "hypso-zoom10"
8. check-visual: "Гипсометрия включена на зуме 10. Должен быть виден цветной полупрозрачный слой (зелёные тона для равнины ЦФО) поверх базовой карты."
**Визуальные критерии:**
- Цветной overlay виден на карте
- Зелёные/жёлтые тона рельефа
- Карта под overlay читаема
---
### TC-T-08 — Hillshade на зуме 11
**Тип:** ui
**Viewport:** desktop
**URL:** https://openclaw.mva154.duckdns.org/enduro/#11/55.75/37.6
**Шаги:**
1. navigate: https://openclaw.mva154.duckdns.org/enduro/#11/55.75/37.6
2. wait: 5000
3. click: "#terrain-toggle"
4. wait: 500
5. click: "#terrain-hypso-cb"
6. wait: 1000
7. click: "#terrain-hillshade-cb"
8. wait: 5000
9. screenshot: "hillshade-zoom11"
10. check-visual: "Оба слоя включены на зуме 11: гипсометрия (цвет) + отмывка (тени). Должны быть видны тени на склонах рельефа."
**Визуальные критерии:**
- Цветной overlay + тени видны
- Рельеф выглядит объёмным
- Нет чёрных/белых артефактов

View File

@@ -2623,3 +2623,168 @@ function initMiniRouteInteraction() {
selectRoute(activeRouteIdx);
});
}
// ═══════════════════════════════════════════
// 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);
}
})();

View File

@@ -1,145 +1,37 @@
{
"timestamp": "2026-05-12T21:44:53.908Z",
"testFile": "TEST_CASES_UI_TERRAIN.md",
"timestamp": "2026-05-12T21:55:27.927Z",
"testFile": "TEST_CASES_UI_TERRAIN_EXT.md",
"results": [
{
"id": "TC-T-01",
"name": "Кнопка рельеф видна",
"id": "TC-T-07",
"name": "Гипсометрия на зуме 10",
"viewport": "desktop",
"status": "completed",
"screenshots": [
"TC-T-01-desktop-terrain-btn-visible.png",
"TC-T-01-desktop-check-1778622228148.png"
"TC-T-07-desktop-hypso-zoom10.png",
"TC-T-07-desktop-check-1778622909625.png"
],
"checks": [
{
"description": "Кнопка рельеф (иконка горы) видна в правой панели кнопок. Не обрезана, достаточного размера для тапа.",
"screenshot": "TC-T-01-desktop-check-1778622228148.png"
"description": "Гипсометрия включена на зуме 10. Должен быть виден цветной полупрозрачный слой (зелёные тона для равнины ЦФО) поверх базовой карты.",
"screenshot": "TC-T-07-desktop-check-1778622909625.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": "Попап рельеф открывается",
"id": "TC-T-08",
"name": "Hillshade на зуме 11",
"viewport": "desktop",
"status": "completed",
"screenshots": [
"TC-T-02-desktop-terrain-popup-open.png",
"TC-T-02-desktop-check-1778622239862.png"
"TC-T-08-desktop-hillshade-zoom11.png",
"TC-T-08-desktop-check-1778622927607.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"
"description": "Оба слоя включены на зуме 11: гипсометрия (цвет) + отмывка (тени). Должны быть видны тени на склонах рельефа.",
"screenshot": "TC-T-08-desktop-check-1778622927607.png"
}
],
"errors": []

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 829 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 797 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 829 KiB

After

Width:  |  Height:  |  Size: 797 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 797 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 829 KiB

After

Width:  |  Height:  |  Size: 797 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 918 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 918 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 918 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB