MotirBuilding in public
MOTIR · moooon
onMotir
You’re viewing a public project. Anyone can view it — no account needed. Sign in to submit, upvote, or comment on requests.View-only — you can’t edit work items
MOTIR-1738

Evaluate the ROOT fix for the component-test effect-ordering class: IS_REACT_ACT_ENVIRONMENT = true (a ~30-file act() migration)

Done
Description

Why this exists

Carved out of MOTIR-1737, which shipped option (a) of its three-way decision — the nightly component-effect-audit lane that DETECTS the effect-ordering race — and explicitly deferred option (b), the root fix that REMOVES the class. Logged as its own card rather than left as prose in a merged PR body (the orphaned-deferral rule: a seam owned by "the later story" orphans).

The condition

vitest.config.ts never sets IS_REACT_ACT_ENVIRONMENT, and React Testing Library deliberately turns the act environment OFF for findBy* / waitFor, draining with a bare zero-delay timer. React flushes passive effects on a separate scheduler callback, so an awaited findBy* can resolve with effects still pending: the render landed, the effect did not. Any non-retrying assertion downstream of an effect is then a load-dependent flake. Three instances found so far — MOTIR-1736 (ProjectRoadmapCanvas) plus the two fixed in MOTIR-1737 (OnboardingCanvasRoadmap, TierDocModal).

Setting IS_REACT_ACT_ENVIRONMENT = true in a setup file makes RTL flush effects deterministically, which ends the class outright. It was NOT done in MOTIR-1737 because it is a migration of its own: it surfaces act() warnings across roughly 30 files, each needing its render/interaction wrapped, and bundling that into a one-file race fix would have been an unreviewable diff.

What to do

  1. Set IS_REACT_ACT_ENVIRONMENT = true in a happy-dom-scoped setup file and measure the real blast radius (how many files warn, how many fail).
  2. If the blast radius is tractable, migrate the warning files and land it; if it is not, record WHY in this card and close it — the nightly lane remains the standing control either way.
  3. Whatever the outcome, reconcile the two: with the root fix in place the audit lane becomes redundant and should be retired (.github/workflows/component-effect-audit.yml, vitest.late-effects.config.ts, tests/helpers/lateEffects.ts, the test:late-effects script, and the CLAUDE.md subsection that documents them) rather than left running as dead weight.
  4. Option (c) from MOTIR-1737 — a lint rule banning a bare expect(<mock>) in a file that also awaits findBy* — is NOT part of this card and is not planned: it is a lossy proxy for what (a) already checks exactly.

Acceptance criteria

  • The blast radius of IS_REACT_ACT_ENVIRONMENT = true is MEASURED and stated (file count, failure count), not estimated.
  • Either the migration lands with the whole happy-dom suite green, or the card records a concrete reason it was rejected.
  • If it lands, the audit lane and its three files are retired in the same PR — no orphaned instrument.
  • No production component change; this is test infrastructure only.