mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 10:24:02 +00:00
refactor: isolate Location controls and cancellable search
This commit is contained in:
1 parent
20c1611354
commit
ea77b49482
16 files changed
+604
-245
No files matched your search
@@ -159,5 +159,12 @@
|
||||
"src/ui/clearLayersControl.js",
|
||||
"scripts/qa-layer-panel.mjs",
|
||||
"src/loadingFeedback.js",
|
||||
"src/data/installationFeedback.js"
|
||||
"src/data/installationFeedback.js",
|
||||
"src/ui/location.js",
|
||||
"src/ui/locationControls.js",
|
||||
"src/ui/locationSearch.js",
|
||||
"src/locationStatus.js",
|
||||
"src/ui/locationControls.test.mjs",
|
||||
"src/ui/locationSearch.test.mjs",
|
||||
"scripts/qa-location-controls.mjs"
|
||||
]
|
||||
+169
-51
@@ -10,27 +10,47 @@
|
||||
"src/data/localGeojsonCore.js",
|
||||
"src/data/localGeojsonLod.js"
|
||||
],
|
||||
"external": ["cesium"]
|
||||
"external": [
|
||||
"cesium"
|
||||
]
|
||||
},
|
||||
"application": {
|
||||
"exports": ["./application"],
|
||||
"modules": ["src/app/application.js"],
|
||||
"exports": [
|
||||
"./application"
|
||||
],
|
||||
"modules": [
|
||||
"src/app/application.js"
|
||||
],
|
||||
"external": []
|
||||
},
|
||||
"viewer": {
|
||||
"exports": ["./application/viewer"],
|
||||
"modules": ["src/app/viewer.js"],
|
||||
"external": ["cesium"]
|
||||
"exports": [
|
||||
"./application/viewer"
|
||||
],
|
||||
"modules": [
|
||||
"src/app/viewer.js"
|
||||
],
|
||||
"external": [
|
||||
"cesium"
|
||||
]
|
||||
},
|
||||
"vite-build": {
|
||||
"runtime": "node",
|
||||
"exports": ["./build/vite"],
|
||||
"modules": ["build/vite.js"],
|
||||
"external": ["vite-plugin-cesium"]
|
||||
"exports": [
|
||||
"./build/vite"
|
||||
],
|
||||
"modules": [
|
||||
"build/vite.js"
|
||||
],
|
||||
"external": [
|
||||
"vite-plugin-cesium"
|
||||
]
|
||||
},
|
||||
"live-providers": {
|
||||
"runtime": "node",
|
||||
"exports": ["./server/providers/live"],
|
||||
"exports": [
|
||||
"./server/providers/live"
|
||||
],
|
||||
"modules": [
|
||||
"server/providers/live.js",
|
||||
"server/providers/common/http.js",
|
||||
@@ -45,16 +65,24 @@
|
||||
"src/data/aisStreamAdapter.js",
|
||||
"src/data/aisWatchdog.js"
|
||||
],
|
||||
"external": ["ws"]
|
||||
"external": [
|
||||
"ws"
|
||||
]
|
||||
},
|
||||
"adsb-lol-source": {
|
||||
"exports": ["./sources/adsb-lol"],
|
||||
"modules": ["src/data/adsbLolFallback.js"],
|
||||
"exports": [
|
||||
"./sources/adsb-lol"
|
||||
],
|
||||
"modules": [
|
||||
"src/data/adsbLolFallback.js"
|
||||
],
|
||||
"external": []
|
||||
},
|
||||
"place-providers": {
|
||||
"runtime": "node",
|
||||
"exports": ["./server/providers/places"],
|
||||
"exports": [
|
||||
"./server/providers/places"
|
||||
],
|
||||
"modules": [
|
||||
"server/providers/places.js",
|
||||
"server/providers/places/google.js",
|
||||
@@ -69,13 +97,19 @@
|
||||
"external": []
|
||||
},
|
||||
"place-payloads": {
|
||||
"exports": ["./sources/places"],
|
||||
"modules": ["src/data/placeProviderPayloads.js"],
|
||||
"exports": [
|
||||
"./sources/places"
|
||||
],
|
||||
"modules": [
|
||||
"src/data/placeProviderPayloads.js"
|
||||
],
|
||||
"external": []
|
||||
},
|
||||
"space-providers": {
|
||||
"runtime": "node",
|
||||
"exports": ["./server/providers/space"],
|
||||
"exports": [
|
||||
"./server/providers/space"
|
||||
],
|
||||
"modules": [
|
||||
"server/providers/space.js",
|
||||
"server/providers/space/celestrak.js",
|
||||
@@ -86,13 +120,19 @@
|
||||
"external": []
|
||||
},
|
||||
"space-requests": {
|
||||
"exports": ["./sources/space"],
|
||||
"modules": ["src/data/spaceProviderRequests.js"],
|
||||
"exports": [
|
||||
"./sources/space"
|
||||
],
|
||||
"modules": [
|
||||
"src/data/spaceProviderRequests.js"
|
||||
],
|
||||
"external": []
|
||||
},
|
||||
"terrain-provider": {
|
||||
"runtime": "node",
|
||||
"exports": ["./server/providers/terrain"],
|
||||
"exports": [
|
||||
"./server/providers/terrain"
|
||||
],
|
||||
"modules": [
|
||||
"server/providers/terrain.js",
|
||||
"src/data/terrainHeightsProxy.js"
|
||||
@@ -100,30 +140,50 @@
|
||||
"external": []
|
||||
},
|
||||
"terrain-source": {
|
||||
"exports": ["./sources/terrain"],
|
||||
"modules": ["src/data/terrainHeightsProxy.js"],
|
||||
"exports": [
|
||||
"./sources/terrain"
|
||||
],
|
||||
"modules": [
|
||||
"src/data/terrainHeightsProxy.js"
|
||||
],
|
||||
"external": []
|
||||
},
|
||||
"traffic-provider": {
|
||||
"runtime": "node",
|
||||
"exports": ["./server/providers/traffic"],
|
||||
"modules": ["server/providers/traffic.js", "src/data/tomtomTiles.js"],
|
||||
"exports": [
|
||||
"./server/providers/traffic"
|
||||
],
|
||||
"modules": [
|
||||
"server/providers/traffic.js",
|
||||
"src/data/tomtomTiles.js"
|
||||
],
|
||||
"external": []
|
||||
},
|
||||
"traffic-source": {
|
||||
"exports": ["./sources/traffic"],
|
||||
"modules": ["src/data/tomtomTiles.js"],
|
||||
"exports": [
|
||||
"./sources/traffic"
|
||||
],
|
||||
"modules": [
|
||||
"src/data/tomtomTiles.js"
|
||||
],
|
||||
"external": []
|
||||
},
|
||||
"firms-provider": {
|
||||
"runtime": "node",
|
||||
"exports": ["./server/providers/firms"],
|
||||
"modules": ["server/providers/firms.js", "src/data/firmsCsv.js"],
|
||||
"exports": [
|
||||
"./server/providers/firms"
|
||||
],
|
||||
"modules": [
|
||||
"server/providers/firms.js",
|
||||
"src/data/firmsCsv.js"
|
||||
],
|
||||
"external": []
|
||||
},
|
||||
"gbfs-provider": {
|
||||
"runtime": "node",
|
||||
"exports": ["./server/providers/gbfs"],
|
||||
"exports": [
|
||||
"./server/providers/gbfs"
|
||||
],
|
||||
"modules": [
|
||||
"server/providers/gbfs.js",
|
||||
"server/providers/common/http.js",
|
||||
@@ -132,13 +192,19 @@
|
||||
"external": []
|
||||
},
|
||||
"gbfs-source": {
|
||||
"exports": ["./sources/gbfs"],
|
||||
"modules": ["src/data/gbfsSource.js"],
|
||||
"exports": [
|
||||
"./sources/gbfs"
|
||||
],
|
||||
"modules": [
|
||||
"src/data/gbfsSource.js"
|
||||
],
|
||||
"external": []
|
||||
},
|
||||
"cctv-provider": {
|
||||
"runtime": "node",
|
||||
"exports": ["./server/providers/cctv"],
|
||||
"exports": [
|
||||
"./server/providers/cctv"
|
||||
],
|
||||
"modules": [
|
||||
"server/providers/cctv.js",
|
||||
"server/providers/cctv/catalog.js",
|
||||
@@ -155,7 +221,9 @@
|
||||
},
|
||||
"radio-provider": {
|
||||
"runtime": "node",
|
||||
"exports": ["./server/providers/radio"],
|
||||
"exports": [
|
||||
"./server/providers/radio"
|
||||
],
|
||||
"modules": [
|
||||
"server/providers/radio.js",
|
||||
"server/providers/radio/catalog.js",
|
||||
@@ -169,7 +237,9 @@
|
||||
},
|
||||
"overpass-provider": {
|
||||
"runtime": "node",
|
||||
"exports": ["./server/providers/overpass"],
|
||||
"exports": [
|
||||
"./server/providers/overpass"
|
||||
],
|
||||
"modules": [
|
||||
"server/providers/common/geo.js",
|
||||
"server/providers/common/http.js",
|
||||
@@ -188,7 +258,9 @@
|
||||
},
|
||||
"military-installations-provider": {
|
||||
"runtime": "node",
|
||||
"exports": ["./server/providers/military-installations"],
|
||||
"exports": [
|
||||
"./server/providers/military-installations"
|
||||
],
|
||||
"modules": [
|
||||
"server/providers/common/http.js",
|
||||
"server/providers/common/query.js",
|
||||
@@ -205,7 +277,9 @@
|
||||
},
|
||||
"regional-provider": {
|
||||
"runtime": "node",
|
||||
"exports": ["./server/providers/regional"],
|
||||
"exports": [
|
||||
"./server/providers/regional"
|
||||
],
|
||||
"modules": [
|
||||
"server/providers/common/http.js",
|
||||
"server/providers/common/query.js",
|
||||
@@ -224,7 +298,9 @@
|
||||
},
|
||||
"openai-provider": {
|
||||
"runtime": "node",
|
||||
"exports": ["./server/providers/openai"],
|
||||
"exports": [
|
||||
"./server/providers/openai"
|
||||
],
|
||||
"modules": [
|
||||
"server/providers/common/rate-limit.js",
|
||||
"server/providers/common/request.js",
|
||||
@@ -244,7 +320,9 @@
|
||||
},
|
||||
"standalone-key-setup": {
|
||||
"runtime": "node",
|
||||
"exports": ["./server/standalone/key-setup"],
|
||||
"exports": [
|
||||
"./server/standalone/key-setup"
|
||||
],
|
||||
"modules": [
|
||||
"scripts/pinokio-environment.mjs",
|
||||
"server/providers/common/source-root.js",
|
||||
@@ -255,7 +333,9 @@
|
||||
"external": []
|
||||
},
|
||||
"place-search": {
|
||||
"exports": ["./search"],
|
||||
"exports": [
|
||||
"./search"
|
||||
],
|
||||
"modules": [
|
||||
"src/search/index.js",
|
||||
"src/search/placeSearch.js",
|
||||
@@ -265,17 +345,27 @@
|
||||
"external": []
|
||||
},
|
||||
"panel-disclosure": {
|
||||
"exports": ["./ui/panels"],
|
||||
"modules": ["src/ui/panelDisclosure.js"],
|
||||
"exports": [
|
||||
"./ui/panels"
|
||||
],
|
||||
"modules": [
|
||||
"src/ui/panelDisclosure.js"
|
||||
],
|
||||
"external": []
|
||||
},
|
||||
"surface-keyboard": {
|
||||
"exports": ["./ui/surfaces"],
|
||||
"modules": ["src/ui/surfaceKeyboard.js"],
|
||||
"exports": [
|
||||
"./ui/surfaces"
|
||||
],
|
||||
"modules": [
|
||||
"src/ui/surfaceKeyboard.js"
|
||||
],
|
||||
"external": []
|
||||
},
|
||||
"panel-rail-layout": {
|
||||
"exports": ["./ui/layout"],
|
||||
"exports": [
|
||||
"./ui/layout"
|
||||
],
|
||||
"modules": [
|
||||
"src/ui/panelRails.js",
|
||||
"src/ui/leftPanelRail.js",
|
||||
@@ -287,7 +377,9 @@
|
||||
"external": []
|
||||
},
|
||||
"visual-input": {
|
||||
"exports": ["./ui/input"],
|
||||
"exports": [
|
||||
"./ui/input"
|
||||
],
|
||||
"modules": [
|
||||
"src/ui/visualInput.js",
|
||||
"src/ui/applicationShortcuts.js",
|
||||
@@ -296,12 +388,19 @@
|
||||
"external": []
|
||||
},
|
||||
"display-controls": {
|
||||
"exports": ["./ui/display"],
|
||||
"modules": ["src/ui/displayControls.js"],
|
||||
"exports": [
|
||||
"./ui/display"
|
||||
],
|
||||
"modules": [
|
||||
"src/ui/displayControls.js"
|
||||
],
|
||||
"external": []
|
||||
},
|
||||
"visual-effects": {
|
||||
"exports": ["./ui/effects", "./ui/effects/bloom"],
|
||||
"exports": [
|
||||
"./ui/effects",
|
||||
"./ui/effects/bloom"
|
||||
],
|
||||
"modules": [
|
||||
"src/ui/effects.js",
|
||||
"src/ui/visualEffects.js",
|
||||
@@ -314,10 +413,14 @@
|
||||
"src/styles/noir.js",
|
||||
"src/styles/snow.js"
|
||||
],
|
||||
"external": ["cesium"]
|
||||
"external": [
|
||||
"cesium"
|
||||
]
|
||||
},
|
||||
"map-source-controls": {
|
||||
"exports": ["./ui/maps"],
|
||||
"exports": [
|
||||
"./ui/maps"
|
||||
],
|
||||
"modules": [
|
||||
"src/ui/mapSource.js",
|
||||
"src/ui/mapSourceControls.js",
|
||||
@@ -327,7 +430,10 @@
|
||||
"external": []
|
||||
},
|
||||
"layer-panel": {
|
||||
"exports": ["./ui/layers", "./ui/layers/feedback"],
|
||||
"exports": [
|
||||
"./ui/layers",
|
||||
"./ui/layers/feedback"
|
||||
],
|
||||
"modules": [
|
||||
"src/ui/layers.js",
|
||||
"src/ui/layerPanel.js",
|
||||
@@ -336,5 +442,17 @@
|
||||
"src/data/installationFeedback.js"
|
||||
],
|
||||
"external": []
|
||||
},
|
||||
"location-controls": {
|
||||
"exports": [
|
||||
"./ui/location"
|
||||
],
|
||||
"modules": [
|
||||
"src/ui/location.js",
|
||||
"src/ui/locationControls.js",
|
||||
"src/ui/locationSearch.js",
|
||||
"src/locationStatus.js"
|
||||
],
|
||||
"external": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env node
|
||||
/** Location UI acceptance; controlled search results isolate UI races from geocoder availability. */
|
||||
import fs from 'node:fs';
|
||||
import puppeteer from 'puppeteer';
|
||||
const browser = await puppeteer.launch({headless:true,args:['--no-sandbox',...(process.platform === 'darwin' ? ['--use-angle=metal','--enable-gpu'] : ['--use-gl=angle','--use-angle=swiftshader'])]});
|
||||
const page=await browser.newPage();const errors=[];page.on('pageerror',e=>errors.push(e.message));let failures=0;
|
||||
const check=(name,ok)=>{console.log(`[${ok?'PASS':'FAIL'}] ${name}`);if(!ok)failures++};
|
||||
try {
|
||||
await page.setViewport({width:1440,height:900});
|
||||
await page.goto(`${process.env.QA_BASE_URL||'http://localhost:4173'}/?welcome=0`,{waitUntil:'domcontentloaded'});
|
||||
await page.waitForFunction(()=>window.__godsEyeView?.styleManager?._locationControls&&document.getElementById('loading-screen')?.classList.contains('hidden'),{timeout:60000});
|
||||
await page.click('#location-bar-toggle');
|
||||
await page.click('[data-pin-target="location-bar"]');
|
||||
const cityId=await page.$eval('.location-pill',node=>node.dataset.locationId);
|
||||
await page.click('.location-pill');
|
||||
await page.waitForFunction(()=>document.getElementById('poi-row').classList.contains('expanded'));
|
||||
check('native city selection highlights and expands its POIs',await page.evaluate(id=>window.__godsEyeView.styleManager._activeLocationId===id&&document.querySelector('.location-pill.active')?.dataset.locationId===id,cityId));
|
||||
await page.keyboard.press('w');
|
||||
check('POI keyboard action selects the second landmark',await page.evaluate(()=>window.__godsEyeView.styleManager._activePoiIndex===1&&document.querySelector('.poi-pill.active')?.dataset.poiIndex==='1'));
|
||||
check('orbit controls and indicator agree',await page.evaluate(()=>{const ui=window.__godsEyeView.styleManager;ui.setOrbit(true);const active=ui.orbitController.active&&document.getElementById('orbit-indicator').classList.contains('active');ui.setOrbit(false);return active&&!ui.orbitController.active&&!document.getElementById('orbit-indicator').classList.contains('active')}));
|
||||
await page.click('#search-toggle');
|
||||
await page.type('#location-search','qwerty');
|
||||
check('typing in search leaves POI selection unchanged',await page.evaluate(()=>window.__godsEyeView.styleManager._activePoiIndex===1));
|
||||
await page.evaluate(()=>{
|
||||
const lookup=window.__godsEyeView.styleManager._locationLookup;
|
||||
window.__qaSearchRequests=[];
|
||||
lookup.search=(query,options)=>new Promise(resolve=>window.__qaSearchRequests.push({query,options,resolve}));
|
||||
document.getElementById('location-search').value='First';
|
||||
});
|
||||
await page.keyboard.press('Enter');
|
||||
await page.waitForFunction(()=>window.__qaSearchRequests.length===1);
|
||||
await page.evaluate(()=>{document.getElementById('location-search').value='Second';document.getElementById('location-search').focus()});
|
||||
await page.keyboard.press('Enter');
|
||||
await page.waitForFunction(()=>window.__qaSearchRequests.length===2);
|
||||
check('second native submit aborts the first request and keeps current busy state',await page.evaluate(()=>window.__qaSearchRequests[0].options.signal.aborted&&document.getElementById('location-search').classList.contains('searching')));
|
||||
await page.evaluate(()=>window.__qaSearchRequests[1].resolve({label:'Second landmark, Test city'}));
|
||||
await page.waitForFunction(()=>window.__godsEyeView.styleManager._searchedLocationLabel==='Second landmark, Test city');
|
||||
await page.evaluate(()=>window.__qaSearchRequests[0].resolve({label:'First landmark, Test city'}));
|
||||
check('late result cannot overwrite the current location readout or style',await page.evaluate(()=>{const ui=window.__godsEyeView.styleManager;return ui._searchedLocationLabel==='Second landmark, Test city'&&ui._locationMiniPoi.textContent.includes('Second landmark')&&ui.activeStyle==='normal'&&!ui._locationSearch.classList.contains('searching')}));
|
||||
check('cancelled POI expansion stays closed after a frame',await page.evaluate(async id=>{const ui=window.__godsEyeView.styleManager;ui._expandPOIRow(id);ui._collapsePOIRow();await new Promise(resolve=>requestAnimationFrame(()=>requestAnimationFrame(resolve)));return !ui._poiRow.classList.contains('expanded')&&!ui._locationBarDivider.classList.contains('visible')},cityId));
|
||||
await page.evaluate(id=>window.__godsEyeView.styleManager._onCityPillClick(id),cityId);
|
||||
await page.waitForFunction(()=>document.getElementById('poi-row').classList.contains('expanded'));
|
||||
// Finish the camera's existing city flight before inspecting both layouts.
|
||||
await page.waitForFunction(()=>!window.__godsEyeView.viewer.camera._currentFlight,{timeout:10000});
|
||||
fs.mkdirSync('qa-shots/location-controls',{recursive:true});
|
||||
await page.screenshot({path:'qa-shots/location-controls/desktop.png'});
|
||||
await page.setViewport({width:620,height:900});
|
||||
await page.waitForFunction(()=>document.getElementById('left-panel-stack')?.dataset.layoutMode==='mobile');
|
||||
await page.screenshot({path:'qa-shots/location-controls/narrow.png'});
|
||||
check('native reset returns through the existing camera handoff',await page.evaluate(async()=>{const ui=window.__godsEyeView.styleManager;ui._resetGlobeBtn.click();const pending=ui._globeResetPromise;if(!pending)return false;await pending;return !ui.orbitController.active&&!window.__godsEyeView.viewer.trackedEntity}));
|
||||
check('destroyed controls cannot navigate or submit another lookup',await page.evaluate(()=>{const ui=window.__godsEyeView.styleManager;const count=window.__qaSearchRequests.length;ui._locationControls.destroy();ui._locationLookup.destroy();const before=ui._navigationGeneration;ui._locationPills.querySelector('button').click();ui._resetGlobeBtn.click();ui._locationSearch.dispatchEvent(new KeyboardEvent('keydown',{key:'Enter',bubbles:true}));return before===ui._navigationGeneration&&count===window.__qaSearchRequests.length}));
|
||||
check('no uncaught browser errors',errors.length===0);
|
||||
}finally{await browser.close()}
|
||||
console.log(`RESULT: ${failures} failures`);process.exitCode=failures?1:0;
|
||||
Reference in new issue
Block a user