## Four distinct causes
| # | Cause | Files | Fixed |
|---|---|---|---:|
| 1 | **Portal** — `container` is empty; modal renders via
`createPortal` | `TaskDetailModal` | 6 |
| 2 | **Renamed testid** — `wf-add-step-modal` no longer exists |
`WorkflowNodeEditor` | 3 |
| 3 | **Unresolvable CSS** — jsdom can't resolve `currentColor` |
`SecretsView` | 4 |
| 4 | **jsdom 29 initial values** — `auto` vs `""` |
`TaskCard.badge-wrap` | 1 |
**1. Portal (6).** Same cause and fix as #2735 — 13 queries moved to
`document`. The symptom pointed away from it: assertions failed with
*"received value must be an HTMLElement / Received has value: null"* on
the **element**, while `screen.getByTestId` in the same test kept
working, because `screen` queries `document`.
**2. Renamed testid (3).** `wf-add-step-modal` exists nowhere in app
source — verified by grep, not inferred. The add-step dialog is a
`FloatingWindow` now (`WorkflowAddStepModal.tsx:145`,
`windowKey="workflow-add-step"`), so the stable id is
`floating-window-workflow-add-step`. It still scopes the
`within(dialog)` queries, so those keep their precision.
**3. Unresolvable CSS (4).** `SecretsView` compared
`getComputedStyle(svg).stroke` against the button's background.
`SecretsView.css:227` sets `stroke: currentColor`, which jsdom does not
resolve — every icon returned `rgba(0, 0, 0, 0)`, **equal to** the
transparent button background. The comparison was two unresolved values
matching each other, not a visibility check.
`currentColor` *is* the element's `color`, which jsdom does compute, so
it now asserts the same invariant through a property that resolves.
**Load-bearing, measured:** adding `color: rgba(0,0,0,0)` to the icon
rule fails exactly those 4.
**4. jsdom 29 initial values (1).** `.card-menu-btn` declares no
`min-height`, and `auto` is the CSS **initial** value — jsdom 29 reports
it where 27 returned `""`. The intent ("nothing constrains the button's
height") is what `auto` states; `""` was pinning a jsdom-27 quirk.
| Check | Result |
|---|---|
| `TaskDetailModal` / `WorkflowNodeEditor` / `SecretsView` /
`badge-wrap` | **51 / 179 / 14 / 20 passed** |
| `pnpm lint`, dashboard app `tsc` | clean |
## Flagged, not forced — and it's the interesting one
`TaskCard.test.tsx`'s 2 remaining failures. *"FN-4511 keeps GitHub badge
and timer chip geometry in parity"* reads border widths through
`githubStyles.borderTopWidth || "1px"`.
**Under jsdom 27 both sides returned `""` and both defaulted to `"1px"`
— so the parity assertion passed while comparing nothing.** jsdom 29
resolves them and they differ:
- the chip's `border: var(--btn-border-width) solid transparent`
(`TaskCard.css:1082`) reports `medium`, because jsdom cannot resolve
`var()` inside a shorthand;
- `.card-github-badge` — which has **no rule in TaskCard.css**, only the
class in `TaskCard.tsx` — reports `1px` from elsewhere.
So jsdom cannot adjudicate this parity at all, and whether the two
genuinely differ *visually* is a question for the e2e screenshot suite.
Restoring a `|| fallback` would rebuild a vacuous guard; changing the
CSS to satisfy a test limitation would alter the product to fit its
harness. Left for someone who can answer it in a real browser.
Worth noting the general shape: the jsdom 27 → 29 bump did not "break"
these tests so much as **stop hiding** what two of them were failing to
check.
## Branch arithmetic
This branch is off `main`, so `components-b` still shows 52 failures
here: **50 are `inline-editing`, fixed by #2735** on its own branch,
plus the 2 flagged above. Once both land, the group is at 2.
Across #2735, #2740 and this PR, dashboard goes from **88 failures / 9
files** to **3** — the 2 above plus the GitHub-tracking affordance
question flagged in #2735. Per #2732 these lanes are still never
executed in CI, since the shard aborts on the first failing package.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Tests**
* Updated dashboard component tests to account for portal-based modal
rendering, ensuring queries target the global document.
* Refined jsdom assertions for icon visibility/styling and card header
control sizing to match real intended behavior.
* Adjusted workflow editor tests for the new add-step dialog, using
updated stable identifiers and updated interaction/close checks.
* Added clarifying comments to document jsdom-specific limitations and
expected outcomes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->