chore(deps): adopt react-native-testing-library 14 - #192
Merged
Conversation
v14 drops React 18 and adopts React 19's async rendering: render, renderHook,
fireEvent, act, rerender and unmount all return promises now, and the renderer
only ever produces host elements.
- run the upstream `rntl-v14-async-functions` codemod, then await what it does
not follow: helpers defined inside test files, calls whose result is
discarded, and `view.rerender(...)` on a result object. None of those leave a
type error behind — a dropped promise simply lets the test run on
- replace the removed UNSAFE_* queries. Most become an accessible query; where
the assertion is about a prop the user cannot see, src/test-utils/host.ts
looks the element up by host name (a FlatList is RCTScrollView, an Svg is
RNSVGSvgView)
- rewrite `expect(() => render(...)).toThrow()` as `rejects.toThrow`: an async
render rejects, it does not throw, and the codemod left invalid syntax here
- hold the token and storage reads pending in the two tests that assert a
transient pre-resolution state, which awaiting a render now flushes past
- advance fake timers around the OAuth retry backoff, which otherwise waits on
a timer nothing advances and hung the suite for 15s
- test getPrimaryFabIcon as the pure element factory it is, rather than
rendering it to look for composite types
- drop the two cameras column-count tests: numColumns never reaches a host
element, and getCameraGridColumns already covers the mapping directly
AppButton only wrapped a lone string child, so an interpolated label
("Select all ({count})") reached a View as bare text — a runtime error on
device that v14's always-on text validation surfaced.
simonvanlierde
force-pushed
the
chore/deps-rntl-14
branch
from
September 7, 2026 06:04
fdccddc to
f998628
Compare
This was referenced Sep 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Completes #189, on top of the jest 30 that landed in #191.
RNTL v14 drops React 18 for React 19's async rendering.
render,renderHook,fireEvent,act,rerenderandunmountnow return promises, and the renderer produces only host elements.What changes outside tests
One component, plus the dependency bump itself (
@testing-library/react-native14.0.1, andtest-rendereras its new peer).AppButtonwrapped only a lone string child. An interpolated label such asSelect all ({onlineCount})arrives as an array, so bare strings reached aView. React Native throws on that at runtime. v14 validates text placement unconditionally, which is how it surfaced.Migration
The upstream
rntl-v14-async-functionscodemod did most of it. Three shapes it does not follow needed sweeping by hand. None of them leaves a type error behind, because a dropped promise just lets the test run on:renderPlayer(), where the result is discardedconst result = render(...), where the result is used only atreturnview.rerender(...), a method call on a result objectThe codemod also put
awaitinside a non-async arrow forexpect(() => render(...)).toThrow(). An async render rejects rather than throws, so those becamerejects.toThrow. I ran both against a wrong expected message to confirm they still fail.The removed
UNSAFE_*queries mostly became accessible queries. Where an assertion covers a prop no user can see,app/src/test-utils/host.tsfinds the element by host name: aFlatListisRCTScrollView, anSvgisRNSVGSvgView.createNodeMockturned out unnecessary, because v14 host refs are non-null.Coverage
Test count drops from 1818 to 1816. Both are the cameras column tests.
numColumnsnever reaches a host element, andgetCameraGridColumnsalready covers the mapping.Two tests assert a null value before an async read resolves, which an awaited render now flushes past. Their token and storage reads are now held pending, so
useAuthedMediaSourceanduseProductsWelcomeCardstill guard what their comments claim.getPrimaryFabIconis now tested as the pure element factory it is.Notes for reviewers
The login suite used to hang for 15 seconds. Its OAuth retry sleeps on
setTimeout, fake timers are on globally, and the awaited press waited for a timer nothing advanced. The leaked act scope then failed the 12 tests after it. That file now runs in 1.3 seconds.Verified locally:
just check,just pre-commit, andjust test(backend 1812, www 11, docs 161, app 1816). I also pointed the host helper at a bogus host name to confirm it discriminates.