Skip to content

fix(react/testing-library): align fireEvent with Lynx bubbling semantics#2532

Merged
upupming merged 3 commits intomainfrom
fix/testing-library-tap-bubbles
Apr 28, 2026
Merged

fix(react/testing-library): align fireEvent with Lynx bubbling semantics#2532
upupming merged 3 commits intomainfrom
fix/testing-library-tap-bubbles

Conversation

@upupming
Copy link
Copy Markdown
Collaborator

@upupming upupming commented Apr 28, 2026

Summary

  • TouchEvent-family events (tap, longtap, touchstart, touchmove, touchend, touchcancel, longpress) now default to bubbles: true, matching the Lynx runtime where every event whose handler signature is EventHandler<BaseTouchEvent<T>> in @lynx-js/types propagates through capture/bubble phases. Other entries (bgload, transitionend, mouse/key/focus/blur/layout, …) keep their non-bubbling default — Lynx has no symmetric capture-bind/capture-catch API for them.
  • Skip read-only Event.prototype accessors (bubbles, cancelable, composed) when applying EventInit via Object.assign after construction — reassigning those getters throws TypeError in strict mode. They're still applied via the EventInit dict.
  • Cover bind / catch / capture-bind / capture-catch handler semantics and the TouchEvent-family bubble defaults in events.test.jsx.

Test plan

  • pnpm vitest run src/__tests__/events.test.jsx — 41/41 pass (was previously failing in strict mode on the Object.assign(event, init) call when init carried bubbles/cancelable/composed)
  • CI green

Summary by CodeRabbit

  • Bug Fixes

    • Touch-family events in the testing library now bubble by default so ancestor handlers run unless explicitly disabled; also avoids runtime errors when certain event properties are read-only.
  • Tests

    • Added comprehensive tests validating capture vs. bubble semantics and propagation behavior for event handlers.
  • Documentation

    • Added a changeset documenting these behavioral updates.

- TouchEvent-family events (tap, longtap, touchstart, touchmove, touchend,
  touchcancel, longpress) now default to bubbles: true, matching the
  Lynx runtime where these events propagate through capture/bubble phases.
- Skip read-only Event accessors (bubbles/cancelable/composed) when
  applying EventInit via Object.assign — those are getters on
  Event.prototype and reassigning them throws TypeError in strict mode.
- Add Event handler property semantics tests covering bind/catch/
  capture-bind/capture-catch propagation and bubble defaults across the
  TouchEvent family.
@upupming upupming requested review from HuJean, Yradex and hzy as code owners April 28, 2026 10:22
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 28, 2026

🦋 Changeset detected

Latest commit: 66f0503

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@lynx-js/react Patch
@lynx-js/react-umd Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 28, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: fbd3a8f1-b703-465c-a045-610162f48fd0

📥 Commits

Reviewing files that changed from the base of the PR and between e0b9dde and 66f0503.

📒 Files selected for processing (1)
  • .changeset/fix-testing-library-tap-bubbles.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • .changeset/fix-testing-library-tap-bubbles.md

📝 Walkthrough

Walkthrough

Touch-event fireEvent helpers now default to bubbles: true; event construction omits bubbles, cancelable, and composed from init before assignment to avoid strict-mode TypeError. A patch changeset and tests validating handler-phase and propagation behavior were added.

Changes

Cohort / File(s) Summary
Changeset / Docs
\.changeset/fix-testing-library-tap-bubbles.md
Adds a patch-level changeset documenting TouchEvent bubbling default and the change to event property assignment.
Tests
packages/react/testing-library/src/__tests__/events.test.jsx
Adds tests covering Lynx handler phase semantics (bind*, catch*, capture-bind*, capture-catch*), propagation behavior, and verifies Touch-event bubbling defaults.
Implementation
packages/react/testing-library/src/fire-event.ts
Sets TouchEvent-family entries to default bubbles: true; changes event creation to exclude bubbles, cancelable, composed from direct assignment to prevent TypeError in strict mode.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • HuJean
  • Yradex
  • hzy

Poem

🐇 I tapped the world and let it go,
Bubbles rising from tip to toe.
I avoided proto's grumpy bite,
Now events travel left and right—
A tiny hop, a merry light.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: aligning fireEvent TouchEvent behavior with Lynx bubbling semantics through updates to event defaults and implementation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/testing-library-tap-bubbles

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 28, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/react/testing-library/src/__tests__/events.test.jsx (1)

314-330: Add longtap to the default-bubbling ancestor test matrix.

Line 314 currently validates touchstart/touchmove/touchend/touchcancel/longpress, but longtap also changed to default bubbles: true in fire-event.ts. Including it here would close that regression gap.

