Skip to content

feat(runner): the Style panel spec, and the two test contracts it stands on (DEV-2203) - #185

Open
danielzytohoc wants to merge 4 commits into
feat/DEV-2203-engine-and-docs-frameworksfrom
feat/DEV-2203-style-panel-e2e
Open

feat(runner): the Style panel spec, and the two test contracts it stands on (DEV-2203)#185
danielzytohoc wants to merge 4 commits into
feat/DEV-2203-engine-and-docs-frameworksfrom
feat/DEV-2203-style-panel-e2e

Conversation

@danielzytohoc

@danielzytohoc danielzytohoc commented Aug 14, 2026

Copy link
Copy Markdown

Fifth in the DEV-2203 series. Stacked on #183 (sibling of #184 — both fork from the same base).

Why

Seven defects hid in the panel → generated-module → grid seam, four silently (DEV-2199's table). style-apply.spec.ts proves a theme reaches the running grid; nothing proved everything before the grid. The first draft of this spec was discarded as flaky — CodeMirror virtualises .cm-content, so file-text assertions depend on scroll position (task comment).

What

Commit 1 — two product test contracts (documented in-source, on the data-preview-status precedent):

  • window.__HOT_FILES__() over the existing filesRef — synchronous view of the workspace files; kills the CodeMirror flake class. Doubles as a support tool.
  • aria-label on the 18 component-list buttons — the computed name concatenates the override badge ("Header 2"), and "Buttons" ⊂ "Radio Buttons".

Commit 2 — e2e/style-panel.spec.ts, 15 tests, fully deterministic (bundler aborted ⇒ runs in PR CI, and unchanged against prod). Covers the whole DEV-2203 checklist: tabs; 18 components; preset tiles naturalWidth > 0; typed controls (select options; numeric unit/min/max with clear-means-remove, never a bare "%"; size trigger shows 4px, never sizing.size_1); linked tokens write and reset as a pair (visible via the Rows badge); density sizes land under the edited variant, including one the grid is not on; apply→Reset round-trips a displaced themeName byte-identically on both v16 shapes, with the fixture precondition asserted first; theme survives reload (incl. the mount reconcile); generated module quotes every dynamic key; Copy-for-my-app carries no bridge; the manual hint on an unrecognisable grid shape; Google Fonts link injection.

State reads localStorage["hot-runner-theme"], files read __HOT_FILES__(), everything debounce-adjacent polls with toPass.

Verification

15/15 in 4.4 s locally; full suite in this tree: 360 unit + 170 e2e passed (one unrelated description-markdown toolbar flake failed in the full parallel run and passes in isolation in both this tree and master — pre-existing flake class, CI has retries).


Note

Low Risk
Changes are E2E tests plus documented dev-only hooks (__HOT_FILES__, aria-label); no auth or production API behavior changes.

Overview
Adds deterministic Playwright coverage for the Style panel (controls, localStorage theme state, and generated handsontable-theme modules) in e2e/style-panel.spec.ts — 15 tests, bundler aborted like other panel specs so they run in PR CI.

Two test contracts ship with the spec:

  • window.__HOT_FILES__() in App.tsx exposes the live workspace map via filesRef, so E2E can assert file contents without scraping virtualised CodeMirror .cm-content.
  • aria-label on each Component-tab row button in StylePanel.tsx stabilises accessible names when override badges change computed names and when labels like "Buttons" vs "Radio Buttons" collide.

The spec exercises tabs and presets, all 18 components, token control types (select, numeric clear-to-remove, resolved size display), linked header tokens, per-variant density sizes, v16 themeName apply/Reset round-trips (React + JS), reload persistence, quoted keys in codegen, Copy-for-my-app without the live bridge, manual hint on unrecognised grid wiring, and Google Fonts injection — with toPass() polling for debounced writes.

Reviewed by Cursor Bugbot for commit ae6c0cf. Bugbot is set up for automated code reviews on this repo. Configure here.

Dan Zyto added 2 commits August 14, 2026 13:45
…2203)

window.__HOT_FILES__ exposes the workspace files map, because the first
draft of the panel spec died on CodeMirror's virtualised DOM:
.cm-content only holds the lines on screen, so file-content assertions
against it pass or fail on scroll position. filesRef is updated
synchronously by every edit path including the panel's quiet writes.
Same standing as data-preview-status — rename only with the suite. It
also makes a decent support tool: __HOT_FILES__() in the console is a
user's exact workspace.

The 18 component-list buttons get aria-label={section.label}: the
computed name concatenates the override badge ('Header 2'), so a role
query breaks the moment a token is overridden, and 'Buttons' collides
with 'Radio Buttons' without an exact name to hang it on.
…ed module (DEV-2203)

The task's highest-value spec: seven defects hid in this seam, four
silently. style-apply.spec.ts proves a theme reaches the running grid;
this proves everything before the grid, deterministically (bundler
aborted), so it runs in PR CI — and unchanged against production.

Fifteen tests: the four tabs; all 18 components reachable by their new
aria-labels; preset tiles with naturalWidth > 0 (a renamed asset is
invisible in markup); typed controls per token type — select options,
numeric unit/min/max with clear-means-remove (never a bare '%'), size
triggers showing the resolved 4px, never sizing.size_1; linked header
tokens writing and resetting as a pair, visible from the Rows badge;
density sizes landing under the edited variant, not the active one;
apply-then-Reset round-tripping a displaced themeName byte-identically
on both v16 shapes (attribute and setting), asserting the fixture
precondition first so a regenerated bucket reads as fixture drift; the
theme surviving a reload through localStorage plus the mount reconcile;
quoted keys in the generated module for every dynamic-key family;
Copy-for-my-app carrying no bridge code; the manual hint on a grid
shape wireTheme refuses to touch; and the Google Fonts link injection.

State assertions read localStorage['hot-runner-theme'], file assertions
read window.__HOT_FILES__() — both behind toPass polling for the 250ms
debounce.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit f960916. Configure here.

Comment thread runner/e2e/style-panel.spec.ts
Dan Zyto added 2 commits August 17, 2026 08:33
…#185)

Until the docs fetch lands the files map is empty, and wireTheme over an
empty map shows the same hint the test treats as proof — it could pass
without ever touching the fixture. The unrecognisable expression is now
asserted as a precondition, and the refused file is asserted
byte-identical after the apply.
@danielzytohoc
danielzytohoc changed the base branch from feat/DEV-2203-editor-and-version-specs to feat/DEV-2203-engine-and-docs-frameworks August 17, 2026 06:34
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