mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-12 06:12:18 +00:00
feat(bikeshare): render GBFS stations on Navara
This commit is contained in:
1 parent
1a694baf5a
commit
d82a6f1550
32 files changed
+1394
-278
No files matched your search
@@ -34,6 +34,7 @@ const navaraPackage = /^(?:(?:three|postprocessing)(?:\/|$)|@navaramap\/)/;
|
||||
// engine in their renderers: cesium only in render/cesium*.js, three and
|
||||
// Navara only in render/navara*.js. The list grows with each moved layer.
|
||||
const RENDERED_LAYER_DIRS = [
|
||||
'src/layers/bikeshare/',
|
||||
'src/layers/earthquakes/',
|
||||
'src/layers/firms/',
|
||||
'src/layers/flights/',
|
||||
@@ -63,7 +64,8 @@ const renderedLayer = (file) =>
|
||||
file === 'src/celestialRing.js' ||
|
||||
file.startsWith('src/celestialRing/') ||
|
||||
RENDERED_LAYER_DIRS.some((dir) => file.startsWith(dir));
|
||||
const cesiumLayerRenderer = (file) => /\/render\/cesium[^/]*\.js$/.test(file);
|
||||
const cesiumLayerRenderer = (file) =>
|
||||
/\/render\/cesium(?:[^/]*|\/[^/]+)\.js$/.test(file);
|
||||
const navaraLayerRenderer = (file) => /\/render\/navara[^/]*\.js$/.test(file);
|
||||
const renderer = (file) =>
|
||||
/^src\/(?:ui|app|standalone|overlays)\//.test(file) ||
|
||||
|
||||
@@ -498,20 +498,28 @@
|
||||
"src/layers/traffic/model.js",
|
||||
"src/layers/traffic/timing.js",
|
||||
"src/layers/traffic/style.js",
|
||||
"src/layers/bikeshare/lifecycle.js",
|
||||
"src/layers/bikeshare/render/cesium/lifecycle.js",
|
||||
"src/layers/bikeshare/viewport.js",
|
||||
"src/layers/bikeshare/presentation.js",
|
||||
"src/layers/bikeshare/presentation.test.mjs",
|
||||
"src/layers/bikeshare/selectionModel.js",
|
||||
"src/layers/bikeshare/render/cesium.js",
|
||||
"src/layers/bikeshare/render/cesium/viewport.js",
|
||||
"src/layers/bikeshare/render/cesium/lifecycle.test.mjs",
|
||||
"src/layers/bikeshare/render/navara.js",
|
||||
"src/layers/bikeshare/render/navara.test.mjs",
|
||||
"src/layers/bikeshare/registry.js",
|
||||
"src/layers/bikeshare/controls.js",
|
||||
"src/layers/bikeshare/source.js",
|
||||
"src/layers/bikeshare/state.js",
|
||||
"src/layers/bikeshare/policy.js",
|
||||
"src/layers/bikeshare/rendering.js",
|
||||
"src/layers/bikeshare/render/cesium/rendering.js",
|
||||
"src/layers/bikeshare/testing.js",
|
||||
"src/layers/bikeshare/ingestion.js",
|
||||
"src/layers/bikeshare/queries.js",
|
||||
"src/layers/bikeshare/index.js",
|
||||
"src/layers/bikeshare/model.js",
|
||||
"src/layers/bikeshare/selection.js",
|
||||
"src/layers/bikeshare/render/cesium/selection.js",
|
||||
"src/data/traffic.js",
|
||||
"src/data/bikeshare.js",
|
||||
"src/data/flowTiles.js",
|
||||
|
||||
@@ -1405,15 +1405,15 @@
|
||||
"modules": [
|
||||
"src/layers/bikeshare/controls.js",
|
||||
"src/layers/bikeshare/index.js",
|
||||
"src/layers/bikeshare/selectionModel.js",
|
||||
"src/layers/bikeshare/presentation.js",
|
||||
"src/layers/bikeshare/ingestion.js",
|
||||
"src/layers/bikeshare/lifecycle.js",
|
||||
"src/layers/bikeshare/model.js",
|
||||
"src/sources/gbfsStations.js",
|
||||
"src/layers/bikeshare/policy.js",
|
||||
"src/layers/shared/color.js",
|
||||
"src/layers/bikeshare/queries.js",
|
||||
"src/layers/bikeshare/registry.js",
|
||||
"src/layers/bikeshare/rendering.js",
|
||||
"src/layers/bikeshare/selection.js",
|
||||
"src/layers/bikeshare/source.js",
|
||||
"src/layers/bikeshare/state.js",
|
||||
"src/layers/bikeshare/testing.js",
|
||||
@@ -1439,7 +1439,7 @@
|
||||
"src/globe/contract.js",
|
||||
"src/globe/cesium/engineFromViewer.js"
|
||||
],
|
||||
"external": ["cesium"]
|
||||
"external": []
|
||||
},
|
||||
"cctv-layer": {
|
||||
"exports": ["./layers/cctv"],
|
||||
@@ -2058,15 +2058,19 @@
|
||||
"src/layers/awareness/testing.js",
|
||||
"src/layers/bikeshare/controls.js",
|
||||
"src/layers/bikeshare/index.js",
|
||||
"src/layers/bikeshare/selectionModel.js",
|
||||
"src/layers/bikeshare/presentation.js",
|
||||
"src/layers/bikeshare/render/cesium.js",
|
||||
"src/layers/bikeshare/render/cesium/viewport.js",
|
||||
"src/layers/bikeshare/ingestion.js",
|
||||
"src/layers/bikeshare/lifecycle.js",
|
||||
"src/layers/bikeshare/render/cesium/lifecycle.js",
|
||||
"src/layers/bikeshare/model.js",
|
||||
"src/sources/gbfsStations.js",
|
||||
"src/layers/bikeshare/policy.js",
|
||||
"src/layers/bikeshare/queries.js",
|
||||
"src/layers/bikeshare/registry.js",
|
||||
"src/layers/bikeshare/rendering.js",
|
||||
"src/layers/bikeshare/selection.js",
|
||||
"src/layers/bikeshare/render/cesium/rendering.js",
|
||||
"src/layers/bikeshare/render/cesium/selection.js",
|
||||
"src/layers/bikeshare/source.js",
|
||||
"src/layers/bikeshare/state.js",
|
||||
"src/layers/bikeshare/testing.js",
|
||||
@@ -2701,6 +2705,7 @@
|
||||
"src/layers/earthquakes/render/navaraGeometry.js",
|
||||
"src/layers/earthquakes/render/navaraGrid.js",
|
||||
"src/layers/installations/render/navara.js",
|
||||
"src/layers/bikeshare/render/navara.js",
|
||||
"src/layers/installations/render/navaraGeometry.js",
|
||||
"src/layers/firms/rectangle.js",
|
||||
"src/layers/firms/render/cesium.js",
|
||||
@@ -2899,15 +2904,19 @@
|
||||
"src/layers/awareness/testing.js",
|
||||
"src/layers/bikeshare/controls.js",
|
||||
"src/layers/bikeshare/index.js",
|
||||
"src/layers/bikeshare/selectionModel.js",
|
||||
"src/layers/bikeshare/presentation.js",
|
||||
"src/layers/bikeshare/render/cesium.js",
|
||||
"src/layers/bikeshare/render/cesium/viewport.js",
|
||||
"src/layers/bikeshare/ingestion.js",
|
||||
"src/layers/bikeshare/lifecycle.js",
|
||||
"src/layers/bikeshare/render/cesium/lifecycle.js",
|
||||
"src/layers/bikeshare/model.js",
|
||||
"src/sources/gbfsStations.js",
|
||||
"src/layers/bikeshare/policy.js",
|
||||
"src/layers/bikeshare/queries.js",
|
||||
"src/layers/bikeshare/registry.js",
|
||||
"src/layers/bikeshare/rendering.js",
|
||||
"src/layers/bikeshare/selection.js",
|
||||
"src/layers/bikeshare/render/cesium/rendering.js",
|
||||
"src/layers/bikeshare/render/cesium/selection.js",
|
||||
"src/layers/bikeshare/source.js",
|
||||
"src/layers/bikeshare/state.js",
|
||||
"src/layers/bikeshare/testing.js",
|
||||
|
||||
+291
-21
@@ -1,19 +1,29 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Keyless station-name regression against the real globe and bike-share tool.
|
||||
* Run with a dev or preview server: node scripts/qa-gbfs-names.mjs --url http://localhost:4173
|
||||
* Run with a dev or QA preview server and an explicitly assigned --url.
|
||||
* GBFS documents are synthetic; no operator feed or provider key is required.
|
||||
*/
|
||||
import assert from 'node:assert/strict';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import puppeteer from 'puppeteer';
|
||||
import sharp from 'sharp';
|
||||
import { watchW1Page, redact } from './qa-browserEvidence.mjs';
|
||||
|
||||
const urlIndex = process.argv.indexOf('--url');
|
||||
const appUrl =
|
||||
urlIndex < 0 ? 'http://localhost:4173' : process.argv[urlIndex + 1];
|
||||
const shots = path.resolve('qa-shots/gbfs-names');
|
||||
if (urlIndex < 0) throw new Error('An explicit --url is required');
|
||||
const appUrl = process.argv[urlIndex + 1];
|
||||
const engineName = new URL(appUrl).searchParams.get('engine') || 'cesium';
|
||||
const extended = process.argv.includes('--w2');
|
||||
const reportIndex = process.argv.indexOf('--report');
|
||||
const reportPath =
|
||||
reportIndex < 0 ? null : path.resolve(process.argv[reportIndex + 1]);
|
||||
const shots = reportPath
|
||||
? reportPath.replace(/\.json$/, '-shots')
|
||||
: path.resolve(`qa-shots/gbfs-names/${engineName}`);
|
||||
fs.mkdirSync(shots, { recursive: true });
|
||||
const report = { engine: engineName, checks: [], poses: {}, browserErrors: [] };
|
||||
const information = {
|
||||
version: '3.0',
|
||||
data: {
|
||||
@@ -67,6 +77,7 @@ const browser = await puppeteer.launch({
|
||||
});
|
||||
let checks = 0;
|
||||
const check = (name, actual, expected) => {
|
||||
report.checks.push({ name, actual, expected });
|
||||
assert.deepEqual(actual, expected, name);
|
||||
checks++;
|
||||
console.log(`[PASS] ${name}`);
|
||||
@@ -75,6 +86,12 @@ async function open(mode = 'normal') {
|
||||
const page = await browser.newPage();
|
||||
await page.bringToFront();
|
||||
const errors = [];
|
||||
if (extended)
|
||||
watchW1Page(page, report, {
|
||||
name: mode,
|
||||
baseUrl: appUrl,
|
||||
preview: process.argv.includes('--preview'),
|
||||
});
|
||||
page.on('pageerror', (error) => errors.push(error.message));
|
||||
await page.setViewport({ width: 1440, height: 900 });
|
||||
await page.evaluateOnNewDocument(
|
||||
@@ -134,15 +151,17 @@ async function open(mode = 'normal') {
|
||||
{ timeout: 60000 },
|
||||
);
|
||||
await page.evaluate(async () => {
|
||||
const { dataManager, viewer } = window.__godsEyeView;
|
||||
const { dataManager, engine } = window.__godsEyeView;
|
||||
await window.__godsEyeView.styleManager.initialRestorePromise;
|
||||
window.__godsEyeView.styleManager.orbitController.stop();
|
||||
for (const [id, layer] of dataManager.layers) {
|
||||
if (layer.enabled)
|
||||
await dataManager.setEnabled(id, false, { origin: 'user' });
|
||||
}
|
||||
const Cartesian3 = viewer.camera.position.constructor;
|
||||
viewer.camera.cancelFlight();
|
||||
viewer.camera.setView({
|
||||
destination: Cartesian3.fromDegrees(-97.7449, 30.2701, 3000),
|
||||
const geo = await import('/src/geo/index.js');
|
||||
engine.camera.cancelFlight();
|
||||
engine.camera.setView({
|
||||
destination: geo.cartesian3.fromDegrees(-97.7449, 30.2701, 3000),
|
||||
orientation: { heading: 0, pitch: -Math.PI / 2, roll: 0 },
|
||||
});
|
||||
await dataManager.setEnabled('bikeshare', true, { origin: 'user' });
|
||||
@@ -150,6 +169,211 @@ async function open(mode = 'normal') {
|
||||
});
|
||||
return { page, errors };
|
||||
}
|
||||
|
||||
async function nextFrame(page) {
|
||||
await page.evaluate(
|
||||
() =>
|
||||
new Promise((resolve) => {
|
||||
const engine = window.__godsEyeView.engine;
|
||||
const remove = engine.frames.postRender.addEventListener(() => {
|
||||
remove();
|
||||
resolve();
|
||||
});
|
||||
engine.render.request('gbfs-raster-qa');
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
async function settledTiles(page) {
|
||||
await page.evaluate(async () => {
|
||||
const engine = window.__godsEyeView.engine;
|
||||
const start = performance.now();
|
||||
let since = null;
|
||||
while (performance.now() - start < 90000) {
|
||||
if (engine.surface.tilesLoaded()) since ??= performance.now();
|
||||
else since = null;
|
||||
if (since !== null && performance.now() - since > 1500) return;
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
}
|
||||
throw new Error('Map tiles did not settle for raster sampling');
|
||||
});
|
||||
}
|
||||
|
||||
async function w2Checks(page) {
|
||||
await page.evaluate(async () => {
|
||||
const app = window.__godsEyeView;
|
||||
const detection = await import('/src/data/detection.js');
|
||||
detection.setMode('OFF');
|
||||
const { appClock } = await import('/src/time/clock.js');
|
||||
appClock.freeze(Date.parse('2026-10-28T19:00:00Z'));
|
||||
const canvas = app.engine.host.canvas;
|
||||
const style = document.createElement('style');
|
||||
style.textContent =
|
||||
'.gbfs-raster-hidden { visibility: hidden !important; }';
|
||||
document.head.append(style);
|
||||
for (const element of document.body.querySelectorAll('*'))
|
||||
if (element !== canvas && !element.contains(canvas))
|
||||
element.classList.add('gbfs-raster-hidden');
|
||||
});
|
||||
for (const [name, height] of [
|
||||
['city', 10000],
|
||||
['close', 3000],
|
||||
['global', 100000],
|
||||
]) {
|
||||
await page.evaluate(async (height) => {
|
||||
const app = window.__godsEyeView;
|
||||
await app.dataManager.setEnabled('bikeshare', false);
|
||||
const geo = await import('/src/geo/index.js');
|
||||
app.engine.camera.setView({
|
||||
destination: geo.cartesian3.fromDegrees(-97.7449, 30.2701, height),
|
||||
orientation: { heading: 0, pitch: -Math.PI / 2, roll: 0 },
|
||||
});
|
||||
}, height);
|
||||
await settledTiles(page);
|
||||
await nextFrame(page);
|
||||
const off = await page.screenshot({
|
||||
path: path.join(shots, `${name}-off.png`),
|
||||
});
|
||||
await page.evaluate(() =>
|
||||
window.__godsEyeView.dataManager.setEnabled('bikeshare', true),
|
||||
);
|
||||
await page.waitForFunction(
|
||||
(count) =>
|
||||
window.__godsEyeView.dataManager.layers
|
||||
.get('bikeshare')
|
||||
.module.getStats().count === count,
|
||||
{},
|
||||
name === 'global' ? 0 : 5,
|
||||
);
|
||||
await nextFrame(page);
|
||||
const controls = await page.evaluate(() => {
|
||||
const app = window.__godsEyeView;
|
||||
const rect = app.engine.host.canvas.getBoundingClientRect();
|
||||
return app.dataManager.layers
|
||||
.get('bikeshare')
|
||||
.module.getDetectableObjects()
|
||||
.map((record) => {
|
||||
const p = app.engine.projector.worldToWindow(record.position);
|
||||
return { id: record.sourceId, x: p.x + rect.left, y: p.y + rect.top };
|
||||
});
|
||||
});
|
||||
const on = await page.screenshot({
|
||||
path: path.join(shots, `${name}-on.png`),
|
||||
});
|
||||
const a = await sharp(off)
|
||||
.ensureAlpha()
|
||||
.raw()
|
||||
.toBuffer({ resolveWithObject: true });
|
||||
const b = await sharp(on).ensureAlpha().raw().toBuffer();
|
||||
for (const control of controls) {
|
||||
let pixels = 0;
|
||||
for (
|
||||
let y = Math.max(0, Math.floor(control.y) - 16);
|
||||
y < Math.min(a.info.height, control.y + 16);
|
||||
y++
|
||||
)
|
||||
for (
|
||||
let x = Math.max(0, Math.floor(control.x) - 16);
|
||||
x < Math.min(a.info.width, control.x + 16);
|
||||
x++
|
||||
) {
|
||||
const i = (y * a.info.width + x) * 4;
|
||||
if (
|
||||
Math.max(
|
||||
...[0, 1, 2].map((c) => Math.abs(a.data[i + c] - b[i + c])),
|
||||
) > 3
|
||||
)
|
||||
pixels++;
|
||||
}
|
||||
control.changedPixels = pixels;
|
||||
}
|
||||
report.poses[name] = controls;
|
||||
check(
|
||||
`${name} expected station population`,
|
||||
controls.length,
|
||||
name === 'global' ? 0 : 5,
|
||||
);
|
||||
if (controls.length)
|
||||
check(
|
||||
`${name} five nonempty marker raster controls`,
|
||||
controls.every((c) => c.changedPixels > 0),
|
||||
true,
|
||||
);
|
||||
}
|
||||
await page.evaluate(() => {
|
||||
for (const element of document.querySelectorAll('.gbfs-raster-hidden'))
|
||||
element.classList.remove('gbfs-raster-hidden');
|
||||
});
|
||||
await page.evaluate(async () => {
|
||||
const app = window.__godsEyeView;
|
||||
const geo = await import('/src/geo/index.js');
|
||||
app.engine.camera.setView({
|
||||
destination: geo.cartesian3.fromDegrees(-97.7449, 30.2701, 3000),
|
||||
orientation: { heading: 0, pitch: -Math.PI / 2, roll: 0 },
|
||||
});
|
||||
await app.dataManager.setEnabled('bikeshare', false);
|
||||
});
|
||||
for (let i = 0; i < 10; i++) {
|
||||
await page.evaluate(() =>
|
||||
window.__godsEyeView.dataManager.setEnabled('bikeshare', true),
|
||||
);
|
||||
await page.waitForFunction(
|
||||
() =>
|
||||
window.__godsEyeView.dataManager.layers
|
||||
.get('bikeshare')
|
||||
.module.getStats().count === 5,
|
||||
);
|
||||
await page.evaluate(() =>
|
||||
window.__godsEyeView.dataManager.setEnabled('bikeshare', false),
|
||||
);
|
||||
}
|
||||
check(
|
||||
'ten cycles clear all records',
|
||||
await page.evaluate(
|
||||
() =>
|
||||
window.__godsEyeView.dataManager.layers
|
||||
.get('bikeshare')
|
||||
.module.getStats().count,
|
||||
),
|
||||
0,
|
||||
);
|
||||
const idle = await page.evaluate(async () => {
|
||||
const app = window.__godsEyeView;
|
||||
let frames = 0,
|
||||
last = performance.now();
|
||||
const remove = app.engine.frames.postRender.addEventListener(() => {
|
||||
frames++;
|
||||
last = performance.now();
|
||||
});
|
||||
const start = performance.now();
|
||||
while (
|
||||
performance.now() - start < 60000 &&
|
||||
(performance.now() - last < 2000 || !app.engine.surface.tilesLoaded())
|
||||
)
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
const ready =
|
||||
performance.now() - last >= 2000 && app.engine.surface.tilesLoaded();
|
||||
frames = 0;
|
||||
await new Promise((resolve) => setTimeout(resolve, 2000));
|
||||
remove();
|
||||
return { ready, frames, governor: app.getRenderGovernorDiagnostics() };
|
||||
});
|
||||
report.idle = idle;
|
||||
check('camera and tiles settle before idle sample', idle.ready, true);
|
||||
check(
|
||||
'disabled static scene renders zero frames over two seconds',
|
||||
idle.frames,
|
||||
0,
|
||||
);
|
||||
await page.evaluate(() =>
|
||||
window.__godsEyeView.dataManager.setEnabled('bikeshare', true),
|
||||
);
|
||||
await page.waitForFunction(
|
||||
() =>
|
||||
window.__godsEyeView.dataManager.layers.get('bikeshare').module.getStats()
|
||||
.count === 5,
|
||||
);
|
||||
}
|
||||
try {
|
||||
const { page, errors } = await open();
|
||||
await page.waitForFunction(
|
||||
@@ -158,6 +382,17 @@ try {
|
||||
.count === 5,
|
||||
{ timeout: 15000 },
|
||||
);
|
||||
await page.evaluate(async () => {
|
||||
const { engine } = window.__godsEyeView;
|
||||
const rendered = new Promise((resolve) => {
|
||||
const remove = engine.frames.postRender.addEventListener(() => {
|
||||
remove();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
window.__godsEyeView.requestRender('gbfs-name-pick-qa');
|
||||
await rendered;
|
||||
});
|
||||
const records = await page.evaluate(() =>
|
||||
window.__godsEyeView.dataManager.layers
|
||||
.get('bikeshare')
|
||||
@@ -198,17 +433,39 @@ try {
|
||||
),
|
||||
true,
|
||||
);
|
||||
if (extended) await w2Checks(page);
|
||||
const clickPoint = await page.evaluate(() => {
|
||||
window.__qaPainted = [];
|
||||
const { viewer } = window.__godsEyeView;
|
||||
const Cartesian3 = viewer.camera.position.constructor;
|
||||
const point = viewer.scene.cartesianToCanvasCoordinates(
|
||||
Cartesian3.fromDegrees(-97.7469, 30.2681),
|
||||
);
|
||||
const rect = viewer.scene.canvas.getBoundingClientRect();
|
||||
return { x: rect.left + point.x, y: rect.top + point.y };
|
||||
const { engine } = window.__godsEyeView;
|
||||
const station = window.__godsEyeView.dataManager.layers
|
||||
.get('bikeshare')
|
||||
.module.getDetectableObjects()
|
||||
.find(({ sourceId }) => sourceId === 'austin-capmetro:english');
|
||||
const point = engine.projector.worldToWindow(station.position);
|
||||
const rect = engine.host.canvas.getBoundingClientRect();
|
||||
const picked = engine.picker.pick(point);
|
||||
return {
|
||||
x: rect.left + point.x,
|
||||
y: rect.top + point.y,
|
||||
pickedId: typeof picked?.id === 'string' ? picked.id : null,
|
||||
primitiveId:
|
||||
typeof picked?.primitive?.id === 'string' ? picked.primitive.id : null,
|
||||
};
|
||||
});
|
||||
check(
|
||||
'the scene pick resolves the first stable station key',
|
||||
clickPoint.pickedId || clickPoint.primitiveId,
|
||||
'austin-capmetro:english',
|
||||
);
|
||||
await page.mouse.click(clickPoint.x, clickPoint.y);
|
||||
await page.waitForFunction(
|
||||
() =>
|
||||
window.__godsEyeView.dataManager.layers
|
||||
.get('bikeshare')
|
||||
.module.getDetectableObjects()
|
||||
.some((record) => record.skipLabel),
|
||||
{ timeout: 10000 },
|
||||
);
|
||||
await page.waitForFunction(
|
||||
() => window.__qaPainted.includes('QA English Square'),
|
||||
{ timeout: 10000 },
|
||||
@@ -263,15 +520,15 @@ try {
|
||||
);
|
||||
}
|
||||
await page.setViewport({ width: 390, height: 844 });
|
||||
await page.evaluate(() => {
|
||||
await page.evaluate(async () => {
|
||||
window.__qaPainted = [];
|
||||
const app = window.__godsEyeView;
|
||||
// Use the supported clean view to inspect the mobile card clear of panels.
|
||||
app.styleManager.toggleCleanView(true);
|
||||
const Cartesian3 = app.viewer.camera.position.constructor;
|
||||
app.viewer.camera.cancelFlight();
|
||||
app.viewer.camera.setView({
|
||||
destination: Cartesian3.fromDegrees(-97.7449, 30.2701, 3000),
|
||||
const geo = await import('/src/geo/index.js');
|
||||
app.engine.camera.cancelFlight();
|
||||
app.engine.camera.setView({
|
||||
destination: geo.cartesian3.fromDegrees(-97.7449, 30.2701, 3000),
|
||||
orientation: { heading: 0, pitch: -Math.PI / 2, roll: 0 },
|
||||
});
|
||||
app.dataManager.layers
|
||||
@@ -330,7 +587,20 @@ try {
|
||||
check(`${mode} produces no page exceptions`, errors, []);
|
||||
await page.close();
|
||||
}
|
||||
if (extended)
|
||||
check(
|
||||
'all pages have no unexpected runtime errors',
|
||||
report.browserErrors,
|
||||
[],
|
||||
);
|
||||
report.pass = true;
|
||||
console.log(`GBFS names: ${checks}/${checks} checks passed; ${appUrl}`);
|
||||
} catch (error) {
|
||||
report.pass = false;
|
||||
report.failure = redact(error.message);
|
||||
throw error;
|
||||
} finally {
|
||||
if (reportPath)
|
||||
fs.writeFileSync(reportPath, JSON.stringify(report, null, 2) + '\n');
|
||||
await browser.close();
|
||||
}
|
||||
Reference in new issue
Block a user