This document describes the integration testing infrastructure used to test React Router applications across different configurations, platforms, and runtime modes. The framework is built on Playwright and provides utilities for creating test fixtures, running dev servers, executing builds, and asserting behavior across SSR, SPA, prerendering, and RSC modes.
For unit testing patterns, see related documentation. For CI/CD pipeline configuration, see 8.1.
Sources: integration/helpers/vite.ts1-621 integration/helpers/create-fixture.ts1-552 integration/playwright.config.ts1-62
The integration testing framework consists of two primary approaches: a legacy fixture system and a modern Vite-based test utility system. Both enable full end-to-end testing of React Router applications.
Sources: integration/helpers/vite.ts1-50 integration/helpers/create-fixture.ts1-100 integration/playwright.config.ts15-35
The test framework uses Playwright for browser automation with a multi-browser matrix configuration.
Key configuration details:
| Setting | Value | Purpose |
|---|---|---|
testDir | "." | Root integration directory |
testMatch | **/*-test.ts | All test files |
timeout | 30s (60s Windows) | Per-test timeout |
workers | Math.floor(cpus/2) min 2 | Parallel execution |
retries | 3 in CI, 0 locally | Flake mitigation |
forbidOnly | true in CI | Prevent .only in CI |
Sources: integration/playwright.config.ts1-62
The legacy fixture system provides in-memory request handling for testing without spawning servers. This approach is being deprecated in favor of the Vite-based system.
The createFixture function builds a test project and returns methods for making requests:
Key methods returned:
requestDocument(href, init?) - Makes HTTP request, returns full ResponserequestResource(href, init?) - Fetches static assetsrequestSingleFetchData(href, init?) - Fetches and decodes .data responsespostDocument(href, data) - Submits forms via POSTgetBrowserAsset(asset) - Reads built client assetsSources: integration/helpers/create-fixture.ts87-273 integration/helpers/create-fixture.ts435-551
The createAppFixture function starts an actual HTTP server for full integration testing:
| Server Mode | Implementation | Use Case |
|---|---|---|
useReactRouterServe | Spawns @react-router/serve CLI | Production build testing |
| SPA mode | Express static server | Client-only testing |
| Prerender mode | Express with fallback routing | Static site testing |
| RSC Framework | Custom server script | RSC integration testing |
| Default | Express + createExpressHandler | Standard SSR testing |
Sources: integration/helpers/create-fixture.ts282-431
The modern approach uses template-based project creation and real CLI commands for more realistic testing.
Templates are pre-configured projects in the integration/ directory with working package.json and dependencies:
| Template | Vite Version | Special Features |
|---|---|---|
vite-5-template | Vite 5 | Baseline configuration |
vite-6-template | Vite 6 | Environment API testing |
vite-7-beta-template | Vite 7 Beta | Cutting-edge Vite |
vite-rolldown-template | Rolldown | Alternative bundler |
rsc-vite-framework | Vite 6 | React Server Components |
cloudflare-dev-proxy-template | Vite 6 | Cloudflare Workers |
Sources: integration/helpers/vite.ts230-269
Creates a test project by copying a template and writing custom files:
The function:
rr-${Math.random().toString(32).slice(2)}.tmp/integration/{projectName}stripIndentSources: integration/helpers/vite.ts271-293
Each runner spawns processes and waits for server readiness:
The waitForServer function uses the wait-on library to poll for HTTP availability with configurable timeout.
Sources: integration/helpers/vite.ts303-416 integration/helpers/vite.ts557-591
Extended fixtures provide automatic lifecycle management:
Benefits:
Sources: integration/helpers/vite.ts428-537
The framework provides helper functions for generating common configuration files:
Generates react-router.config.ts content:
Produces a configuration string using JSON.stringify (cannot support function configs).
Sources: integration/helpers/vite.ts26-44
Provides modular Vite configuration builders:
Usage example:
Sources: integration/helpers/vite.ts72-145
Generates Express server code for custom server testing:
Produces different implementations for RSC vs standard mode:
createRequestListener from @mjackson/node-fetch-servercreateRequestHandler from @react-router/expressSources: integration/helpers/vite.ts147-228
Sources: integration/vite-dev-test.ts277-311
The reactRouterServe fixture automatically runs build() before starting the server.
Sources: integration/helpers/vite.ts496-508
Sources: integration/vite-dev-test.ts296-310
Tests often iterate over multiple templates to ensure cross-version compatibility:
Sources: integration/vite-dev-test.ts17-34
The createEditor function provides a way to edit and revert files during tests:
Sources: integration/helpers/vite.ts593-606
The grep function searches for patterns in build output:
Sources: integration/helpers/vite.ts608-620
The extended page fixture automatically tracks JavaScript errors:
Sources: integration/helpers/vite.ts469-473
The legacy createFixture and createAppFixture approach is being deprecated in favor of the Vite-based utilities. The legacy system has issues:
New tests should use the test fixture from integration/helpers/vite.ts.
Refresh this wiki