🧪 Proposed test update
-  it.each(['touchstart', 'touchmove', 'touchend', 'touchcancel', 'longpress'])(
+  it.each(['longtap', 'touchstart', 'touchmove', 'touchend', 'touchcancel', 'longpress'])(
     '%s: bubbles to ancestor handlers by default',
     (eventName) => {
       const parent = vi.fn();
       const childRef = createRef();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react/testing-library/src/__tests__/events.test.jsx` around lines
314 - 330, Update the test matrix in the it.each call so the ancestor-bubbling
test covers the 'longtap' event as well: inside the array passed to it.each
(currently ['touchstart','touchmove','touchend','touchcancel','longpress']), add
'longtap' so that the loop invokes fireEvent[eventName](childRef.current) for
'longtap' and asserts parent handler was called; this ensures the change in
fire-event.ts (default bubbles: true for longtap) is covered by the test.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/react/testing-library/src/__tests__/events.test.jsx`:
- Around line 314-330: Update the test matrix in the it.each call so the
ancestor-bubbling test covers the 'longtap' event as well: inside the array
passed to it.each (currently
['touchstart','touchmove','touchend','touchcancel','longpress']), add 'longtap'
so that the loop invokes fireEvent[eventName](childRef.current) for 'longtap'
and asserts parent handler was called; this ensures the change in fire-event.ts
(default bubbles: true for longtap) is covered by the test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e101f9b8-2193-46b8-b249-8fe0d90e315e

📥 Commits

Reviewing files that changed from the base of the PR and between e15852f and 5217110.

📒 Files selected for processing (3)
  • .changeset/fix-testing-library-tap-bubbles.md
  • packages/react/testing-library/src/__tests__/events.test.jsx
  • packages/react/testing-library/src/fire-event.ts

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Apr 28, 2026

Merging this PR will not alter performance

✅ 81 untouched benchmarks
⏩ 26 skipped benchmarks1


Comparing fix/testing-library-tap-bubbles (66f0503) with main (e15852f)

Open in CodSpeed

Footnotes

  1. 26 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@relativeci
Copy link
Copy Markdown

relativeci Bot commented Apr 28, 2026

Web Explorer

#9256 Bundle Size — 900.02KiB (0%).

66f0503(current) vs 3920afa main#9255(baseline)

Bundle metrics  Change 2 changes
                 Current
#9256
     Baseline
#9255
No change  Initial JS 44.46KiB 44.46KiB
No change  Initial CSS 2.22KiB 2.22KiB
No change  Cache Invalidation 0% 0%
No change  Chunks 9 9
No change  Assets 11 11
Change  Modules 228(-0.44%) 229
No change  Duplicate Modules 11 11
Change  Duplicate Code 27.29%(+0.04%) 27.28%
No change  Packages 10 10
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#9256
     Baseline
#9255
No change  JS 495.88KiB 495.88KiB
No change  Other 401.92KiB 401.92KiB
No change  CSS 2.22KiB 2.22KiB

Bundle analysis reportBranch fix/testing-library-tap-bubblesProject dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented Apr 28, 2026

React MTF Example

#814 Bundle Size — 196.54KiB (0%).

66f0503(current) vs e15852f main#811(baseline)

Bundle metrics  no changes
                 Current
#814
     Baseline
#811
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 3 3
No change  Modules 173 173
No change  Duplicate Modules 66 66
No change  Duplicate Code 44.08% 44.08%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#814
     Baseline
#811
No change  IMG 111.23KiB 111.23KiB
No change  Other 85.31KiB 85.31KiB

Bundle analysis reportBranch fix/testing-library-tap-bubblesProject dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented Apr 28, 2026

React Example

#7682 Bundle Size — 225.38KiB (0%).

66f0503(current) vs e15852f main#7679(baseline)

Bundle metrics  no changes
                 Current
#7682
     Baseline
#7679
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 4 4
No change  Modules 179 179
No change  Duplicate Modules 69 69
No change  Duplicate Code 44.57% 44.57%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#7682
     Baseline
#7679
No change  IMG 145.76KiB 145.76KiB
No change  Other 79.63KiB 79.63KiB

Bundle analysis reportBranch fix/testing-library-tap-bubblesProject dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented Apr 28, 2026

React External

#799 Bundle Size — 680.27KiB (0%).

66f0503(current) vs 3920afa main#798(baseline)

Bundle metrics  no changes
                 Current
#799
     Baseline
#798
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 3 3
No change  Modules 17 17
No change  Duplicate Modules 5 5
No change  Duplicate Code 8.59% 8.59%
No change  Packages 0 0
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#799
     Baseline
#798
No change  Other 680.27KiB 680.27KiB

Bundle analysis reportBranch fix/testing-library-tap-bubblesProject dashboard


Generated by RelativeCIDocumentationReport issue

@upupming upupming merged commit e4ace87 into main Apr 28, 2026
106 of 111 checks passed
@upupming upupming deleted the fix/testing-library-tap-bubbles branch April 28, 2026 12:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants