mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-06 11:24:00 +00:00
test(qa): floor verification on both engines
qa-floor-verify --engine=cesium|navara: on an engine without a viewer the
camera pin, the tile readiness, the mesh probes (engine.surface
sampleHeightDetailed, tiles only, excluding the layer's mover sets) and the
sprite census (the probe's drawn()) go through the engine. The Cesium path
is unchanged. Live AUS traffic: Cesium FAIL as on 7c7422e2 (13 contacts at
the -27 m geoid fallback); Navara FAIL with 1 of 15 low contacts under the
mesh (68.6 m against 121.4 m). Task 10b, checklist item 7.
This commit is contained in:
1 parent
132a941e9a
commit
ba1191b2e5
1 file changed
+51
-4
@@ -10,7 +10,12 @@ import fs from 'node:fs';
|
|||||||
|
|
||||||
// QA_BASE_URL matches the sibling harnesses (qa-height-datum / qa-cctv-v2) so a
|
// QA_BASE_URL matches the sibling harnesses (qa-height-datum / qa-cctv-v2) so a
|
||||||
// secondary checkout can verify against its own dev server instead of the default :4173.
|
// secondary checkout can verify against its own dev server instead of the default :4173.
|
||||||
const APP_URL = process.env.QA_BASE_URL || 'http://localhost:4173';
|
const BASE_URL = process.env.QA_BASE_URL || 'http://localhost:4173';
|
||||||
|
// --engine=cesium|navara (phase 3): on Navara the camera, the mesh probes and
|
||||||
|
// the sprite census go through the engine and the QA probe.
|
||||||
|
const ENGINE = (process.argv.find((arg) => arg.startsWith('--engine=')) ?? '--engine=cesium').slice(9);
|
||||||
|
const APP_URL =
|
||||||
|
ENGINE === 'cesium' ? BASE_URL : `${BASE_URL.replace(/\/$/, '')}/?engine=${ENGINE}`;
|
||||||
// CLI: --lat --lon --floor-min --floor-max (defaults: Austin airport)
|
// CLI: --lat --lon --floor-min --floor-max (defaults: Austin airport)
|
||||||
const argv = Object.fromEntries(process.argv.slice(2).map((a) => a.split('=')).filter((x) => x.length === 2).map(([k, v]) => [k.replace(/^--/, ''), Number(v)]));
|
const argv = Object.fromEntries(process.argv.slice(2).map((a) => a.split('=')).filter((x) => x.length === 2).map(([k, v]) => [k.replace(/^--/, ''), Number(v)]));
|
||||||
const SITE = {
|
const SITE = {
|
||||||
@@ -38,7 +43,7 @@ const page = await browser.newPage();
|
|||||||
await page.setViewport({ width: 1400, height: 900 });
|
await page.setViewport({ width: 1400, height: 900 });
|
||||||
page.on('pageerror', (e) => console.log('[pageerror]', e.message));
|
page.on('pageerror', (e) => console.log('[pageerror]', e.message));
|
||||||
await page.goto(APP_URL, { waitUntil: 'domcontentloaded', timeout: 120000 });
|
await page.goto(APP_URL, { waitUntil: 'domcontentloaded', timeout: 120000 });
|
||||||
await page.waitForFunction(() => window.__godsEyeView?.dataManager && window.__godsEyeView?.viewer, { timeout: 150000 });
|
await page.waitForFunction(() => window.__godsEyeView?.dataManager && window.__godsEyeView?.engine, { timeout: 150000 });
|
||||||
await sleep(2000);
|
await sleep(2000);
|
||||||
|
|
||||||
// Let the app's boot fly-to fully settle FIRST (it was overriding an early
|
// Let the app's boot fly-to fully settle FIRST (it was overriding an early
|
||||||
@@ -46,8 +51,16 @@ await sleep(2000);
|
|||||||
// coarse global tiles at ~25 m and the oracle was garbage).
|
// coarse global tiles at ~25 m and the oracle was garbage).
|
||||||
await sleep(12000);
|
await sleep(12000);
|
||||||
await page.evaluate((site) => { window.__QA_SITE = site; }, SITE);
|
await page.evaluate((site) => { window.__QA_SITE = site; }, SITE);
|
||||||
const camPin = async () => page.evaluate(() => {
|
const camPin = async () => page.evaluate(async () => {
|
||||||
const v = window.__godsEyeView.viewer;
|
const v = window.__godsEyeView.viewer;
|
||||||
|
if (!v) {
|
||||||
|
const geo = await import('/src/geo/index.js');
|
||||||
|
const { camera } = window.__godsEyeView.engine;
|
||||||
|
camera.cancelFlight();
|
||||||
|
camera.setView({ destination: geo.cartesian3.fromDegrees(window.__QA_SITE.lon, window.__QA_SITE.lat, 3000) });
|
||||||
|
const c = camera.pose().cartographic;
|
||||||
|
return { lat: +(c.latitude * 180 / Math.PI).toFixed(3), lon: +(c.longitude * 180 / Math.PI).toFixed(3), h: Math.round(c.height) };
|
||||||
|
}
|
||||||
const C = v.camera.positionCartographic.constructor;
|
const C = v.camera.positionCartographic.constructor;
|
||||||
v.camera.cancelFlight();
|
v.camera.cancelFlight();
|
||||||
v.camera.setView({ destination: v.scene.globe.ellipsoid.cartographicToCartesian(C.fromDegrees(window.__QA_SITE.lon, window.__QA_SITE.lat, 3000)) });
|
v.camera.setView({ destination: v.scene.globe.ellipsoid.cartographicToCartesian(C.fromDegrees(window.__QA_SITE.lon, window.__QA_SITE.lat, 3000)) });
|
||||||
@@ -63,6 +76,7 @@ await sleep(100000);
|
|||||||
console.log('camera at probe time:', JSON.stringify(await camPin()));
|
console.log('camera at probe time:', JSON.stringify(await camPin()));
|
||||||
const ready = await page.evaluate(() => {
|
const ready = await page.evaluate(() => {
|
||||||
const v = window.__godsEyeView.viewer;
|
const v = window.__godsEyeView.viewer;
|
||||||
|
if (!v) return { tilesLoaded: window.__godsEyeView.engine.surface.tilesLoaded() };
|
||||||
const prims = v.scene.primitives;
|
const prims = v.scene.primitives;
|
||||||
for (let i = 0; i < prims.length; i++) {
|
for (let i = 0; i < prims.length; i++) {
|
||||||
const p = prims.get(i);
|
const p = prims.get(i);
|
||||||
@@ -73,11 +87,44 @@ const ready = await page.evaluate(() => {
|
|||||||
console.log('tileset ready:', JSON.stringify(ready));
|
console.log('tileset ready:', JSON.stringify(ready));
|
||||||
await sleep(8000);
|
await sleep(8000);
|
||||||
|
|
||||||
const report = await page.evaluate(() => {
|
const report = await page.evaluate(async () => {
|
||||||
const gev = window.__godsEyeView;
|
const gev = window.__godsEyeView;
|
||||||
const v = gev.viewer;
|
const v = gev.viewer;
|
||||||
const layer = gev.dataManager.layers.get('flights')?.module;
|
const layer = gev.dataManager.layers.get('flights')?.module;
|
||||||
if (!layer) return { err: 'no flights module' };
|
if (!layer) return { err: 'no flights module' };
|
||||||
|
if (!v) {
|
||||||
|
// The engine path: mesh probes through engine.surface, excluding the
|
||||||
|
// layer's own mover sets; the census from the probe's drawn().
|
||||||
|
const geo = await import('/src/geo/index.js');
|
||||||
|
const { engine } = gev;
|
||||||
|
const center = geo.cartesian3.fromDegrees(window.__QA_SITE.lon, window.__QA_SITE.lat, 200);
|
||||||
|
const nearby = layer.getNearby(center, 15000, 60);
|
||||||
|
const exclude = engine.movers.list().map(({ id }) => id).filter((id) => id.startsWith('flights'));
|
||||||
|
const out = [];
|
||||||
|
for (const p of nearby) {
|
||||||
|
const c = geo.cartographic.fromCartesian(p.position);
|
||||||
|
const answer = engine.surface.sampleHeightDetailed(
|
||||||
|
geo.cartographic.fromRadians(c.longitude, c.latitude, 0),
|
||||||
|
{ exclude },
|
||||||
|
);
|
||||||
|
const meshH = answer?.source === 'tiles' && Number.isFinite(answer.height) ? answer.height : null;
|
||||||
|
out.push({
|
||||||
|
id: p.id,
|
||||||
|
renderAltM: +c.height.toFixed(1),
|
||||||
|
meshM: meshH != null ? +meshH.toFixed(1) : null,
|
||||||
|
aboveMeshM: meshH != null ? +(c.height - meshH).toFixed(1) : null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let shown = 0, hidden = 0;
|
||||||
|
for (const row of gev.layers.drawn('flights') ?? []) {
|
||||||
|
if (!row.position) continue;
|
||||||
|
const cc = geo.cartographic.fromCartesian(row.position);
|
||||||
|
const la = cc.latitude * 180 / Math.PI, lo = cc.longitude * 180 / Math.PI;
|
||||||
|
if (Math.abs(la - window.__QA_SITE.lat) > 0.08 || Math.abs(lo - window.__QA_SITE.lon) > 0.10) continue;
|
||||||
|
if (row.show) shown++; else hidden++;
|
||||||
|
}
|
||||||
|
return { ausContacts: out.length, contacts: out.slice(0, 16), spritesShown: shown, spritesHidden: hidden };
|
||||||
|
}
|
||||||
const ell = v.scene.globe.ellipsoid;
|
const ell = v.scene.globe.ellipsoid;
|
||||||
const C = v.camera.positionCartographic.constructor;
|
const C = v.camera.positionCartographic.constructor;
|
||||||
const center = ell.cartographicToCartesian(C.fromDegrees(window.__QA_SITE.lon, window.__QA_SITE.lat, 200));
|
const center = ell.cartographicToCartesian(C.fromDegrees(window.__QA_SITE.lon, window.__QA_SITE.lat, 200));
|
||||||
|
|||||||
Reference in new issue
Block a user