From 1403b84b0b84183cd111886fb6ad4670e50f1b77 Mon Sep 17 00:00:00 2001 From: lingniu Date: Wed, 12 Aug 2026 11:28:50 +0800 Subject: [PATCH] feat(navigation): refine mobile station explorer --- station-navigation/app.js | 31 ++++- station-navigation/index.html | 5 +- station-navigation/server.py | 5 + station-navigation/styles.css | 144 +++++++++++++++++++++++- station-navigation/tests/test_app.mjs | 32 +++++- station-navigation/tests/test_server.py | 3 + 6 files changed, 208 insertions(+), 12 deletions(-) diff --git a/station-navigation/app.js b/station-navigation/app.js index e038809e..5289672b 100644 --- a/station-navigation/app.js +++ b/station-navigation/app.js @@ -1,4 +1,4 @@ -const state = { stations: [], query: '', searchText: '', locationFilter: { province: '', city: '', district: '' }, suggestions: [], activeSuggestion: -1, searchDebounce: null, stationFilter: 'all', selected: null, userLocation: null, map: null, markers: [], userMarker: null, pitch: true }; +const state = { stations: [], query: '', searchText: '', locationFilters: [], suggestions: [], activeSuggestion: -1, searchDebounce: null, stationFilter: 'all', selected: null, userLocation: null, map: null, markers: [], userMarker: null, pitch: true }; document.addEventListener('DOMContentLoaded', () => { initClock(); initMap(); loadStations(); }); document.addEventListener('pointerdown', event => { if (!event.target?.closest?.('.map-explore-toolbar')) closeStationSearchSuggestions(); }); @@ -31,12 +31,17 @@ function updateSummary(summary) { const total = Number(summary.totalStations || 0), partner = Number(summary.cooperativeStations || 0), external = Math.max(0, total - partner); setHTML('kpiTotal', `${formatNumber(total)} `); setHTML('kpiPartner', `${formatNumber(partner)} `); setHTML('statusTotal', `${formatNumber(total)} `); setHTML('statusPartner', `${formatNumber(partner)} `); setHTML('statusExternal', `${formatNumber(external)} `); + setHTML('mobileStatusTotal', `${formatNumber(total)} `); setHTML('mobileStatusPartner', `${formatNumber(partner)} `); setHTML('mobileStatusExternal', `${formatNumber(external)} `); document.getElementById('partnerSegment').style.width = `${total ? partner * 100 / total : 0}%`; document.getElementById('externalSegment').style.width = `${total ? external * 100 / total : 0}%`; + document.getElementById('mobilePartnerSegment').style.width = `${total ? partner * 100 / total : 0}%`; + document.getElementById('mobileExternalSegment').style.width = `${total ? external * 100 / total : 0}%`; } function stationMatchesQuery(station, query = state.query) { const needle = normalize(query); return !needle || [station.name, station.shortName, station.address].some(value => normalize(value).includes(needle)); } -function stationMatchesLocation(station) { const filter = state.locationFilter; return (!filter.province || station.province === filter.province) && (!filter.city || station.city === filter.city) && (!filter.district || stationDistrictName(station) === filter.district); } +function locationFilterKey(filter) { return [filter.level || 'location', filter.province || '', filter.city || '', filter.district || ''].join('|'); } +function stationMatchesLocationFilter(station, filter) { return (!filter.province || station.province === filter.province) && (!filter.city || station.city === filter.city) && (!filter.district || stationDistrictName(station) === filter.district); } +function stationMatchesLocation(station) { return !state.locationFilters.length || state.locationFilters.some(filter => stationMatchesLocationFilter(station, filter)); } function stationTypeScope() { return state.stations.filter(station => state.stationFilter !== 'partner' || station.cooperative); } function filteredStations() { return stationTypeScope().filter(station => stationMatchesLocation(station) && stationMatchesQuery(station)); } function stationSearchScore(station, query) { @@ -101,7 +106,7 @@ function renderList() { document.getElementById('rankViewportMeta').textContent = `当前视野 ${formatNumber(visibleNodes.length)} · 全部 ${formatNumber(allNodes.length)}`; document.getElementById('panelRankTitle').textContent = state.userLocation && level === 'station' ? `附近${state.stationFilter === 'partner' ? '合作' : ''}加氢站` : level === 'province' ? '加氢站省份 TOP 排名' : level === 'city' ? '加氢站城市 TOP 排名' : '加氢站 TOP 排名'; if (!display.length) { box.innerHTML = '
未找到匹配站点
请尝试名称、地址、城市或拼音首字母
'; return; } - box.innerHTML = display.slice(0, 100).map((node, index) => { const distance = node.kind === 'station' ? stationDistance(node.station) : Number.POSITIVE_INFINITY, partnerTag = node.kind === 'station' && node.cooperative ? '合作' : ''; return ``; }).join(''); + box.innerHTML = display.slice(0, 100).map((node, index) => { const distance = node.kind === 'station' ? stationDistance(node.station) : Number.POSITIVE_INFINITY, partnerTag = node.kind === 'station' ? `` : '', rowValue = Number.isFinite(distance) ? `${formatNumber(distance, 1)} km` : node.kind === 'station' ? '' : `${formatNumber(node.count)} 座`; return ``; }).join(''); box.querySelectorAll('[data-node-id]').forEach(button => button.addEventListener('click', () => { const node = display.find(item => item.id === button.dataset.nodeId); if (node?.kind === 'station') selectStation(node.station, true); else if (node) state.map?.setZoomAndCenter(nextZoomForLevel(node.level), node.lnglat); })); } function compareNodes(left, right) { if (state.userLocation && left.kind === 'station' && right.kind === 'station') return stationDistance(left.station) - stationDistance(right.station); return right.count - left.count || String(left.name || '').localeCompare(String(right.name || ''), 'zh-CN'); } @@ -150,6 +155,22 @@ function renderStationSearchSuggestions() { } function openStationSearchSuggestions() { const box = document.getElementById('stationSearchSuggestions'); if (!box) return; box.hidden = false; renderStationSearchSuggestions(); } function closeStationSearchSuggestions() { const box = document.getElementById('stationSearchSuggestions'); if (box) box.hidden = true; state.activeSuggestion = -1; } +function locationFilterLabel(filter) { return filter.label || (filter.district ? stationGroupName({ city: filter.district }, 'city') : filter.city ? stationGroupName({ city: filter.city }, 'city') : stationGroupName({ province: filter.province }, 'province')); } +function renderLocationFilterChips() { + const rail = document.getElementById('selectedLocationFilters'); if (!rail) return; + rail.hidden = !state.locationFilters.length; + rail.innerHTML = state.locationFilters.map(filter => { const key = locationFilterKey(filter), label = locationFilterLabel(filter); return ``; }).join(''); +} +function removeLocationFilter(key) { + state.locationFilters = state.locationFilters.filter(filter => locationFilterKey(filter) !== key); + state.selected = null; closeDetail(); renderLocationFilterChips(); render(); renderStationSearchSuggestions(); + document.getElementById('selectedRegionHint').textContent = state.locationFilters.length ? `视角: 已筛选 ${state.locationFilters.map(locationFilterLabel).join('、')}` : '视角: 全国加氢站网络'; +} +function addLocationFilter(option) { + const filter = { level: option.level, province: option.province, city: option.city, district: option.district, label: option.label }; + if (!state.locationFilters.some(current => locationFilterKey(current) === locationFilterKey(filter))) state.locationFilters.push(filter); + renderLocationFilterChips(); +} function focusSearchResults() { const stations = filteredStations(); if (!state.map || !stations.length) return; const longitudes = stations.map(station => Number(station.longitude)), latitudes = stations.map(station => Number(station.latitude)); @@ -161,11 +182,11 @@ function focusSearchResults() { function handleStationSearchInput(value) { state.searchText = value; document.getElementById('clearSearch').hidden = !normalize(value); state.activeSuggestion = -1; openStationSearchSuggestions(); window.clearTimeout(state.searchDebounce); state.searchDebounce = window.setTimeout(() => { state.query = value; state.selected = null; closeDetail(); render(); if (normalize(value)) focusSearchResults(); }, 180); } function selectStationSearchSuggestion(index) { const item = state.suggestions[index]; if (!item) return; - if (item.type === 'location') { state.locationFilter = { province: item.province, city: item.city, district: item.district }; state.query = ''; state.searchText = ''; document.getElementById('stationSearch').value = ''; document.getElementById('clearSearch').hidden = true; state.map?.setZoomAndCenter(item.level === 'province' ? 7.2 : item.level === 'city' ? 10.5 : 13, item.lnglat); document.getElementById('selectedRegionHint').textContent = `视角: ${item.path}`; closeStationSearchSuggestions(); render(); return; } + if (item.type === 'location') { addLocationFilter(item); state.query = ''; state.searchText = ''; document.getElementById('stationSearch').value = ''; document.getElementById('clearSearch').hidden = true; state.map?.setZoomAndCenter(item.level === 'province' ? 7.2 : item.level === 'city' ? 10.5 : 13, item.lnglat); document.getElementById('selectedRegionHint').textContent = `视角: 已筛选 ${state.locationFilters.map(locationFilterLabel).join('、')}`; closeStationSearchSuggestions(); render(); return; } closeStationSearchSuggestions(); selectStation(item.station, true); } function setStationFilter(filter) { if (!['all', 'partner'].includes(filter) || state.stationFilter === filter) return; state.stationFilter = filter; state.selected = null; closeDetail(); document.querySelectorAll('[data-station-filter]').forEach(button => button.classList.toggle('is-active', button.dataset.stationFilter === filter)); render(); renderStationSearchSuggestions(); } -function clearSearch() { window.clearTimeout(state.searchDebounce); document.getElementById('stationSearch').value = ''; state.query = ''; state.searchText = ''; state.locationFilter = { province: '', city: '', district: '' }; closeStationSearchSuggestions(); closeDetail(); resetMap(); render(); } +function clearSearch() { window.clearTimeout(state.searchDebounce); document.getElementById('stationSearch').value = ''; state.query = ''; state.searchText = ''; state.locationFilters = []; renderLocationFilterChips(); closeStationSearchSuggestions(); closeDetail(); resetMap(); render(); } function handleSearchKeydown(event) { if (event.key === 'Escape') { closeStationSearchSuggestions(); event.currentTarget.blur(); return; } if (!['ArrowDown', 'ArrowUp', 'Enter'].includes(event.key)) return; const box = document.getElementById('stationSearchSuggestions'); if (box?.hidden) openStationSearchSuggestions(); if (event.key === 'Enter' && state.activeSuggestion >= 0) { event.preventDefault(); selectStationSearchSuggestion(state.activeSuggestion); return; } if (event.key !== 'Enter') { event.preventDefault(); const direction = event.key === 'ArrowDown' ? 1 : -1; state.activeSuggestion = (state.activeSuggestion + direction + state.suggestions.length) % Math.max(state.suggestions.length, 1); renderStationSearchSuggestions(); } } function selectStation(station, fit = false) { diff --git a/station-navigation/index.html b/station-navigation/index.html index 69a6c06c..decae925 100644 --- a/station-navigation/index.html +++ b/station-navigation/index.html @@ -33,12 +33,15 @@ +
加氢站类型分布STATUS
--
全部站点
--
合作站
--
外部站
+
正在同步加氢站数据…
+
全部 0
@@ -53,7 +56,7 @@
地图引擎: 羚牛氢能 GIS (AMap 3D Engine)站点数据服务 · 公开目录视角: 全国加氢站网络
diff --git a/station-navigation/server.py b/station-navigation/server.py index 6831ed60..96037190 100644 --- a/station-navigation/server.py +++ b/station-navigation/server.py @@ -125,6 +125,11 @@ def _prewarm_station_directory_cache(): class StationNavigationHandler(SimpleHTTPRequestHandler): server_version = "LingniuStationNavigation/1.0" + def __init__(self, *args, **kwargs): + # Static files must resolve from this release directory even when the + # local launcher is invoked from the repository root. + super().__init__(*args, directory=str(ROOT), **kwargs) + def do_GET(self): path = urlparse(self.path).path if path in {"/", "/index.html"}: diff --git a/station-navigation/styles.css b/station-navigation/styles.css index 9a1ee725..ce36b532 100644 --- a/station-navigation/styles.css +++ b/station-navigation/styles.css @@ -1,8 +1,17 @@ /* Keep the public service visually identical to the main map shell. */ -.station-navigation-shell .header-kpi-group { display: flex; } +.station-navigation-shell .station-summary-strip { display: none; } +.station-navigation-shell .station-summary-strip .panel-header { margin-bottom: 8px; } +.station-navigation-shell .station-summary-strip .status-glass-grid3 { margin-bottom: 7px; } +.station-navigation-shell .station-summary-strip .glass-cell { padding: 6px 9px; } .station-navigation-shell .map-filter-chip { min-height: 27px; padding: 0 9px; border: 1px solid var(--glass-border); border-radius: 8px; background: var(--pill-bg); color: var(--text-muted); font-size: 10px; font-weight: 700; cursor: pointer; } .station-navigation-shell .map-filter-chip.is-active { border-color: rgba(0,113,67,.24); background: rgba(0,113,67,.1); color: var(--accent-primary); } .station-navigation-shell .filter-chip-rail { display: flex; gap: 6px; } +.station-navigation-shell .selected-location-filter-rail { display: flex; align-items: center; gap: 6px; min-width: 0; max-width: min(360px, 30vw); overflow-x: auto; scrollbar-width: none; } +.station-navigation-shell .selected-location-filter-rail::-webkit-scrollbar { display: none; } +.station-navigation-shell .selected-location-filter-rail[hidden] { display: none; } +.station-navigation-shell .selected-location-filter-chip { display: inline-flex; flex: 0 0 auto; align-items: center; gap: 7px; min-height: 29px; max-width: 132px; padding: 0 8px 0 10px; border: 1px solid rgba(0,113,67,.22); border-radius: 999px; background: rgba(0,113,67,.09); color: var(--accent-primary); font-size: 10px; font-weight: 700; cursor: pointer; } +.station-navigation-shell .selected-location-filter-chip span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } +.station-navigation-shell .selected-location-filter-chip b { font: 700 15px/1 -apple-system, BlinkMacSystemFont, sans-serif; } .station-navigation-shell .province-info-card.is-station-point { min-width: 92px; } .station-navigation-shell .province-info-card.is-station-point .p-total { color: var(--accent-primary); } .station-navigation-shell .province-info-card.is-external .p-total { color: var(--text-muted); } @@ -10,11 +19,136 @@ .station-navigation-shell .rank-glass-row.is-selected { background: rgba(0,113,67,.09); border-color: rgba(0,113,67,.2); } .station-navigation-shell .r-name { display: flex; min-width: 0; align-items: flex-start; gap: 5px; line-height: 1.35; } .station-navigation-shell .station-list-name { min-width: 0; overflow-wrap: anywhere; white-space: normal; } -.station-navigation-shell .station-list-partner-tag { flex: 0 0 auto; margin-top: 1px; padding: 2px 5px; border-radius: 4px; background: rgba(0,113,67,.1); color: var(--accent-primary); font-size: 9px; font-weight: 700; line-height: 1; } +.station-navigation-shell .station-list-partner-tag { flex: 0 0 30px; min-width: 30px; margin-top: 1px; padding: 2px 5px; border-radius: 4px; background: rgba(0,113,67,.1); color: var(--accent-primary); font-size: 9px; font-weight: 700; line-height: 1; text-align: center; } +.station-navigation-shell .station-list-partner-tag.is-placeholder { visibility: hidden; } .station-navigation-shell .rank-empty { display: grid; min-height: 160px; place-items: center; color: var(--text-muted); font-size: 12px; text-align: center; } .station-navigation-shell .map-detail-card .detail-grid { margin-bottom: 0; } @media (max-width: 760px) { - .station-navigation-shell .header-kpi-group { display: flex; } - .station-navigation-shell .filter-chip-rail { max-width: 124px; overflow: hidden; } - .station-navigation-shell .map-filter-chip { padding: 0 7px; font-size: 9px; } + /* Mobile is navigation-first: keep the first screen focused on map, + search and the next action, rather than dashboard chrome. */ + .station-navigation-shell .liquid-header { + position: relative; + padding: 9px 10px 10px; + gap: 8px; + } + + .station-navigation-shell .header-left { + width: calc(100% - 78px); + gap: 8px; + } + + .station-navigation-shell .brand-block { flex-basis: 118px; min-width: 96px; } + .station-navigation-shell .brand-logo-svg { max-width: 118px; } + .station-navigation-shell .brand-divider { height: 18px; } + .station-navigation-shell .cockpit-title { font-size: 14px; } + + .station-navigation-shell .header-controls { + position: absolute; + top: 8px; + right: 8px; + width: auto; + order: initial; + } + + .station-navigation-shell .theme-switcher-bw { padding: 2px; border-radius: 9px; } + .station-navigation-shell .theme-switcher-bw .bw-btn { display: grid; width: 31px; min-height: 28px; padding: 4px; place-items: center; } + .station-navigation-shell .theme-switcher-bw .bw-btn span { display: none; } + .station-navigation-shell .header-kpi-group, + .station-navigation-shell .station-status-card { display: none; } + .station-navigation-shell .station-summary-strip { display: block; padding: 9px 11px; border-radius: 14px; flex: 0 0 auto; } + .station-navigation-shell .station-summary-strip .panel-header { margin-bottom: 7px; padding-bottom: 5px; } + .station-navigation-shell .station-summary-strip .status-glass-grid3 { gap: 5px; margin-bottom: 6px; } + .station-navigation-shell .station-summary-strip .glass-cell { padding: 6px; } + + .station-navigation-shell .map-spatial-container { + height: clamp(430px, 58dvh, 540px); + min-height: clamp(430px, 58dvh, 540px); + } + + .station-navigation-shell .map-top-bar { display: none; } + + .station-navigation-shell .map-explore-toolbar { + top: 8px; + left: 8px; + right: 8px; + gap: 6px; + padding: 5px; + border-radius: 14px; + } + + .station-navigation-shell .locate-btn { + flex-basis: 36px; + width: 36px; + min-height: 36px; + border-radius: 10px; + } + + .station-navigation-shell .entity-search-field { + height: 36px; + border-radius: 10px; + } + + .station-navigation-shell .entity-search-field input { font-size: 12px; } + .station-navigation-shell .selected-location-filter-rail { order: 3; flex: 1 0 100%; max-width: none; padding-bottom: 1px; } + .station-navigation-shell .filter-chip-rail { order: 4; max-width: none; overflow: visible; } + .station-navigation-shell .map-filter-chip { min-height: 30px; padding: 0 10px; font-size: 10px; } + .station-navigation-shell .filter-result-meta { order: 5; padding-right: 5px; font-size: 9px; } + + .station-navigation-shell .explore-suggestions { + width: calc(100vw - 32px); + max-height: min(300px, calc(100dvh - 248px)); + border-radius: 14px; + } + + .station-navigation-shell .map-action-controls { + right: 8px; + bottom: 31px; + } + + .station-navigation-shell .map-action-controls .glass-btn:nth-child(1), + .station-navigation-shell .map-action-controls .glass-btn:nth-child(2) { display: none; } + + .station-navigation-shell .map-action-controls .glass-btn { + min-height: 32px; + padding: 6px 10px; + border-radius: 10px; + font-size: 10px; + } + + .station-navigation-shell .map-detail-card { + bottom: 46px; + max-height: min(42dvh, 300px); + padding: 12px; + border-radius: 17px; + } + + .station-navigation-shell .detail-title-wrap h2 { + display: -webkit-box; + overflow: hidden; + white-space: normal; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + } + + .station-navigation-shell .detail-navigate-btn, + .station-navigation-shell .detail-close-btn { + width: 32px; + height: 32px; + flex-basis: 32px; + } + + .station-navigation-shell .detail-navigate-btn svg { width: 15px; height: 15px; } + .station-navigation-shell .sidebar-operations { gap: 8px; } + .station-navigation-shell .sidebar-card { padding: 10px 11px; border-radius: 14px; } + .station-navigation-shell .status-glass-grid3 { gap: 5px; margin-bottom: 7px; } + .station-navigation-shell .glass-cell { padding: 6px; } + .station-navigation-shell .rank-glass-row { min-height: 42px; padding: 7px 8px; } +} + +@media (max-width: 390px) { + .station-navigation-shell .header-left { width: calc(100% - 76px); } + .station-navigation-shell .brand-block { flex-basis: 104px; min-width: 88px; } + .station-navigation-shell .brand-logo-svg { max-width: 104px; } + .station-navigation-shell .cockpit-title { font-size: 13px; } + .station-navigation-shell .brand-divider { margin-left: -2px; } } diff --git a/station-navigation/tests/test_app.mjs b/station-navigation/tests/test_app.mjs index 333fa69e..1f9415ba 100644 --- a/station-navigation/tests/test_app.mjs +++ b/station-navigation/tests/test_app.mjs @@ -3,6 +3,7 @@ import fs from 'node:fs'; import vm from 'node:vm'; const source = fs.readFileSync(new URL('../app.js', import.meta.url), 'utf8'); +const styles = fs.readFileSync(new URL('../styles.css', import.meta.url), 'utf8'); const sandbox = { console, document: { addEventListener() {}, getElementById() { return null; } }, @@ -48,7 +49,7 @@ assert.equal(sandbox.stationNodeCount, 3); assert.equal(sandbox.locationOptionCount, 8); vm.runInNewContext(` globalThis.inferredDistrict = stationDistrictName({ province: '浙江省', city: '嘉兴市', address: '嘉兴市海盐县海盐经济开发区' }); - state.locationFilter = { province: '', city: '', district: '' }; + state.locationFilters = []; state.query = '广州'; globalThis.queryMatches = stationMatchesQuery({ name: '广州合作站' }); globalThis.queryMisses = stationMatchesQuery({ name: '杭州合作站' }); @@ -56,18 +57,47 @@ vm.runInNewContext(` assert.equal(sandbox.inferredDistrict, '海盐县'); assert.equal(sandbox.queryMatches, true); assert.equal(sandbox.queryMisses, false); +vm.runInNewContext(` + state.query = ''; + state.locationFilters = [ + { level: 'city', province: '广东省', city: '广州市', district: '', label: '广州' }, + { level: 'city', province: '浙江省', city: '嘉兴市', district: '', label: '嘉兴' } + ]; + globalThis.multiLocationMatches = [ + stationMatchesLocation({ province: '广东省', city: '广州市', district: '白云区' }), + stationMatchesLocation({ province: '浙江省', city: '嘉兴市', district: '海盐县' }), + stationMatchesLocation({ province: '广东省', city: '深圳市', district: '南山区' }) + ]; +`, sandbox); +assert.equal(sandbox.multiLocationMatches.join(','), 'true,true,false'); assert.ok(Math.abs(sandbox.distanceKm([113, 23], [114, 23]) - 102.4) < 1); assert.match(source, /zoom < 11\) return 'city'/); assert.match(source, /state\.userLocation && left\.kind === 'station'/); assert.doesNotMatch(source, /rankSecondaryTab|setRank\(/); assert.match(source, /stationSearchSuggestions/); assert.match(source, /handleStationSearchInput/); +assert.match(source, /locationFilters/); +assert.match(source, /renderLocationFilterChips/); +assert.match(source, /kpiTotal|kpiPartner/); +const index = fs.readFileSync(new URL('../index.html', import.meta.url), 'utf8'); +assert.match(index, /station-summary-strip/); +assert.match(index, /station-status-card/); +assert.equal((index.match(/id="statusTotal"/g) || []).length, 1); +assert.equal((index.match(/id="mobileStatusTotal"/g) || []).length, 1); assert.match(source, /window\.setTimeout\(\(\) => \{ state\.query = value/); assert.match(source, /focusSearchResults\(\)/); assert.match(source, /visibleOnly && !normalize\(state\.query\)/); assert.match(source, /station-list-partner-tag/); +assert.match(source, /station-list-partner-tag\$\{node\.cooperative \? '' : ' is-placeholder'\}/); +assert.match(source, /node\.kind === 'station' \? '' : `\$\{formatNumber\(node\.count\)\} 座`/); assert.match(source, /node\.cooperative \? 'H₂ · 合作' : ''/); assert.doesNotMatch(source, /在线 \$\{formatNumber\(node\.online\)\}/); assert.doesNotMatch(source, /monthlyHydrogenKg|totalHydrogenKg|vehicle/); assert.match(source, /uri\.amap\.com\/navigation/); +assert.equal((source.match(/function navigateToStation\(/g) || []).length, 1); +assert.match(styles, /station-summary-strip/); +assert.match(styles, /header-kpi-group,\n \.station-navigation-shell \.station-status-card/); +assert.match(styles, /theme-switcher-bw \.bw-btn span \{ display: none; \}/); +assert.match(styles, /height: clamp\(430px, 58dvh, 540px\)/); +assert.match(styles, /map-action-controls \.glass-btn:nth-child\(2\)/); console.log('station navigation app tests: ok'); diff --git a/station-navigation/tests/test_server.py b/station-navigation/tests/test_server.py index 625dd4c8..358abb19 100644 --- a/station-navigation/tests/test_server.py +++ b/station-navigation/tests/test_server.py @@ -30,6 +30,9 @@ class StationNavigationTest(unittest.TestCase): def test_static_assets_are_fingerprinted(self): self.assertRegex(server.STATIC_ASSET_VERSION, r"^[0-9a-f]{16}$") + def test_static_assets_resolve_from_the_release_directory(self): + self.assertIn('directory=str(ROOT)', Path(__file__).parents[1].joinpath('server.py').read_text(encoding='utf-8')) + def test_default_cache_window_is_two_minutes(self): self.assertEqual(server.STATION_CACHE_SECONDS, 120)