From f3af98e211c620f691582a9da474d754af878adb Mon Sep 17 00:00:00 2001 From: Ib Green <7025232+ibgreen@users.noreply.github.com> Date: Fri, 31 Jul 2026 09:25:23 -0400 Subject: [PATCH 1/2] test(mvt): stabilize polygon comparison --- modules/mvt/test/mvt-loader.spec.ts | 50 +++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/modules/mvt/test/mvt-loader.spec.ts b/modules/mvt/test/mvt-loader.spec.ts index 009adaad9d..fdf3a9b524 100644 --- a/modules/mvt/test/mvt-loader.spec.ts +++ b/modules/mvt/test/mvt-loader.spec.ts @@ -209,16 +209,25 @@ test('MVTLoader#Parse Polygons MVT', async t => { }; const geometry = await parse(mvtArrayBuffer, MVTLoader, loaderOptions); - let expected = binary - ? decodedPolygonsGeoJSON - : {shape: 'geojson-table', type: 'FeatureCollection', features: decodedPolygonsGeoJSON}; if (binary) { - // @ts-ignore - expected = geojsonToBinary(expected, {fixRingWinding: false}); + const expected = geojsonToBinary(structuredClone(decodedPolygonsGeoJSON), { + fixRingWinding: false + }); t.ok(geometry.byteLength > 0); delete geometry.byteLength; + t.deepEqual(geometry, expected, `Parsed Polygons MVT as ${outputFormat}`); + } else { + const expected = { + shape: 'geojson-table', + type: 'FeatureCollection', + features: normalizeGeoJsonFeatures(decodedPolygonsGeoJSON) + }; + const normalizedGeometry = { + ...geometry, + features: normalizeGeoJsonFeatures(geometry.features) + }; + t.deepEqual(normalizedGeometry, expected, `Parsed Polygons MVT as ${outputFormat}`); } - t.deepEqual(geometry, expected, `Parsed Polygons MVT as ${outputFormat}`); } t.end(); }); @@ -368,3 +377,32 @@ test('Triangulation is supported', async t => { t.end(); }); + +/** + * Copies GeoJSON features while normalizing projected coordinate precision for stable comparisons. + * + * @param features GeoJSON features to normalize. + * @returns Feature copies with rounded geometry coordinates. + */ +function normalizeGeoJsonFeatures(features: any[]): any[] { + return features.map(feature => ({ + ...feature, + geometry: { + ...feature.geometry, + coordinates: roundCoordinates(feature.geometry.coordinates) + } + })); +} + +/** + * Rounds nested coordinates to avoid browser-specific floating-point projection drift. + * + * @param coordinates Nested GeoJSON coordinate values. + * @returns Coordinates rounded to stable sub-millimeter precision. + */ +function roundCoordinates(coordinates: any): any { + if (Array.isArray(coordinates)) { + return coordinates.map(value => roundCoordinates(value)); + } + return typeof coordinates === 'number' ? Number(coordinates.toFixed(9)) : coordinates; +} From 05e90cc84f5abe65789c798243075179dc87974a Mon Sep 17 00:00:00 2001 From: Ib Green <7025232+ibgreen@users.noreply.github.com> Date: Fri, 31 Jul 2026 09:36:34 -0400 Subject: [PATCH 2/2] test: stabilize headless browser CI --- .../devtools-extensions/get-playwright-launch-options.mjs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dev-modules/devtools-extensions/get-playwright-launch-options.mjs b/dev-modules/devtools-extensions/get-playwright-launch-options.mjs index 79204197e9..8e39a5f788 100644 --- a/dev-modules/devtools-extensions/get-playwright-launch-options.mjs +++ b/dev-modules/devtools-extensions/get-playwright-launch-options.mjs @@ -1,5 +1,9 @@ const DEFAULT_PLAYWRIGHT_CHANNEL = 'chromium'; -const DEFAULT_PLAYWRIGHT_ARGS = ['--enable-unsafe-webgpu', '--ignore-gpu-blocklist']; +const DEFAULT_PLAYWRIGHT_ARGS = [ + '--disable-dev-shm-usage', + '--enable-unsafe-webgpu', + '--ignore-gpu-blocklist' +]; const SOFTWARE_GPU_ARGS = ['--use-angle=swiftshader', '--enable-unsafe-swiftshader']; export function getPlaywrightLaunchOptions(options = {}) {