Skip to content

test: golden-master interaction traces with a browser cross-check - #838

Merged
STRML merged 8 commits into
masterfrom
test/golden-traces
Oct 31, 2026
Merged

STRML merged 8 commits into
masterfrom
test/golden-traces

Conversation

@STRML

@STRML STRML commented Oct 31, 2026

Copy link
Copy Markdown
Collaborator

Pins every observable output of Draggable and DraggableCore before the perf and clarity work. No file under lib/ changes.

scenario ─▶ per-event act() driver (mouse, touch, hybrid) ─▶ trace
   callbacks + DraggableData, return values, rendered transform,
   classes, body user-select class, document listeners attached
                                    ▼
                     test/golden/__golden__/<scenario>.golden.json
                                    ▲
   16 scenarios ─▶ Chromium (Playwright, real input) ─▶ same trace, compared

The old tests send mousedown and mousemove in one act(), so the move lands before the drag state commits and Draggable.onDrag (bounds, slack, the user callback) never runs in jsdom. This harness dispatches one act() per event, and also pins the batched cadence, since some consumers hit it.

166 scenarios (145 per-event, 21 batched): both components, controlled and uncontrolled, defaultPosition, positionOffset, every axis, parent / selector / object bounds, grid, scale 0.5 and 2, handle and cancel, allowAnyClick, disabled, nodeRef vs findDOMNode, enableUserSelectHack, allowMobileScroll, ctrl+click, return-false from each callback, multi-touch, mouse+touch hybrids, unmount mid-drag, StrictMode. An optional project replays the findDOMNode path under React 18.

Coverage: Draggable.tsx 62.5% -> 97.2% lines, DraggableCore.tsx 83.2% -> 97.5%. Mutation check: dropping the bounds call at lib/Draggable.tsx:318 fails 10 traces.

Bugs pinned with "knownBug", not fixed: R1 stuck-dragging batch, R2 onStop false called twice, R3 touch drag never stops after onDrag false, R4 second pointer fires onStart again, R5 idle unmount clears selection mid-drag, R6/R7 uncontrolled onStop position and bounds, R9 touch breaks after the child node changes, R10 hybrid touchend gives NaN, R11.

The serializer keeps sentinels distinct from lookalike objects and keeps array holes, the same fix react-grid-layout#2320 needed. CI installs Playwright Chromium and runs yarn golden:browser with the github-actions reporter.

Status - 2026-10-31

Check (local, on 390fc86) Result
yarn test 13 files, 370 tests pass
two consecutive golden runs 0 diffs
yarn golden:browser 16 / 16 match (macOS; Linux in CI)
lint / typecheck pass

Review gate: codex-review.sh with test/golden/__golden__/** excluded as generated.

Test plan

  • CI green on this head, including the browser cross-check on Linux
  • Review gate passes on this head

STRML added 7 commits October 31, 2026 17:44
Batched drag helpers let movement arrive before React commits the start state, leaving bounds and user callbacks untested. Record each input in its own act and retain a batched cadence to pin that behavior too.

Capture ordered callbacks, DOM output and actual listener attachments, with lossless special-value encoding and an explicit golden update gate.
Refactors need an observable baseline for bounds, slack, touch identity, callback vetoes and teardown. Add 164 short interaction scenarios across both component layers and event cadences, retaining today's bugs as named metadata.

Run the traces in the normal test suite and regenerate them only through golden:update. Bypassing the bounds call at Draggable.tsx:318 causes 10 trace failures; restoring it returns the suite to green.
Synthetic DOM input cannot establish browser layout fidelity. Add a separate offline Playwright project comparing 16 shared mouse scenarios against committed jsdom traces, using local React and library source while preserving the existing Puppeteer suite.

Add two isolated React 18 goldens that exercise the real findDOMNode fallback. Both pass against a matching cached runtime. The browser fixture compiles and collects, but Chromium launch is blocked by macOS MachPort permissions, so real browser parity remains unverified.
Behavior changes need an explicit review trail before the planned refactors. Document the trace format, per-event and batched timing, known-bug convention, update commands and isolated source cross-check projects.

Record the verified React 18 path and the sandbox limitation on browser execution so compilation is not mistaken for browser parity.
Sentinels ({$type}, {$number}) are plain objects, so a trace value could change to a lookalike without changing its golden file, and array holes encoded as null. Ordinary objects with a "$" key are now wrapped in {$escaped}, and holes encode as {$hole: true}. Same fix as react-grid-layout#2320 round 1. No golden file changed; a new serializer test covers each collision.
The browser cross-check loaded Playwright from PLAYWRIGHT_MODULE_PATH only, so CI could not run it. Pin playwright@1.62.1, the version react-grid-layout and react-resizable use.
Install Playwright Chromium and run yarn golden:browser after the Puppeteer browser tests. The github-actions reporter turns each parity failure into a check annotation. Locally: 16/16 traces match real Chromium input.
@coderabbitai

coderabbitai Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Caution

Review failed

The pull request is closed.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

Review round 1 (P1): every trace recorded package.json's version and the browser check asserted 4.7.2, so the release command's version bump would break the golden suite on the release commit itself. Traces now carry only schemaVersion. Sweep: rg for package version use in test/golden found runScenario.jsx, legacy.golden.test.jsx and crosscheck.test.js; react-grid-layout and react-resizable goldens record no package version. 166 golden files lose their version line and nothing else; the two React 18 legacy goldens were edited the same way because regenerating them needs a separate React 18 install.

P2: the legacy runner required exactly React 18.3.1 although its config accepts any matching React 18; it now checks the major version. P2: the browser check left its temporary Vite cache directory behind; afterAll now removes it, also when launch fails. A run now leaves no directory behind.
@STRML
STRML merged commit 65a564f into master Oct 31, 2026
5 of 6 checks passed
@STRML
STRML deleted the test/golden-traces branch October 31, 2026 21:54
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