diff --git a/docs/react/testing.md b/docs/react/testing.md
deleted file mode 100644
index dd1f2d7d308..00000000000
--- a/docs/react/testing.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-sidebar_label: Testing
----
-
-# Testing Ionic React
-
-When an `@ionic/react` application is generated using the Ionic CLI, it is automatically set up for unit testing and integration testing with [Jest](https://jestjs.io/) and [React Testing Library](https://testing-library.com/docs/react-testing-library/intro). The combo provides a great way to test your React components in isolation as well integrated together. For more information on how to get started testing an Ionic React app, see our article [Testing Ionic React Apps with Jest and React Testing Library](https://ionicframework.com/blog/testing-ionic-react-apps-with-jest-and-react-testing-library/).
diff --git a/docs/react/testing/introduction.md b/docs/react/testing/introduction.md
new file mode 100644
index 00000000000..a8cae30a467
--- /dev/null
+++ b/docs/react/testing/introduction.md
@@ -0,0 +1,21 @@
+---
+sidebar_label: Introduction
+title: Ionic React Testing Introduction
+description: Learn how to test an Ionic React application. This document provides an overview of how to test an application built with @ionic/react.
+---
+
+# Testing Ionic React
+
+This document provides an overview of how to test an application built with `@ionic/react`. It covers the basics of testing with React, as well as the specific tools and libraries developers can use to test their applications.
+
+## Introduction
+
+Testing is an important part of the development process, and it helps to ensure that an application is working as intended. In `@ionic/react`, testing is done using a combination of tools and libraries, including Jest, React Testing Library, Playwright or Cypress.
+
+## Types of Tests
+
+There are two types of tests that can be written:
+
+**Unit Tests**: Unit tests are used to test individual functions and components in isolation. [Jest](https://jestjs.io) and [React Testing Library](https://testing-library.com) are commonly used for unit testing.
+
+**Integration Tests**: Integration tests are used to test how different components work together. [Cypress](https://www.cypress.io) or [Playwright](https://playwright.dev) are commonly used for integration testing.
diff --git a/docs/react/testing/unit-testing/best-practices.md b/docs/react/testing/unit-testing/best-practices.md
new file mode 100644
index 00000000000..ce1562d391f
--- /dev/null
+++ b/docs/react/testing/unit-testing/best-practices.md
@@ -0,0 +1,51 @@
+---
+sidebar_label: Best Practices
+---
+
+# Best Practices
+
+## IonApp is required for test templates
+
+In your test template when rendering with React Testing Library, you must wrap your component with an `IonApp` component. This is required for the component to be rendered correctly.
+
+```tsx title="Example.test.tsx"
+import { IonApp } from '@ionic/react';
+import { render } from "@testing-library/react";
+
+import Example from './Example';
+
+test('example', () => {
+ render(
+
+
+
+ );
+ ...
+});
+```
+
+## Use `user-event` for user interactions
+
+React Testing Library recommends using the `user-event` library for simulating user interactions. This library provides a more realistic simulation of user interactions than the `fireEvent` function provided by React Testing Library.
+
+```tsx title="Example.test.tsx"
+import { IonApp } from '@ionic/react';
+import { render } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+
+import Example from './Example';
+
+test('example', async () => {
+ const user = userEvent.setup();
+
+ render(
+
+
+
+ );
+
+ await user.click(screen.getByRole('button', { name: /click me!/i }));
+});
+```
+
+For more information on `user-event`, see the [user-event documentation](https://testing-library.com/docs/user-event/intro/).
diff --git a/docs/react/testing/unit-testing/examples.md b/docs/react/testing/unit-testing/examples.md
new file mode 100644
index 00000000000..39275eef669
--- /dev/null
+++ b/docs/react/testing/unit-testing/examples.md
@@ -0,0 +1,112 @@
+---
+sidebar_label: Examples
+title: Ionic React Testing Examples
+description: Learn how to test an Ionic React application. This document provides examples of how to test different types of components.
+---
+
+# Examples
+
+## Testing a modal presented from a trigger
+
+This example shows how to test a modal that is presented from a trigger. The modal is presented when the user clicks a button.
+
+### Example component
+
+```tsx title="src/Example.tsx"
+import { IonButton, IonModal } from '@ionic/react';
+
+export default function Example() {
+ return (
+ <>
+ Open
+ Modal content
+ >
+ );
+}
+```
+
+### Testing the modal
+
+```tsx title="src/Example.test.tsx"
+import { IonApp } from '@ionic/react';
+import { fireEvent, render, screen, waitFor } from '@testing-library/react';
+
+import Example from './Example';
+
+test('button presents a modal when clicked', async () => {
+ render(
+
+
+
+ );
+ // Simulate a click on the button
+ fireEvent.click(screen.getByText('Open'));
+ // Wait for the modal to be presented
+ await waitFor(() => {
+ // Assert that the modal is present
+ expect(screen.getByText('Modal content')).toBeInTheDocument();
+ });
+});
+```
+
+## Testing a modal presented from useIonModal
+
+This example shows how to test a modal that is presented using the `useIonModal` hook. The modal is presented when the user clicks a button.
+
+### Example component
+
+```tsx title="src/Example.tsx"
+import { IonContent, useIonModal, IonHeader, IonToolbar, IonTitle, IonButton, IonPage } from '@ionic/react';
+
+const ModalContent: React.FC = () => {
+ return (
+
+ Modal Content
+
+ );
+};
+
+const Example: React.FC = () => {
+ const [present] = useIonModal(ModalContent);
+ return (
+
+
+
+ Blank
+
+
+
+ present()}>
+ Open
+
+
+
+ );
+};
+
+export default Example;
+```
+
+### Testing the modal
+
+```tsx title="src/Example.test.tsx"
+import { IonApp } from '@ionic/react';
+import { fireEvent, render, screen, waitFor } from '@testing-library/react';
+
+import Example from './Example';
+
+test('should present ModalContent when button is clicked', async () => {
+ render(
+
+
+
+ );
+ // Simulate a click on the button
+ fireEvent.click(screen.getByText('Open'));
+ // Wait for the modal to be presented
+ await waitFor(() => {
+ // Assert that the modal is present
+ expect(screen.getByText('Modal Content')).toBeInTheDocument();
+ });
+});
+```
diff --git a/docs/react/testing/unit-testing/setup.md b/docs/react/testing/unit-testing/setup.md
new file mode 100644
index 00000000000..0e4cf3d1ed1
--- /dev/null
+++ b/docs/react/testing/unit-testing/setup.md
@@ -0,0 +1,40 @@
+---
+sidebar_label: Setup
+title: Ionic React Unit Testing Setup
+description: Learn how to set up unit tests for an Ionic React application.
+---
+
+# Unit Testing Setup
+
+Ionic requires a few additional steps to set up unit tests. If you are using an Ionic starter project, these steps have already been completed for you.
+
+### Install React Testing Library
+
+React Testing Library is a set of utilities that make it easier to test React components. It's used to interact with components and test their behavior.
+
+```bash
+npm install --save-dev @testing-library/react @testing-library/jest-dom @testing-library/user-event
+```
+
+### Initialize Ionic React
+
+Ionic React requires the `setupIonicReact` function to be called before any tests are run. Failing to do so will result in mode-based classes and platform behaviors not being applied to your components.
+
+In `src/setupTest.ts`, add the following code:
+
+```diff
+import '@testing-library/jest-dom/extend-expect';
+
++ import { setupIonicReact } from '@ionic/react';
+
++ setupIonicReact();
+
+// Mock matchmedia
+window.matchMedia = window.matchMedia || function () {
+ return {
+ matches: false,
+ addListener: function () { },
+ removeListener: function () { }
+ };
+};
+```
diff --git a/sidebars.js b/sidebars.js
index c08a43ada8f..832bec09c8f 100644
--- a/sidebars.js
+++ b/sidebars.js
@@ -120,7 +120,23 @@ module.exports = {
'react/pwa',
'react/overlays',
'react/storage',
- 'react/testing',
+ {
+ type: 'category',
+ label: 'Testing',
+ items: [
+ 'react/testing/introduction',
+ {
+ type: 'category',
+ label: 'Unit Testing',
+ collapsed: false,
+ items: [
+ 'react/testing/unit-testing/setup',
+ 'react/testing/unit-testing/examples',
+ 'react/testing/unit-testing/best-practices',
+ ],
+ },
+ ],
+ },
'react/performance',
],
},
diff --git a/vercel.json b/vercel.json
index 8bc50e73908..b7f986824c5 100644
--- a/vercel.json
+++ b/vercel.json
@@ -63,7 +63,8 @@
"source": "/docs/vue/your-first-app/6-deploying-mobile",
"destination": "/docs/vue/your-first-app/deploying-mobile"
},
- { "source": "/docs/vue/your-first-app/7-live-reload", "destination": "/docs/vue/your-first-app/live-reload" }
+ { "source": "/docs/vue/your-first-app/7-live-reload", "destination": "/docs/vue/your-first-app/live-reload" },
+ { "source": "/docs/react/testing", "destination": "/docs/react/testing/introduction" }
],
"rewrites": [
{ "source": "/docs", "destination": "/" },