You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Run the browser-dependent unit tests in a DOM-capable test environment
Motivation
Many unit tests — the map-engine adapters (Leaflet and deck.gl), the map-engine registry, and the panel manager — do not actually run. Every one of these specs errors while loading, before a single assertion executes, so the suite reports them as failures and they provide zero protection today even though the tests are written and look comprehensive (well over 200 cases).
This was invisible for a long time because the test job failed earlier, during dependency install, and never reached the tests at all. Now that install is fixed, the test step runs and surfaces this second, pre-existing layer of breakage. The same specs fail on a developer's machine and in CI, so npm test is red for everyone and a green-looking suite would be misleading.
The root cause is environmental, not a product bug: these specs exercise code that expects a browser (a window, a document, browser element types), but the unit suite runs in a plain Node process with no browser environment. CI compounds it by running on an older Node than the project officially supports.
How it should work
Running the unit suite — locally and in CI — executes all unit specs to completion, with no load/import errors.
The browser-dependent specs (map-engine adapters including deck.gl, the engine registry, and the panel manager) execute. The adapters and registry — written against current behavior — pass; the panel-manager specs (and one validator case) surface as real failures once they run, and fixing those stale assertions is tracked separately in Fix the stale unit tests revealed by the jsdom test-environment migration #149.
CI runs the unit suite on the Node version the project officially supports.
A developer can run the unit suite and the browser-dependent tests are actually enforced, not silently skipped. The suite is intentionally red until Fix the stale unit tests revealed by the jsdom test-environment migration #149 lands the stale-test fixes; once both land, a green result honestly means the covered code works.
The end-to-end suite is unaffected and continues to run as before.
Done when
The unit suite runs every unit spec without import/load errors, both locally and in CI.
No DOM at import. These specs import browser-coupled modules (the Leaflet/ deck.gl adapters; PanelManager_ → TimeControl) that read window / screen / HTMLAnchorElement at module-load time. The repo's existing "shim window in beforeEach" pattern is too late — the failure happens during import.
Node can't require() ESM. Those modules transitively require() ESM-only packages (@mapbox/tiny-sdf via deck.gl, d3-time-format via TimeControl). CI runs Node 18 (.github/workflows/playwright-tests.yml, node-version: "18"), which throws ERR_REQUIRE_ESM — even though AGENTS.md states the project requires Node 20+.
The split (verified by running locally on Node 22 vs CI on Node 18): deckGLHelpers fails only on the ESM-require issue — it passes once Node is 20+. The other eight need a DOM regardless of Node version.
Where the change lands & rough plan
Move the unit specs to a DOM-capable runner instead of trying to bolt a DOM onto Playwright's runner. Vitest with environment: 'jsdom' is verified to work on a throwaway probe: deckGLAdapter's 28 tests all pass under it (no live WebGL is needed — the adapter tests drive _viewState and the layer registry), and panelManager.layout clears the window/ESM blockers under jsdom.
Rough steps:
Add vitest + jsdom as dev dependencies.
Add a vitest.config with test.environment = 'jsdom' covering tests/unit.
Swap the unit specs' test import from @playwright/test to vitest (the test/expect APIs are compatible, so only the import line changes).
Add a small Vitest setup file to stub the few remaining browser globals — the probe showed panelManager still needs one (a Tooltip-providing library referenced at import); identify and stub those.
Keep Playwright for tests/e2e; point the CI "unit" step at Vitest.
Bump the CI workflow Node from 18 → 20.
⚠️ Gotcha: do not try to give Playwright's own runner a DOM via NODE_OPTIONS=--require <jsdom-setup>. It triggers ERR_METHOD_NOT_IMPLEMENTED: resolveSync — Playwright's ESM loader conflicts with require()-ing ESM under a preload. A separate runner (Vitest) is the path; patching Playwright is a dead end.
⚠️ Gotcha: the specs import .ts source files directly, so the runner must transpile TypeScript on the fly. Vitest does this natively; a plain Jest setup would need extra config.
References
.github/workflows/playwright-tests.yml — node-version: "18", npx playwright test tests/unit
Run the browser-dependent unit tests in a DOM-capable test environment
Motivation
Many unit tests — the map-engine adapters (Leaflet and deck.gl), the map-engine registry, and the panel manager — do not actually run. Every one of these specs errors while loading, before a single assertion executes, so the suite reports them as failures and they provide zero protection today even though the tests are written and look comprehensive (well over 200 cases).
This was invisible for a long time because the test job failed earlier, during dependency install, and never reached the tests at all. Now that install is fixed, the test step runs and surfaces this second, pre-existing layer of breakage. The same specs fail on a developer's machine and in CI, so
npm testis red for everyone and a green-looking suite would be misleading.The root cause is environmental, not a product bug: these specs exercise code that expects a browser (a
window, a document, browser element types), but the unit suite runs in a plain Node process with no browser environment. CI compounds it by running on an older Node than the project officially supports.How it should work
Done when
Out of scope
Draft implementation plan — written as of 42b9e0a on 2026-06-16. Rough guide; re-verify against latest code.
Current behavior
Unit specs run through Playwright's test runner (
playwright test tests/unit) in a Node worker with no DOM. Nine specs fail at import:tests/unit/LeafletAdapter.spec.jstests/unit/deckGLAdapter.spec.jstests/unit/deckGLHelpers.spec.jstests/unit/mapEngineRegistry.spec.jstests/unit/panelManager/panelManager.{layout,queries,registration,stateManagement,toolManagement}.spec.jsTwo stacked causes:
PanelManager_→TimeControl) that readwindow/screen/HTMLAnchorElementat module-load time. The repo's existing "shimwindowinbeforeEach" pattern is too late — the failure happens duringimport.require()ESM. Those modules transitivelyrequire()ESM-only packages (@mapbox/tiny-sdfvia deck.gl,d3-time-formatviaTimeControl). CI runs Node 18 (.github/workflows/playwright-tests.yml,node-version: "18"), which throwsERR_REQUIRE_ESM— even though AGENTS.md states the project requires Node 20+.The split (verified by running locally on Node 22 vs CI on Node 18):
deckGLHelpersfails only on the ESM-require issue — it passes once Node is 20+. The other eight need a DOM regardless of Node version.Where the change lands & rough plan
Move the unit specs to a DOM-capable runner instead of trying to bolt a DOM onto Playwright's runner. Vitest with
environment: 'jsdom'is verified to work on a throwaway probe:deckGLAdapter's 28 tests all pass under it (no live WebGL is needed — the adapter tests drive_viewStateand the layer registry), andpanelManager.layoutclears thewindow/ESM blockers under jsdom.Rough steps:
vitest+jsdomas dev dependencies.vitest.configwithtest.environment = 'jsdom'coveringtests/unit.@playwright/testtovitest(thetest/expectAPIs are compatible, so only the import line changes).panelManagerstill needs one (aTooltip-providing library referenced at import); identify and stub those.tests/e2e; point the CI "unit" step at Vitest.References
.github/workflows/playwright-tests.yml—node-version: "18",npx playwright test tests/unitplaywright.config.js— current unit+e2e configtests/unit/panelManager/testHelpers.js— existing (too-late)windowshim patternsrc/essence/Basics/Layers_/LayerConstructors.js—let L = window.Lat module load (one of the import-timewindowtriggers)