Skip to content

fix(#310): firefox-gen was red since #297 β€” and "renders the atlas" passed on a DEAD atlas - #311

Merged
TortoiseWolfe merged 1 commit into
mainfrom
fix/310-firefox-webgl-gate
Jul 17, 2026
Merged

fix(#310): firefox-gen was red since #297 β€” and "renders the atlas" passed on a DEAD atlas#311
TortoiseWolfe merged 1 commit into
mainfrom
fix/310-firefox-webgl-gate

Conversation

@TortoiseWolfe

Copy link
Copy Markdown
Owner

Closes #310. Found by the owner spotting a red shard on main.

main has been red for four runs

firefox-gen 6/6 has failed on every main run since a8ee9b4 β€” #297's merge, when the
atlas became the default
. PR CI is chromium-only (firefox/webkit only run on push-to-main), so
#297 went in green and four more merges landed on top of a red main without anyone looking.

run sha merged firefox-gen 6/6
c6b7021 β€” βœ…
a8ee9b4 #297 β€” atlas becomes default ❌
c2cadd0 #304 ❌
77d464f #306 ❌
8910cc1 #308 ❌

The cause is the environment, not the atlas

Probed with Playwright's Firefox against the real page:

webgl: false
hudText: "Atlas β€” chatt   error: The browser supports WebGL, but initialization failed."
typeChip: false
console: "Error constructing CesiumWidget. Visit http://get.webgl.org ..."

Headless Firefox has no WebGL β†’ Cesium's Viewer ctor throws β†’ AtlasViewer catches it into its
error state β†’ everything behind {ready && …} (chips, count, legend) never renders. Real
Firefox has WebGL.
The tests were right; two of them just needed the WebGL gate this file
already uses for the R3F canvas.

The worse bug this exposed

test('/chatt/ renders the atlas by default', ...)
  await expect(page.getByText('Atlas β€”')).toBeVisible()

Atlas β€” {slug} renders unconditionally β€” the status line beside it is a ternary whose first
branch is error: ${error}. The probe shows Atlas β€” chatt sitting directly beside the error.

So the test whose whole job was proving the atlas renders was green, on Firefox, on a
completely dead atlas.
It could not fail when the product was broken. Same family as
toBeVisible() ignoring occlusion (#299) and the placeholder client_id a test asserted
toBeTruthy() on (#288).

The fix: the mount and the scene are different claims, so they're different tests

test gate proves
the atlas MODULE mounts none β€” runs everywhere the Cesium chunk loaded and the module evaluated. Deliberately weak. This is what catches a #294-class dead vendor chunk (which took prod down for five hours), on every browser, WebGL or not.
the atlas SCENE initialises without erroring WebGL the HUD contains no error: and the chips exist. Cannot pass on a dead atlas.

Verified RED for the right reason β€” skip removed, run on Firefox's genuinely dead atlas:

Expected string: not "error:"
Received string: "Atlas β€” chatt error: The browser supports WebGL, but initialization failed."

It fails on the exact atlas the old test called green.

The gate is deliberately narrow

test.skip() is #288's false-green failure mode, so only the two specs that need ready are
gated (the building count, the type chip). Everything else β€” cannot-scroll, HUD width, cookie
banner/PWA, contentinfo, the #299 wordmark β€” passes on Firefox without WebGL and stays
ungated, keeping its signal on all three browsers. Chromium has swiftshader, so every real
assertion still runs on every PR.

The building count test is not loosened: it's the one that catches "0 buildings" over a
correct 8031-building legend, which has shipped once.

Verified on a CI-identical root build

firefox-gen    13 passed,  5 skipped,  0 failed      (was: 2 failed)
chromium-gen   20 passed,  0 skipped

…sed on a DEAD atlas

main's firefox-gen 6/6 shard has failed on EVERY run since a8ee9b4 -- #297's
merge, when the atlas became the default. Four runs, unnoticed, because PR CI is
chromium-only and firefox/webkit run on push-to-main.

Root cause is the environment, not the atlas. Probed with Playwright's firefox
against the real page:

  webgl: false
  hudText: "Atlas β€” chatt   error: The browser supports WebGL, but
            initialization failed."
  typeChip: false
  console: "Error constructing CesiumWidget. Visit http://get.webgl.org ..."

Headless firefox has no WebGL, Cesium's Viewer ctor throws, AtlasViewer catches
it into its error state, and everything behind `{ready && …}` -- chips, count,
legend -- never renders. Real firefox has WebGL. The tests were RIGHT; only two
of them needed the WebGL gate this file already uses for the R3F canvas.

THE WORSE BUG THIS EXPOSED, which is why this is not just a `test.skip`:

  test('/chatt/ renders the atlas by default', ...)
    await expect(page.getByText('Atlas β€”')).toBeVisible()

`Atlas β€” {slug}` renders UNCONDITIONALLY; the status line beside it is a ternary
whose first branch is `error: ${error}`. So that test was GREEN, on firefox, on a
completely dead atlas -- the probe above shows "Atlas β€” chatt" sitting directly
beside "error: ...". The test whose whole job was proving the atlas renders could
not fail when the atlas was broken. Same family as toBeVisible() ignoring
occlusion (#299) and the placeholder client_id asserted toBeTruthy() (#288).

The mount and the scene are different claims, so they are now different tests:

  the atlas MODULE mounts (no WebGL needed)   unconditional, deliberately weak.
      Proves the Cesium chunk loaded and the module evaluated -- exactly what
      catches a #294-class dead vendor chunk, on every browser.
  the atlas SCENE initialises without erroring   gated on WebGL. Asserts the HUD
      does NOT contain 'error:' and the chips exist.

Verified RED for the right reason: with its skip removed on firefox, the SCENE
test fails with
  Expected string: not "error:"
  Received string: "Atlas β€” chatt error: The browser supports WebGL, but
                    initialization failed."
i.e. it fails on the exact atlas the old test called green.

Gate applied to only the two specs that need `ready` (the count, the type chip).
The rest -- cannot-scroll, HUD width, cookie banner/PWA, contentinfo, the #299
wordmark -- pass on firefox WITHOUT WebGL and stay ungated, so they keep their
signal on all three browsers. test.skip() is #288's false-green failure mode, so
the gate stays narrow and chromium (swiftshader) still runs every real assertion
on every PR.

Verified on a CI-identical root build:
  firefox-gen   13 passed, 5 skipped, 0 failed   (was: 2 failed)
  chromium-gen  20 passed, 0 skipped

Closes #310
@TortoiseWolfe TortoiseWolfe added the full-e2e Run the full firefox+webkit E2E matrix on this PR label Jul 17, 2026
@TortoiseWolfe TortoiseWolfe reopened this Jul 17, 2026
@TortoiseWolfe
TortoiseWolfe merged commit 220ca53 into main Jul 17, 2026
34 checks passed
@TortoiseWolfe
TortoiseWolfe deleted the fix/310-firefox-webgl-gate branch July 17, 2026 14:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

full-e2e Run the full firefox+webkit E2E matrix on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

main's E2E red since #297: firefox-gen 6/6 (no WebGL headless) β€” and 'renders the atlas' passes on a DEAD atlas

2 participants