Skip to content

test(runner): flip the grid's colour scheme the way the theme reads it (DEV-2546) - #219

Merged
demtario merged 1 commit into
masterfrom
fix/DEV-2546-row-striping-dark-switch
Aug 18, 2026
Merged

test(runner): flip the grid's colour scheme the way the theme reads it (DEV-2546)#219
demtario merged 1 commit into
masterfrom
fix/DEV-2546-row-striping-dark-switch

Conversation

@demtario

@demtario demtario commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

e2e/row-striping.spec.ts failed 4/4 on its dark half in its first ever live run (DEV-2546), with an odd/even channel delta of exactly 0. The starters are fine — the switch this suite used to reach dark is what broke.

The starters stripe correctly in dark

Measured on production, React and JavaScript, HOT 18.0.0:

how dark is applied wrapper color-scheme --ht-foreground-color odd row bg even row bg delta
OS prefers-color-scheme: dark light dark light-dark(#222222ff, #b9b9bbff) color(srgb .0478 .0478 .0519) ≈ (12, 12, 13) rgb(5, 5, 6) 7 — stripes
Style panel → Colour scheme: dark dark (generated theme) ≈ (12, 12, 13) rgb(5, 5, 6) 7 — stripes
the class swap this spec did normal "" — gone rgba(0, 0, 0, 0) rgba(0, 0, 0, 0) 0 — the reported failure

Why the class swap stopped meaning "dark"

The spec renamed the wrapper class ht-theme-mainht-theme-main-dark. That only ever worked while the starters imported handsontable/styles/ht-theme-main.min.css, the one place the dark class was ever defined. DEV-2200 (#149) dropped that import in favour of the JS theme object, and ThemeManager now injects :where(.ht-theme-main){…} plus .ht-theme-main { color-scheme: light dark } keyed to the resolved class name. Rename the class and the whole block stops applying: every --ht-* token goes empty, the color-mix() stripe is invalid at computed-value time, and the theme rules that painted the even row are gone too. Both rows end up transparent — an unthemed grid, which is not a dark one.

Green Aug 11 (#141), invalidated Aug 12 (#149), first run Aug 17.

What changed

mainTheme declares no colorScheme, so the builder defaults to auto and the grid resolves its light-dark() tokens against color-scheme: light dark — the visitor's own preference. So the spec emulates that media query instead, and asserts the shipped theme really is scheme-adaptive before doing so. The emulation is page-scoped and survives the reload, so it is reset before the Style panel half, which sets an explicit scheme of its own.

Two reasons the suite's own anti-vacuity guard certified an unthemed grid as a dark one, both now closed:

  • transparent computes to rgba(0, 0, 0, 0) — four numbers, none of them NaN — so the parser that claimed to refuse it read pure black instead. Against a white light reading that is contrast 21 and luminance 0, so expectSchemeFlipped passed on a grid with no theme at all. A zero alpha is now rejected, naming the row that carried it.
  • Nothing checked that the tokens the stripe is mixed from still exist. --ht-background-color is now read off the theme wrapper, so the message says the grid lost its theme instead of leaving a bare Received: 0 to explain.

The prefers-color-scheme value the preview itself reports is folded into the flip-failure message — diagnostics only, since a flip that never reached the cross-origin iframe already fails on the readings.

Verification

E2E_LIVE=1 E2E_BASE_URL=https://demos.handsontable.com pnpm e2e e2e/row-striping.spec.ts
4 passed (11.9s)

Both failure modes were re-run as controls, and both fail with the message they should:

  • the old class swap → Error: the grid lost its theme — --ht-background-color is unset
  • the flip removed entirely → Error: the colour scheme never changed … (the preview reports prefers-color-scheme: dark = false)

Run against production only — the spec is live-only, and a local webServer run in a worktree collides on port 4173. Nothing in CI typechecks e2e/ (no tsconfig includes it), so the type check here was an explicit tsc --strict over the file.

Scope

Spec-only. No starter source changed, so no pipeline/import.mjs, no scripts/prepare-container.mjs, no catalog resync and no deploy — unlike DEV-2197, which needed the catalog resync in c19808a.

Worth landing before or with #189, which wires this spec into every e2e-live dispatch and the weekly canary.

Found on the way, not fixed here

The shell's own dark toggle does not reach the preview grid at all: the shell writes data-hot-theme on its own document, the Tier-1 preview is a cross-origin iframe on the bundler's origin, and the grid follows the visitor's OS instead. Filed as DEV-2561.

🤖 Generated with Claude Code

…t (DEV-2546)

The dark half of `row-striping.spec.ts` failed 4/4 on its first ever live
run, with an odd/even channel delta of exactly 0. The starters are fine:
measured on production, an OS dark preference gives odd `(12, 12, 13)`
against even `(5, 5, 6)`, and the Style panel's dark scheme gives the
same. What was broken is the switch this suite used to get there.

It swapped the wrapper class `ht-theme-main` -> `ht-theme-main-dark`.
That worked only while the starters imported
`handsontable/styles/ht-theme-main.min.css`, the one place the dark class
was ever defined. DEV-2200 dropped that import in favour of the JS theme
object, and `ThemeManager` now injects `:where(.ht-theme-main){...}` plus
`.ht-theme-main { color-scheme: light dark }` keyed to the *resolved*
class name. Rename the class and the whole block stops applying: every
`--ht-*` token goes empty, the `color-mix()` stripe is invalid at
computed-value time, and the theme rules that painted the even row are
gone too. Both rows end up `transparent` -- an unthemed grid, which is
not a dark one. Green Aug 11, invalidated Aug 12, first run Aug 17.

`mainTheme` declares no `colorScheme`, so the grid resolves its
`light-dark()` tokens against `color-scheme: light dark` -- the visitor's
own preference. Emulate that instead, and assert the theme really is
scheme-adaptive before doing so. The emulation is page-scoped and
survives the reload, so it is reset before the Style panel half, which
sets an explicit scheme of its own.

Two reasons the suite's own anti-vacuity guard certified this:

  * `transparent` computes to `rgba(0, 0, 0, 0)` -- four numbers, none of
    them NaN -- so the parser that claimed to refuse it read pure black
    instead. Against a white light reading that is contrast 21 and
    luminance 0, so `expectSchemeFlipped` passed on a grid with no theme
    at all. Reject a zero alpha, and name the row that carried it.
  * Nothing checked that the tokens the stripe is mixed from still exist.
    Read `--ht-background-color` off the theme wrapper and fail there,
    so the message says the grid lost its theme rather than leaving a
    bare `Received: 0` to explain.

Verified against production: 4/4 pass. Both failure modes were re-run as
controls -- the old class swap now fails with "the grid lost its theme",
and removing the flip entirely fails with "the colour scheme never
changed", which now also reports what the preview saw.

Spec-only. No starter source changed, so no catalog resync and no
deploy -- unlike DEV-2197, which needed both.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@demtario
demtario merged commit 4e995cc into master Aug 18, 2026
3 checks passed
@demtario
demtario deleted the fix/DEV-2546-row-striping-dark-switch branch August 18, 2026 08:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant