mirror of
https://github.com/callstack/react-native-testing-library.git
synced 2026-09-18 23:09:04 +08:00
1 line
94 KiB
JavaScript
1 line
94 KiB
JavaScript
"use strict";(self.rspackChunkwebsite=self.rspackChunkwebsite||[]).push([["543"],{898(e,s,n){n.r(s),n.d(s,{default:()=>c});var r=n(4848),i=n(8453),o=n(7425),l=n(4424);function a(e){let s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",li:"li",p:"p",pre:"pre",span:"span",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(s.h1,{id:"migration-to-14x",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#migration-to-14x",children:"#"}),"Migration to 14.x"]}),"\n",(0,r.jsx)(s.p,{children:"This guide describes the migration to React Native Testing Library version 14 from version 13.x."}),"\n",(0,r.jsxs)(s.h2,{id:"overview",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#overview",children:"#"}),"Overview"]}),"\n",(0,r.jsx)(s.p,{children:"RNTL v14 drops support for React 18 and adopts React 19's async rendering model. Here's what changed:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"React 19.0.0+ and React Native 0.78+ are now required"}),"\n",(0,r.jsxs)(s.li,{children:["Node.js ",(0,r.jsx)(s.code,{children:"^22.13.0 || >=24"})," is now required"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"render"}),", ",(0,r.jsx)(s.code,{children:"renderHook"}),", ",(0,r.jsx)(s.code,{children:"fireEvent"}),", and ",(0,r.jsx)(s.code,{children:"act"})," are now async"]}),"\n",(0,r.jsxs)(s.li,{children:["Switched from deprecated ",(0,r.jsx)(s.a,{href:"https://reactjs.org/docs/test-renderer.html",rel:"noopener noreferrer",target:"_blank",children:"React Test Renderer"})," to ",(0,r.jsx)(s.a,{href:"https://github.com/mdjastrzebski/test-renderer",rel:"noopener noreferrer",target:"_blank",children:"Test Renderer"})]}),"\n",(0,r.jsxs)(s.li,{children:["Removed deprecated APIs: ",(0,r.jsx)(s.code,{children:"update"}),", ",(0,r.jsx)(s.code,{children:"getQueriesForElement"}),", ",(0,r.jsx)(s.code,{children:"UNSAFE_root"}),", ",(0,r.jsx)(s.code,{children:"concurrentRoot"})," option, ",(0,r.jsx)(s.code,{children:"createNodeMock"})," option"]}),"\n",(0,r.jsxs)(s.li,{children:["Reintroduced ",(0,r.jsx)(s.code,{children:"container"})," API, which is now safe to use"]}),"\n"]}),"\n",(0,r.jsx)(o.Pq,{type:"info",title:"React 18 Users",children:(0,r.jsx)(s.p,{children:"If you need to support React 18, please continue using RNTL v13.x."})}),"\n",(0,r.jsxs)(s.h2,{id:"quick-migration",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#quick-migration",children:"#"}),"Quick Migration"]}),"\n",(0,r.jsx)(s.p,{children:"We provide codemods to automate most of the migration:"}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"Step 1: Update dependencies"})}),"\n",(0,r.jsx)(l.ky,{command:{npm:"npx codemod@latest rntl-v14-update-deps --target .\nnpm install",yarn:"yarn dlx codemod@latest rntl-v14-update-deps --target .\nyarn install",pnpm:"pnpm dlx codemod@latest rntl-v14-update-deps --target .\npnpm install",bun:"bunx codemod@latest rntl-v14-update-deps --target .\nbun install"}}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"Step 2: Update test code to async"})}),"\n",(0,r.jsx)(l.ky,{command:{npm:"npx codemod@latest rntl-v14-async-functions --target ./src",yarn:"yarn dlx codemod@latest rntl-v14-async-functions --target ./src",pnpm:"pnpm dlx codemod@latest rntl-v14-async-functions --target ./src",bun:"bunx codemod@latest rntl-v14-async-functions --target ./src"}}),"\n",(0,r.jsx)(s.p,{children:"After running the codemods, review the changes and run your tests."}),"\n",(0,r.jsxs)(s.p,{children:["If your project uses coding agents, add the RNTL package-docs instruction snippet from the ",(0,r.jsx)(s.a,{href:"/docs/start/quick-start.html#agent-docs-in-the-package",children:"Quick Start"})," so agents read the docs that match your installed package version."]}),"\n",(0,r.jsxs)(s.h2,{id:"breaking-changes",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#breaking-changes",children:"#"}),"Breaking Changes"]}),"\n",(0,r.jsxs)(s.h3,{id:"supported-react-react-native-and-nodejs-versions",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#supported-react-react-native-and-nodejs-versions",children:"#"}),"Supported React, React Native, and Node.js versions"]}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsxs)(s.strong,{children:["This version requires React 19+, React Native 0.78+, and Node.js ",(0,r.jsx)(s.code,{children:"^22.13.0 || >=24"}),"."]})," If you need to support React 18, please use the latest v13.x version."]}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"RNTL Version"}),(0,r.jsx)(s.th,{children:"React Version"}),(0,r.jsx)(s.th,{children:"React Native Version"}),(0,r.jsx)(s.th,{children:"Node.js Version"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"v14.x"}),(0,r.jsx)(s.td,{children:">= 19.0.0"}),(0,r.jsx)(s.td,{children:">= 0.78"}),(0,r.jsx)(s.td,{children:"^22.13.0 || >=24"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"v13.x"}),(0,r.jsx)(s.td,{children:">= 18.0.0"}),(0,r.jsx)(s.td,{children:">= 0.71"}),(0,r.jsx)(s.td,{children:">= 18"})]})]})]}),"\n",(0,r.jsxs)(s.h3,{id:"test-renderer-replaces-react-test-renderer",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#test-renderer-replaces-react-test-renderer",children:"#"}),"Test Renderer replaces React Test Renderer"]}),"\n",(0,r.jsxs)(s.p,{children:["In v14, React Native Testing Library uses ",(0,r.jsx)(s.a,{href:"https://github.com/mdjastrzebski/test-renderer",rel:"noopener noreferrer",target:"_blank",children:"Test Renderer"})," instead of the deprecated ",(0,r.jsx)(s.a,{href:"https://reactjs.org/docs/test-renderer.html",rel:"noopener noreferrer",target:"_blank",children:"React Test Renderer"}),". Test Renderer works with React 19 and has better TypeScript support."]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"What changed:"})}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"The underlying renderer is now Test Renderer instead of React Test Renderer"}),"\n",(0,r.jsx)(s.li,{children:"This is mostly an internal change; your tests should work without modifications in most cases"}),"\n",(0,r.jsxs)(s.li,{children:["Type definitions now use ",(0,r.jsx)(s.a,{href:"https://github.com/mdjastrzebski/test-renderer#test-instance",rel:"noopener noreferrer",target:"_blank",children:(0,r.jsx)(s.code,{children:"TestInstance"})})," from Test Renderer instead of ",(0,r.jsx)(s.code,{children:"ReactTestInstance"})]}),"\n",(0,r.jsx)(s.li,{children:"Test Renderer 1.x is required as a peer dependency. Use the recommended Test Renderer version for your React 19 minor version."}),"\n"]}),"\n",(0,r.jsxs)(s.h4,{id:"recommended-test-renderer-versions",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#recommended-test-renderer-versions",children:"#"}),"Recommended Test Renderer versions"]}),"\n",(0,r.jsx)(s.p,{children:"Choose the Test Renderer version that matches your React 19 minor version:"}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"React version"}),(0,r.jsx)(s.th,{children:"Recommended Test Renderer version"}),(0,r.jsx)(s.th,{children:"Notable React features"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"19.2"})}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"test-renderer@1.2"})}),(0,r.jsxs)(s.td,{children:[(0,r.jsx)(s.code,{children:"<Activity />"}),", ",(0,r.jsx)(s.code,{children:"useEffectEvent"})]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"19.1"})}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"test-renderer@1.1"})}),(0,r.jsxs)(s.td,{children:["Owner Stack support, updated ",(0,r.jsx)(s.code,{children:"useId()"})," format"]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"19.0"})}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"test-renderer@1.0"})}),(0,r.jsxs)(s.td,{children:["Actions, ",(0,r.jsx)(s.code,{children:"useActionState"}),", ",(0,r.jsx)(s.code,{children:"useOptimistic"}),", ",(0,r.jsx)(s.code,{children:"use"})]})]})]})]}),"\n",(0,r.jsxs)(s.p,{children:["Using an older Test Renderer line can prevent RNTL from supporting newer React 19 features in your tests. Using a newer Test Renderer line than your React version can produce peer dependency warnings, or an install error with ",(0,r.jsx)(s.code,{children:"npm"}),"."]}),"\n",(0,r.jsxs)(s.p,{children:["See the ",(0,r.jsx)(s.a,{href:"https://github.com/mdjastrzebski/test-renderer#react-19-compatibility-lines",rel:"noopener noreferrer",target:"_blank",children:"Test Renderer React 19 compatibility lines"})," for the latest recommendations."]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"Migration:"})}),"\n",(0,r.jsxs)(s.h4,{id:"1-update-dependencies",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#1-update-dependencies",children:"#"}),"1. Update dependencies"]}),"\n",(0,r.jsx)(s.p,{children:"Run codemod for updating dependencies:"}),"\n",(0,r.jsx)(l.ky,{command:{npm:"npx codemod@latest rntl-v14-update-deps\nnpm install",yarn:"yarn dlx codemod@latest rntl-v14-update-deps\nyarn install",pnpm:"pnpm dlx codemod@latest rntl-v14-update-deps\npnpm install",bun:"bunx codemod@latest rntl-v14-update-deps\nbun install"}}),"\n",(0,r.jsxs)(s.h5,{id:"manual-changes",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#manual-changes",children:"#"}),"Manual changes"]}),"\n",(0,r.jsx)(s.p,{children:"Remove React Test Renderer and its type definitions from your dev dependencies, and add the Test Renderer line that matches your React minor version:"}),"\n",(0,r.jsx)(l.ky,{command:{npm:"npm uninstall react-test-renderer @types/react-test-renderer\nnpm install -D test-renderer@1.2",yarn:"yarn remove react-test-renderer @types/react-test-renderer\nyarn add -D test-renderer@1.2",pnpm:"pnpm remove react-test-renderer @types/react-test-renderer\npnpm add -D test-renderer@1.2",bun:"bun remove react-test-renderer @types/react-test-renderer\nbun add -D test-renderer@1.2"}}),"\n",(0,r.jsxs)(s.p,{children:["The commands above use ",(0,r.jsx)(s.code,{children:"test-renderer@1.2"})," for React 19.2. Use ",(0,r.jsx)(s.code,{children:"test-renderer@1.1"})," for React 19.1, or ",(0,r.jsx)(s.code,{children:"test-renderer@1.0"})," for React 19.0."]}),"\n",(0,r.jsxs)(s.h4,{id:"2-update-type-imports-if-needed",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#2-update-type-imports-if-needed",children:"#"}),"2. Update type imports (if needed)"]}),"\n",(0,r.jsx)(s.p,{children:"If you were directly importing types from React Test Renderer, you may need to update your imports:"}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"ts",children:(0,r.jsxs)(s.code,{children:[(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// Before (v13)"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"import"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" type"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" { ReactTestInstance } "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"from"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:" 'react-test-renderer'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:";"})]}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// After (v14)"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"import"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" type"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" { TestInstance } "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"from"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:" 'test-renderer'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:";"})]})]})})}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"Note:"})," Most users won't need to update type imports, as React Native Testing Library now exports the necessary types directly."]}),"\n",(0,r.jsxs)(s.p,{children:["See the ",(0,r.jsx)(s.a,{href:"https://github.com/mdjastrzebski/test-renderer",rel:"noopener noreferrer",target:"_blank",children:"Test Renderer documentation"})," for more."]}),"\n",(0,r.jsxs)(s.h3,{id:"async-apis-by-default",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#async-apis-by-default",children:"#"}),"Async APIs by Default"]}),"\n",(0,r.jsx)(s.p,{children:"With React 18 support dropped, RNTL v14 uses React 19's async rendering model. The following functions are now async by default:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"render()"})," → returns ",(0,r.jsx)(s.code,{children:"Promise<RenderResult>"})]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"rerender()"})," and ",(0,r.jsx)(s.code,{children:"unmount()"})," → return ",(0,r.jsx)(s.code,{children:"Promise<void>"})]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"renderHook()"})," → returns ",(0,r.jsx)(s.code,{children:"Promise<RenderHookResult>"})]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"fireEvent()"})," and helpers (",(0,r.jsx)(s.code,{children:"press"}),", ",(0,r.jsx)(s.code,{children:"changeText"}),", ",(0,r.jsx)(s.code,{children:"scroll"}),") → return ",(0,r.jsx)(s.code,{children:"Promise<void>"})]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"act()"})," → always returns ",(0,r.jsx)(s.code,{children:"Promise<T>"})]}),"\n"]}),"\n",(0,r.jsx)(o.Pq,{type:"tip",title:"Already using async APIs?",children:(0,r.jsxs)(s.p,{children:["If you adopted the async APIs introduced in RNTL v13.3 (",(0,r.jsx)(s.code,{children:"renderAsync"}),", ",(0,r.jsx)(s.code,{children:"fireEventAsync"}),", ",(0,r.jsx)(s.code,{children:"renderHookAsync"}),"), rename them to their non-async counterparts (",(0,r.jsx)(s.code,{children:"render"}),", ",(0,r.jsx)(s.code,{children:"fireEvent"}),", ",(0,r.jsx)(s.code,{children:"renderHook"}),"). The async versions have been removed since the standard APIs are now async by default."]})}),"\n",(0,r.jsxs)(s.h4,{id:"render-async-default",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#render-async-default",children:"#"}),(0,r.jsx)(s.code,{children:"render"})," is now async"]}),"\n",(0,r.jsxs)(s.p,{children:["In v14, ",(0,r.jsx)(s.code,{children:"render"})," is async by default and returns a Promise. This allows proper support for ",(0,r.jsx)(s.code,{children:"Suspense"})," boundaries and the ",(0,r.jsx)(s.code,{children:"use()"})," hook."]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"Before (v13):"})}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"ts",children:(0,r.jsxs)(s.code,{children:[(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"import"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" { render"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" screen } "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"from"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:" '@testing-library/react-native'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:";"})]}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"it"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'should render component'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" () "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"=>"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" {"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" render"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(<"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"MyComponent"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" />);"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" expect"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"screen"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:".getByText"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'Hello'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"))"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:".toBeOnTheScreen"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"();"})]}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"});"})})]})})}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"After (v14):"})}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"ts",children:(0,r.jsxs)(s.code,{children:[(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"import"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" { render"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" screen } "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"from"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:" '@testing-library/react-native'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:";"})]}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"it"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'should render component'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" async"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" () "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"=>"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" {"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" await"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" render"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(<"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"MyComponent"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" />);"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" expect"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"screen"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:".getByText"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'Hello'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"))"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:".toBeOnTheScreen"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"();"})]}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"});"})})]})})}),"\n",(0,r.jsxs)(s.p,{children:["See the ",(0,r.jsxs)(s.a,{href:"/docs/api/render.html",children:[(0,r.jsx)(s.code,{children:"render"})," API documentation"]}),"."]}),"\n",(0,r.jsxs)(s.h4,{id:"renderhook-is-now-async",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#renderhook-is-now-async",children:"#"}),(0,r.jsx)(s.code,{children:"renderHook"})," is now async"]}),"\n",(0,r.jsxs)(s.p,{children:["In v14, ",(0,r.jsx)(s.code,{children:"renderHook"})," is async by default and returns a Promise."]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"Before (v13):"})}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"ts",children:(0,r.jsxs)(s.code,{children:[(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"import"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" { renderHook } "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"from"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:" '@testing-library/react-native'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:";"})]}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"it"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'should test hook'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" () "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"=>"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" {"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" const"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" { "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"result"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" rerender"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" } "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" renderHook"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(() "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"=>"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" useMyHook"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"());"})]}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" rerender"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(newProps);"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" unmount"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"();"})]}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"});"})})]})})}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"After (v14):"})}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"ts",children:(0,r.jsxs)(s.code,{children:[(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"import"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" { renderHook } "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"from"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:" '@testing-library/react-native'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:";"})]}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"it"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'should test hook'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" async"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" () "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"=>"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" {"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" const"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" { "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"result"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" rerender"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" } "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" await"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" renderHook"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(() "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"=>"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" useMyHook"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"());"})]}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" await"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" rerender"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(newProps);"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" await"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" unmount"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"();"})]}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"});"})})]})})}),"\n",(0,r.jsxs)(s.p,{children:["See the ",(0,r.jsxs)(s.a,{href:"/docs/api/misc/render-hook.html",children:[(0,r.jsx)(s.code,{children:"renderHook"})," API documentation"]}),"."]}),"\n",(0,r.jsxs)(s.h4,{id:"fireevent-is-now-async",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#fireevent-is-now-async",children:"#"}),(0,r.jsx)(s.code,{children:"fireEvent"})," is now async"]}),"\n",(0,r.jsxs)(s.p,{children:["In v14, ",(0,r.jsx)(s.code,{children:"fireEvent"})," and its helpers (",(0,r.jsx)(s.code,{children:"press"}),", ",(0,r.jsx)(s.code,{children:"changeText"}),", ",(0,r.jsx)(s.code,{children:"scroll"}),") are async by default and return a Promise."]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"Before (v13):"})}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"ts",children:(0,r.jsxs)(s.code,{children:[(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"import"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" { fireEvent"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" screen } "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"from"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:" '@testing-library/react-native'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:";"})]}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"it"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'should press button'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" () "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"=>"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" {"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" render"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(<"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"MyComponent"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" />);"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" fireEvent"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:".press"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"screen"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:".getByText"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'Press me'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"));"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" expect"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(onPress)"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:".toHaveBeenCalled"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"();"})]}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"});"})})]})})}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"After (v14):"})}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"ts",children:(0,r.jsxs)(s.code,{children:[(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"import"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" { fireEvent"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" screen } "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"from"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:" '@testing-library/react-native'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:";"})]}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"it"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'should press button'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" async"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" () "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"=>"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" {"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" await"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" render"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(<"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"MyComponent"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" />);"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" await"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" fireEvent"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:".press"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"screen"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:".getByText"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'Press me'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"));"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" expect"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(onPress)"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:".toHaveBeenCalled"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"();"})]}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"});"})})]})})}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.code,{children:"fireEvent.press()"})," and ",(0,r.jsx)(s.code,{children:"fireEvent.scroll()"})," now create default synthetic native event objects. If you pass event props, they are deep-merged into the default event object:"]}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"ts",children:(0,r.jsxs)(s.code,{children:[(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"await"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" fireEvent"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:".press"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"screen"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:".getByText"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'Press me'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:")"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" {"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" nativeEvent"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" { pageX"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" 20"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" pageY"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" 30"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" }"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"});"})}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"expect"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(onPress)"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:".toHaveBeenCalledWith"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"("})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" expect"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:".objectContaining"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"({"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" nativeEvent"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" expect"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:".objectContaining"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"({ pageX"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" 20"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" pageY"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" 30"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" })"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" })"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:");"})})]})})}),"\n",(0,r.jsxs)(s.p,{children:["If your v13 assertions expected the handler to receive exactly the object you passed to ",(0,r.jsx)(s.code,{children:"fireEvent.press()"})," or ",(0,r.jsx)(s.code,{children:"fireEvent.scroll()"}),", update them to use partial matching."]}),"\n",(0,r.jsxs)(s.h4,{id:"act-is-now-async",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#act-is-now-async",children:"#"}),(0,r.jsx)(s.code,{children:"act"})," is now async"]}),"\n",(0,r.jsxs)(s.p,{children:["In v14, ",(0,r.jsx)(s.code,{children:"act"})," is async by default and always returns a Promise. You should always ",(0,r.jsx)(s.code,{children:"await"})," the result of ",(0,r.jsx)(s.code,{children:"act()"}),"."]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"What changed:"})}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"act"})," now always returns ",(0,r.jsx)(s.code,{children:"Promise<T>"})," instead of ",(0,r.jsx)(s.code,{children:"T | Thenable<T>"})]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"act"})," should always be awaited"]}),"\n"]}),"\n",(0,r.jsx)(o.Pq,{type:"note",title:"Note",children:(0,r.jsxs)(s.p,{children:["The transition to async ",(0,r.jsx)(s.code,{children:"act"})," may prevent testing very short transient states, as awaiting ",(0,r.jsx)(s.code,{children:"act"})," will flush all pending updates before returning."]})}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"Before (v13):"})}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"ts",children:(0,r.jsxs)(s.code,{children:[(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"import"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" { act } "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"from"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:" '@testing-library/react-native'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:";"})]}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"it"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'should update state'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" () "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"=>"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" {"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" act"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(() "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"=>"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" {"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" setState"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'new value'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:");"})]}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" });"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" expect"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(state)"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:".toBe"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'new value'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:");"})]}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"});"})})]})})}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"After (v14):"})}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"ts",children:(0,r.jsxs)(s.code,{children:[(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"import"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" { act } "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"from"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:" '@testing-library/react-native'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:";"})]}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"it"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'should update state'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" async"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" () "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"=>"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" {"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" await"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" act"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(() "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"=>"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" {"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" setState"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'new value'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:");"})]}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" });"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" expect"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(state)"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:".toBe"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'new value'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:");"})]}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"});"})})]})})}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"Note"}),": Even if your callback is synchronous, you should still use ",(0,r.jsx)(s.code,{children:"await act(...)"})," as ",(0,r.jsx)(s.code,{children:"act"})," now always returns a Promise."]}),"\n",(0,r.jsxs)(s.p,{children:["See the ",(0,r.jsxs)(s.a,{href:"/docs/api/misc/other.html#act",children:[(0,r.jsx)(s.code,{children:"act"})," API documentation"]}),"."]}),"\n",(0,r.jsxs)(s.h4,{id:"why-async-apis",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#why-async-apis",children:"#"}),"Why async APIs?"]}),"\n",(0,r.jsxs)(s.p,{children:["The async APIs properly handle ",(0,r.jsx)(s.code,{children:"Suspense"})," boundaries and the ",(0,r.jsx)(s.code,{children:"use()"})," hook, and ensure all pending React updates complete before assertions run. This matches React 19's async rendering model."]}),"\n",(0,r.jsxs)(s.h3,{id:"removed-apis",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#removed-apis",children:"#"}),"Removed APIs"]}),"\n",(0,r.jsxs)(s.h4,{id:"update-alias-removed",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#update-alias-removed",children:"#"}),(0,r.jsx)(s.code,{children:"update"})," alias removed"]}),"\n",(0,r.jsxs)(s.p,{children:["The ",(0,r.jsx)(s.code,{children:"update"})," alias for ",(0,r.jsx)(s.code,{children:"rerender"})," has been removed. Use ",(0,r.jsx)(s.code,{children:"rerender"})," instead:"]}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"ts",children:(0,r.jsxs)(s.code,{children:[(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// Before (v13)"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"screen"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:".update"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(<"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"MyComponent"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" />);"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"const"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" { "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"update"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" } "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" render"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(<"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"MyComponent"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" />);"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"update"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(<"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"MyComponent"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" newProp"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" />);"})]}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// After (v14)"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"await"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" screen"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:".rerender"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(<"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"MyComponent"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" />);"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"const"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" { "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"rerender"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" } "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" await"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" render"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(<"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"MyComponent"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" />);"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"await"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" rerender"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(<"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"MyComponent"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" newProp"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" />);"})]})]})})}),"\n",(0,r.jsxs)(s.h4,{id:"getqueriesforelement-export-removed",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#getqueriesforelement-export-removed",children:"#"}),(0,r.jsx)(s.code,{children:"getQueriesForElement"})," export removed"]}),"\n",(0,r.jsxs)(s.p,{children:["The ",(0,r.jsx)(s.code,{children:"getQueriesForElement"})," export alias for ",(0,r.jsx)(s.code,{children:"within"})," has been removed. Use ",(0,r.jsx)(s.code,{children:"within"})," instead:"]}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"ts",children:(0,r.jsxs)(s.code,{children:[(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// Before (v13)"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"import"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" { getQueriesForElement } "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"from"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:" '@testing-library/react-native'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:";"})]}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"const"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" queries"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" ="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" getQueriesForElement"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(element);"})]}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// After (v14)"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"import"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" { within } "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"from"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:" '@testing-library/react-native'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:";"})]}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"const"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" queries"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" ="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" within"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(element);"})]})]})})}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"Note:"})," ",(0,r.jsx)(s.code,{children:"getQueriesForElement"})," was just an alias for ",(0,r.jsx)(s.code,{children:"within"}),", so the functionality is identical - only the import needs to change."]}),"\n",(0,r.jsxs)(s.h4,{id:"unsafe_root-removed",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#unsafe_root-removed",children:"#"}),(0,r.jsx)(s.code,{children:"UNSAFE_root"})," removed"]}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.code,{children:"UNSAFE_root"})," has been removed. Use ",(0,r.jsx)(s.code,{children:"container"})," to access the pseudo-element container, or ",(0,r.jsx)(s.code,{children:"root"})," to access the first rendered host element:"]}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"ts",children:(0,r.jsxs)(s.code,{children:[(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// Before (v13)"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"const"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" unsafeRoot"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" ="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" screen"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:".UNSAFE_root;"})]}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// After (v14)"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"const"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" container"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" ="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" screen"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:".container; "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// pseudo-element container"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"const"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" root"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" ="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" screen"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:".root; "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// first rendered host element"})]})]})})}),"\n",(0,r.jsxs)(s.h4,{id:"legacy-unsafe_-queries-removed",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#legacy-unsafe_-queries-removed",children:"#"}),"Legacy ",(0,r.jsx)(s.code,{children:"UNSAFE_*"})," queries removed"]}),"\n",(0,r.jsxs)(s.p,{children:["The legacy ",(0,r.jsx)(s.code,{children:"UNSAFE_getAllByType"}),", ",(0,r.jsx)(s.code,{children:"UNSAFE_getByType"}),", ",(0,r.jsx)(s.code,{children:"UNSAFE_getAllByProps"}),", and ",(0,r.jsx)(s.code,{children:"UNSAFE_getByProps"})," queries have been removed. These queries could return composite (user-defined) components, which is no longer supported with ",(0,r.jsx)(s.a,{href:"https://github.com/mdjastrzebski/test-renderer",rel:"noopener noreferrer",target:"_blank",children:"Test Renderer"})," as it only renders host elements."]}),"\n",(0,r.jsxs)(s.p,{children:["If you were using these legacy queries, you should refactor your tests to use the standard queries (",(0,r.jsx)(s.code,{children:"getByRole"}),", ",(0,r.jsx)(s.code,{children:"getByText"}),", ",(0,r.jsx)(s.code,{children:"getByTestId"}),", etc.) which target host elements."]}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"ts",children:(0,r.jsxs)(s.code,{children:[(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// Before (v13)"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"const"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" buttons"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" ="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" screen"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:".UNSAFE_getAllByType"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(Button);"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"const"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" input"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" ="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" screen"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:".UNSAFE_getByProps"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"({ placeholder"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:" 'Enter text'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" });"})]}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// After (v14)"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"const"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" buttons"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" ="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" screen"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:".getAllByRole"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'button'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:");"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"const"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" input"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" ="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" screen"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:".getByPlaceholderText"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'Enter text'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:");"})]})]})})}),"\n",(0,r.jsxs)(s.h4,{id:"concurrentroot-option-removed",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#concurrentroot-option-removed",children:"#"}),(0,r.jsx)(s.code,{children:"concurrentRoot"})," option removed"]}),"\n",(0,r.jsxs)(s.p,{children:["The ",(0,r.jsx)(s.code,{children:"concurrentRoot"})," option has been removed from both ",(0,r.jsx)(s.code,{children:"render"})," options and ",(0,r.jsx)(s.code,{children:"configure"})," function. In v14, concurrent rendering is always enabled, since it's the standard rendering mode for React 19 and React Native's New Architecture."]}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"ts",children:(0,r.jsxs)(s.code,{children:[(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// Before (v13)"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"render"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(<"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"MyComponent"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" />"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" { concurrentRoot"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" true"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" }); "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// Enable concurrent mode"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"render"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(<"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"MyComponent"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" />"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" { concurrentRoot"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" false"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" }); "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// Disable concurrent mode"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"configure"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"({ concurrentRoot"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" false"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" }); "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// Disable globally"})]}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// After (v14)"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"await"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" render"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(<"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"MyComponent"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" />); "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// Always uses concurrent rendering"})]})]})})}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"Migration:"})," Remove any ",(0,r.jsx)(s.code,{children:"concurrentRoot"})," options from your ",(0,r.jsx)(s.code,{children:"render"})," calls and ",(0,r.jsx)(s.code,{children:"configure"})," function. If you were setting ",(0,r.jsx)(s.code,{children:"concurrentRoot: true"}),", just remove the option. If you were setting ",(0,r.jsx)(s.code,{children:"concurrentRoot: false"})," to disable concurrent rendering, this is no longer supported in v14."]}),"\n",(0,r.jsxs)(s.h4,{id:"createnodemock-option-removed",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#createnodemock-option-removed",children:"#"}),(0,r.jsx)(s.code,{children:"createNodeMock"})," option removed"]}),"\n",(0,r.jsxs)(s.p,{children:["The ",(0,r.jsx)(s.code,{children:"createNodeMock"})," render option has been removed. It was previously passed through to React Test Renderer, but the v14 Test Renderer integration does not support this option."]}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"ts",children:(0,r.jsxs)(s.code,{children:[(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// Before (v13)"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"render"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(<"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"MyComponent"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" />"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" {"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" createNodeMock"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" (element) "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"=>"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" {"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" if"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" ("}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"element"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:".type "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"==="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" TextInput) {"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" return"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" { focus"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" jest"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:".fn"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"() };"})]}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" }"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" return"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" {};"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" }"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"});"})}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// After (v14)"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"await"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" render"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(<"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"MyComponent"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" />);"})]})]})})}),"\n",(0,r.jsxs)(s.p,{children:["If you used ",(0,r.jsx)(s.code,{children:"createNodeMock"})," to mock imperative refs, prefer testing user-visible behavior and mock the component or native module at the boundary where the ref behavior is introduced."]}),"\n",(0,r.jsxs)(s.h3,{id:"container-api-reintroduced",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#container-api-reintroduced",children:"#"}),(0,r.jsx)(s.code,{children:"container"})," API reintroduced"]}),"\n",(0,r.jsxs)(s.p,{children:["In v14, the ",(0,r.jsx)(s.code,{children:"container"})," API has been reintroduced and is now safe to use. Previously, ",(0,r.jsx)(s.code,{children:"container"})," was renamed to ",(0,r.jsx)(s.code,{children:"UNSAFE_root"})," in v12 due to behavioral differences from React Testing Library's ",(0,r.jsx)(s.code,{children:"container"}),". Now ",(0,r.jsx)(s.code,{children:"container"})," returns a pseudo-element container whose children are the elements you rendered, consistent with React Testing Library's behavior."]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"What changed:"})}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"screen.container"})," is now available and safe to use"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"container"})," returns a pseudo-element container from Test Renderer"]}),"\n",(0,r.jsx)(s.li,{children:"The container's children are the elements you rendered"}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"UNSAFE_root"})," has been removed"]}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"Before (v13):"})}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"ts",children:(0,r.jsxs)(s.code,{children:[(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"import"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" { render"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" screen } "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"from"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:" '@testing-library/react-native'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:";"})]}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"it"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'should access root'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" () "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"=>"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" {"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" render"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(<"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"MyComponent"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" />);"})]}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:" // UNSAFE_root was the only way to access the container"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" const"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" root"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" ="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" screen"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:".UNSAFE_root;"})]}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"});"})})]})})}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"After (v14):"})}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"ts",children:(0,r.jsxs)(s.code,{children:[(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"import"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" { render"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" screen } "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"from"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:" '@testing-library/react-native'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:";"})]}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"it"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'should access container'"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" async"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" () "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"=>"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" {"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" await"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" render"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(<"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"MyComponent"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" />);"})]}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:" // container is now safe and available"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" const"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" container"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" ="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" screen"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:".container;"})]}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:" // root is the first child of container"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" const"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" root"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" ="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" screen"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:".root;"})]}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"});"})})]})})}),"\n",(0,r.jsxs)(s.p,{children:["See the ",(0,r.jsxs)(s.a,{href:"/docs/api/screen.html#container",children:[(0,r.jsx)(s.code,{children:"screen"})," API documentation"]}),"."]}),"\n",(0,r.jsxs)(s.h3,{id:"text-string-validation-enforced-by-default",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#text-string-validation-enforced-by-default",children:"#"}),"Text string validation enforced by default"]}),"\n",(0,r.jsxs)(s.p,{children:["In v14, Test Renderer enforces React Native's requirement that text strings must be rendered within a ",(0,r.jsx)(s.code,{children:"<Text>"})," component. The ",(0,r.jsx)(s.code,{children:"unstable_validateStringsRenderedWithinText"})," option has been removed from ",(0,r.jsx)(s.code,{children:"RenderOptions"})," since this validation is now always on."]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"What changed:"})}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"Text string validation is now always enabled and cannot be disabled"}),"\n",(0,r.jsxs)(s.li,{children:["The ",(0,r.jsx)(s.code,{children:"unstable_validateStringsRenderedWithinText"})," option has been removed"]}),"\n",(0,r.jsxs)(s.li,{children:["Tests will now throw ",(0,r.jsx)(s.code,{children:"Invariant Violation: Text strings must be rendered within a <Text> component"})," errors when attempting to render strings outside of ",(0,r.jsx)(s.code,{children:"<Text>"})," components, matching React Native's runtime behavior"]}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"Migration:"})}),"\n",(0,r.jsxs)(s.p,{children:["If you were using ",(0,r.jsx)(s.code,{children:"unstable_validateStringsRenderedWithinText: true"})," in your render options, you can simply remove this option as the validation is now always enabled:"]}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"ts",children:(0,r.jsxs)(s.code,{children:[(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// Before (v13)"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"render"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(<"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"MyComponent"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" />"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" {"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" unstable_validateStringsRenderedWithinText"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" true"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"});"})}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// After (v14)"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"await"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" render"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"(<"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"MyComponent"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" />);"})]}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// Validation is now always enabled"})})]})})}),"\n",(0,r.jsxs)(s.p,{children:["If you were relying on the previous behavior where strings could be rendered outside of ",(0,r.jsx)(s.code,{children:"<Text>"})," components, you'll need to fix your components to wrap strings in ",(0,r.jsx)(s.code,{children:"<Text>"})," components, as this matches React Native's actual runtime behavior."]}),"\n",(0,r.jsxs)(s.h3,{id:"hidden-suspense-and-activity-content",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#hidden-suspense-and-activity-content",children:"#"}),"Hidden Suspense and Activity content"]}),"\n",(0,r.jsxs)(s.p,{children:["When React keeps previously rendered content hidden, such as suspended content or React 19.2 ",(0,r.jsx)(s.code,{children:'<Activity mode="hidden">'}),", RNTL now applies React Native-like hidden props to the affected instances. In practice, hidden instances receive ",(0,r.jsx)(s.code,{children:"display: 'none'"}),", preserving existing styles by appending the hidden style."]}),"\n",(0,r.jsx)(s.p,{children:"This makes visibility queries and matchers behave closer to runtime behavior:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"default queries do not match hidden instances"}),"\n",(0,r.jsxs)(s.li,{children:["queries with ",(0,r.jsx)(s.code,{children:"{ includeHiddenElements: true }"})," can still find hidden instances"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"toBeVisible()"})," treats these instances as hidden"]}),"\n"]}),"\n",(0,r.jsxs)(s.h3,{id:"accessible-name-changes",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#accessible-name-changes",children:"#"}),"Accessible name changes"]}),"\n",(0,r.jsx)(s.p,{children:"Accessible name calculation has been updated to better match React Native behavior:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"aria-labelledby"})," and ",(0,r.jsx)(s.code,{children:"accessibilityLabelledBy"})," still take precedence over explicit labels"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"aria-label"})," and ",(0,r.jsx)(s.code,{children:"accessibilityLabel"})," take precedence over text content"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"Image"})," ",(0,r.jsx)(s.code,{children:"alt"})," is used as an accessible label"]}),"\n",(0,r.jsxs)(s.li,{children:["a root ",(0,r.jsx)(s.code,{children:"TextInput"})," can use its ",(0,r.jsx)(s.code,{children:"placeholder"})," as its accessible name"]}),"\n",(0,r.jsx)(s.li,{children:"child accessible names are concatenated with spaces"}),"\n",(0,r.jsxs)(s.li,{children:["child ",(0,r.jsx)(s.code,{children:"TextInput"})," placeholders are not used when computing a parent's accessible name"]}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:["This affects ",(0,r.jsx)(s.code,{children:"getByRole(..., { name })"})," and ",(0,r.jsx)(s.code,{children:"toHaveAccessibleName()"}),". If a v13 role query matched because descendant text or label queries were used as a fallback, update the test to match the element's computed accessible name directly or query the descendant element instead."]}),"\n",(0,r.jsxs)(s.h3,{id:"unknown-options-now-warn",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#unknown-options-now-warn",children:"#"}),"Unknown options now warn"]}),"\n",(0,r.jsxs)(s.p,{children:["RNTL now logs a warning when unknown options are passed to ",(0,r.jsx)(s.code,{children:"configure"}),", ",(0,r.jsx)(s.code,{children:"render"}),", ",(0,r.jsx)(s.code,{children:"renderHook"}),", or ",(0,r.jsx)(s.code,{children:"userEvent.setup"}),". This helps catch stale v13 options and misspellings during migration."]}),"\n",(0,r.jsxs)(s.p,{children:["For example, after removing ",(0,r.jsx)(s.code,{children:"concurrentRoot"}),", ",(0,r.jsx)(s.code,{children:"createNodeMock"}),", or ",(0,r.jsx)(s.code,{children:"unstable_validateStringsRenderedWithinText"}),", make sure those options are not still being passed through shared test helpers."]}),"\n",(0,r.jsxs)(s.h2,{id:"codemods",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#codemods",children:"#"}),"Codemods"]}),"\n",(0,r.jsx)(s.p,{children:"Two codemods are available to automate the migration. Both are safe to run multiple times - they only transform code that hasn't been migrated yet."}),"\n",(0,r.jsxs)(s.h3,{id:"rntl-v14-update-deps",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#rntl-v14-update-deps",children:"#"}),(0,r.jsx)(s.code,{children:"rntl-v14-update-deps"})]}),"\n",(0,r.jsxs)(s.p,{children:["Updates your ",(0,r.jsx)(s.code,{children:"package.json"}),":"]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Removes React Test Renderer (",(0,r.jsx)(s.code,{children:"react-test-renderer"})," and ",(0,r.jsx)(s.code,{children:"@types/react-test-renderer"}),")"]}),"\n",(0,r.jsxs)(s.li,{children:["Adds Test Renderer (",(0,r.jsx)(s.code,{children:"test-renderer"}),") using the current recommended 1.x line"]}),"\n",(0,r.jsxs)(s.li,{children:["Updates ",(0,r.jsx)(s.code,{children:"@testing-library/react-native"})," to the v14 version"]}),"\n"]}),"\n",(0,r.jsx)(l.ky,{command:{npm:"npx codemod@latest rntl-v14-update-deps --target .\nnpm install",yarn:"yarn dlx codemod@latest rntl-v14-update-deps --target .\nyarn install",pnpm:"pnpm dlx codemod@latest rntl-v14-update-deps --target .\npnpm install",bun:"bunx codemod@latest rntl-v14-update-deps --target .\nbun install"}}),"\n",(0,r.jsxs)(s.h3,{id:"rntl-v14-async-functions",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#rntl-v14-async-functions",children:"#"}),(0,r.jsx)(s.code,{children:"rntl-v14-async-functions"})]}),"\n",(0,r.jsx)(s.p,{children:"Transforms test files:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Adds ",(0,r.jsx)(s.code,{children:"await"})," to ",(0,r.jsx)(s.code,{children:"render()"}),", ",(0,r.jsx)(s.code,{children:"act()"}),", ",(0,r.jsx)(s.code,{children:"renderHook()"}),", ",(0,r.jsx)(s.code,{children:"fireEvent()"})," calls"]}),"\n",(0,r.jsx)(s.li,{children:"Makes test functions async when needed"}),"\n",(0,r.jsxs)(s.li,{children:["Handles ",(0,r.jsx)(s.code,{children:"screen.rerender()"}),", ",(0,r.jsx)(s.code,{children:"screen.unmount()"}),", and renderer methods"]}),"\n"]}),"\n",(0,r.jsx)(l.ky,{command:{npm:"npx codemod@latest rntl-v14-async-functions --target ./src",yarn:"yarn dlx codemod@latest rntl-v14-async-functions --target ./src",pnpm:"pnpm dlx codemod@latest rntl-v14-async-functions --target ./src",bun:"bunx codemod@latest rntl-v14-async-functions --target ./src"}}),"\n",(0,r.jsxs)(s.h4,{id:"custom-render-functions",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#custom-render-functions",children:"#"}),"Custom render functions"]}),"\n",(0,r.jsxs)(s.p,{children:["If you have custom render helpers (like ",(0,r.jsx)(s.code,{children:"renderWithProviders"}),"), you can specify them using the ",(0,r.jsx)(s.code,{children:"customRenderFunctions"})," parameter. The codemod will then also transform calls to these functions:"]}),"\n",(0,r.jsx)(l.ky,{command:{npm:'npx codemod@latest rntl-v14-async-functions \\\n --target ./src \\\n --param customRenderFunctions="renderWithProviders,renderWithTheme"',yarn:'yarn dlx codemod@latest rntl-v14-async-functions \\\n --target ./src \\\n --param customRenderFunctions="renderWithProviders,renderWithTheme"',pnpm:'pnpm dlx codemod@latest rntl-v14-async-functions \\\n --target ./src \\\n --param customRenderFunctions="renderWithProviders,renderWithTheme"',bun:'bunx codemod@latest rntl-v14-async-functions \\\n --target ./src \\\n --param customRenderFunctions="renderWithProviders,renderWithTheme"'}}),"\n",(0,r.jsxs)(s.p,{children:["This will add ",(0,r.jsx)(s.code,{children:"await"})," to your custom render calls and make the containing test functions async, just like it does for the standard ",(0,r.jsx)(s.code,{children:"render"})," function."]}),"\n",(0,r.jsxs)(s.h4,{id:"limitations",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#limitations",children:"#"}),"Limitations"]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"Helper functions defined in test files are not transformed by default"}),"\n",(0,r.jsxs)(s.li,{children:["Namespace imports (",(0,r.jsx)(s.code,{children:"import * as RNTL"}),") are not handled"]}),"\n"]}),"\n",(0,r.jsxs)(s.h2,{id:"full-changelog",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#full-changelog",children:"#"}),"Full Changelog"]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.a,{href:"https://github.com/callstack/react-native-testing-library/compare/v13.3.3...v14.0.0",rel:"noopener noreferrer",target:"_blank",children:"https://github.com/callstack/react-native-testing-library/compare/v13.3.3...v14.0.0"})})]})}function c(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(a,{...e})}):a(e)}c.__RSPRESS_PAGE_META={},c.__RSPRESS_PAGE_META["14.x%2Fdocs%2Fstart%2Fmigration-v14.mdx"]={toc:[{id:"overview",text:"Overview",depth:2},{id:"quick-migration",text:"Quick Migration",depth:2},{id:"breaking-changes",text:"Breaking Changes",depth:2},{id:"supported-react-react-native-and-nodejs-versions",text:"Supported React, React Native, and Node.js versions",depth:3},{id:"test-renderer-replaces-react-test-renderer",text:"Test Renderer replaces React Test Renderer",depth:3},{id:"recommended-test-renderer-versions",text:"Recommended Test Renderer versions",depth:4},{id:"1-update-dependencies",text:"1. Update dependencies",depth:4},{id:"2-update-type-imports-if-needed",text:"2. Update type imports (if needed)",depth:4},{id:"async-apis-by-default",text:"Async APIs by Default",depth:3},{id:"render-async-default",text:"`render` is now async",depth:4},{id:"renderhook-is-now-async",text:"`renderHook` is now async",depth:4},{id:"fireevent-is-now-async",text:"`fireEvent` is now async",depth:4},{id:"act-is-now-async",text:"`act` is now async",depth:4},{id:"why-async-apis",text:"Why async APIs?",depth:4},{id:"removed-apis",text:"Removed APIs",depth:3},{id:"update-alias-removed",text:"`update` alias removed",depth:4},{id:"getqueriesforelement-export-removed",text:"`getQueriesForElement` export removed",depth:4},{id:"unsafe_root-removed",text:"`UNSAFE_root` removed",depth:4},{id:"legacy-unsafe_-queries-removed",text:"Legacy `UNSAFE_*` queries removed",depth:4},{id:"concurrentroot-option-removed",text:"`concurrentRoot` option removed",depth:4},{id:"createnodemock-option-removed",text:"`createNodeMock` option removed",depth:4},{id:"container-api-reintroduced",text:"`container` API reintroduced",depth:3},{id:"text-string-validation-enforced-by-default",text:"Text string validation enforced by default",depth:3},{id:"hidden-suspense-and-activity-content",text:"Hidden Suspense and Activity content",depth:3},{id:"accessible-name-changes",text:"Accessible name changes",depth:3},{id:"unknown-options-now-warn",text:"Unknown options now warn",depth:3},{id:"codemods",text:"Codemods",depth:2},{id:"rntl-v14-update-deps",text:"`rntl-v14-update-deps`",depth:3},{id:"rntl-v14-async-functions",text:"`rntl-v14-async-functions`",depth:3},{id:"custom-render-functions",text:"Custom render functions",depth:4},{id:"limitations",text:"Limitations",depth:4},{id:"full-changelog",text:"Full Changelog",depth:2}],title:"Migration to 14.x",headingTitle:"Migration to 14.x",frontmatter:{}}}}]); |