Skip to content

Commit ab2829b

Browse files
committed
fix prerelease
1 parent 812207d commit ab2829b

6 files changed

Lines changed: 277 additions & 87 deletions

File tree

packages/browser-react/AGENTS.md

Lines changed: 75 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,20 @@
22

33
React component testing support for Rstest browser mode. Provides `render`, `renderHook`, `cleanup`, and `act` utilities for testing React components in a real browser environment.
44

5-
## Module structure
5+
## Do
66

7-
- `src/index.ts` — Default entry with auto-cleanup via `beforeEach`
8-
- `src/pure.tsx` — Pure exports without auto-cleanup (for manual control)
9-
- `src/act.ts` — React `act()` wrapper with `IS_REACT_ACT_ENVIRONMENT` management
7+
- Support React 17, 18, and 19 — ensure code works across all versions
8+
- Use `act()` for all render/unmount/state update operations
9+
- Keep this package focused on React rendering lifecycle only
10+
- Use JSDoc comments for public API functions
11+
- Default to small, focused diffs
12+
13+
## Don't
14+
15+
- Don't add DOM query utilities (users should use `@testing-library/dom`)
16+
- Don't add dependencies beyond React peer deps
17+
- Don't break compatibility with older React versions without discussion
18+
- Don't use React version-specific APIs without fallbacks
1019

1120
## Commands
1221

@@ -15,19 +24,58 @@ React component testing support for Rstest browser mode. Provides `render`, `ren
1524
pnpm --filter @rstest/browser-react build
1625
pnpm --filter @rstest/browser-react dev # Watch mode
1726

18-
# Typecheck
19-
pnpm --filter @rstest/browser-react typecheck
27+
# Type check single file
28+
pnpm tsc --noEmit src/pure.tsx
29+
30+
# Format single file
31+
pnpm prettier --write src/pure.tsx
2032

2133
# Run tests
2234
pnpm --filter @rstest/browser-react test
2335
```
2436

37+
Note: Prefer file-scoped commands for faster feedback during development.
38+
39+
## Project structure
40+
41+
- `src/index.ts` — Default entry with auto-cleanup via `beforeEach`
42+
- `src/pure.tsx` — Core implementation (render, renderHook, cleanup, configure)
43+
- `src/act.ts` — React `act()` wrapper with `IS_REACT_ACT_ENVIRONMENT` management
44+
45+
## Good and bad examples
46+
47+
### Handling React version differences
48+
49+
Good — use feature detection with fallback:
50+
51+
```typescript
52+
// src/act.ts
53+
const _act = (React as Record<string, unknown>).act as
54+
| ((callback: () => unknown) => Promise<void>)
55+
| undefined;
56+
57+
export const act: ActFunction =
58+
typeof _act !== 'function'
59+
? async (callback) => {
60+
await callback();
61+
} // React 17 fallback
62+
: async (callback) => {
63+
await _act(callback);
64+
}; // React 18+
65+
```
66+
67+
Bad — assume specific React version:
68+
69+
```typescript
70+
import { act } from 'react'; // Breaks React 17
71+
```
72+
2573
## Exports
2674

2775
### Default entry (`@rstest/browser-react`)
2876

29-
- `render` — Render a React component
30-
- `renderHook` — Test React hooks
77+
- `render` — Render a React component, returns `RenderResult`
78+
- `renderHook` — Test React hooks, returns `RenderHookResult`
3179
- `cleanup` — Cleanup mounted components
3280
- `act` — Wrap state updates
3381

@@ -39,36 +87,28 @@ Same exports plus:
3987

4088
- `configure` — Configure render behavior (e.g., `reactStrictMode`)
4189

42-
No auto-cleanup, user must call `cleanup()` manually.
90+
No auto-cleanup user must call `cleanup()` manually.
4391

44-
## Usage with @testing-library/dom
45-
46-
This package provides React rendering utilities. For DOM queries (`getByRole`, `getByText`, etc.), users can optionally install `@testing-library/dom`:
92+
## Key types
4793

4894
```typescript
49-
import { render } from '@rstest/browser-react'
50-
import { screen } from '@testing-library/dom'
51-
52-
test('example', async () => {
53-
await render(<Button>Click me</Button>)
54-
expect(screen.getByRole('button')).toBeTruthy()
55-
})
95+
interface RenderResult {
96+
container: HTMLElement;
97+
baseElement: HTMLElement;
98+
unmount: () => Promise<void>;
99+
rerender: (ui: ReactNode) => Promise<void>;
100+
asFragment: () => DocumentFragment;
101+
}
102+
103+
interface RenderOptions {
104+
container?: HTMLElement;
105+
baseElement?: HTMLElement;
106+
wrapper?: JSXElementConstructor<{ children: ReactNode }>;
107+
}
56108
```
57109

58-
## Do
59-
60-
- Keep this package focused on React rendering lifecycle
61-
- Use `act()` for all render/unmount operations
62-
- Support React 17, 18, and 19
63-
64-
## Don't
65-
66-
- Don't add DOM query utilities (users can use @testing-library/dom)
67-
- Don't add dependencies beyond React peer deps
68-
- Don't break compatibility with older React versions without discussion
69-
70-
## Key files
110+
## When stuck
71111

72-
- `src/pure.tsx` — Core implementation
73-
- `src/act.ts`React act wrapper
74-
- `src/index.ts` — Auto-cleanup entry
112+
- Ask clarifying questions or propose a plan
113+
- Check React version compatibility before making changes
114+
- Reference `@testing-library/react` for API design inspiration

packages/browser-react/README.md

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
# @rstest/browser-react
2+
3+
React component testing support for [Rstest](https://rstest.dev) browser mode.
4+
5+
## Installation
6+
7+
```bash
8+
npm install @rstest/browser-react
9+
# or
10+
pnpm add @rstest/browser-react
11+
```
12+
13+
## Usage
14+
15+
### Basic component testing
16+
17+
```tsx
18+
import { render, cleanup } from '@rstest/browser-react';
19+
import { screen } from '@testing-library/dom';
20+
import { expect, test } from '@rstest/core';
21+
22+
test('renders button', async () => {
23+
await render(<button>Click me</button>);
24+
expect(screen.getByRole('button')).toBeTruthy();
25+
});
26+
```
27+
28+
### Testing with wrapper (providers/context)
29+
30+
```tsx
31+
import { render } from '@rstest/browser-react';
32+
33+
const Wrapper = ({ children }) => (
34+
<ThemeProvider theme="dark">{children}</ThemeProvider>
35+
);
36+
37+
test('renders with theme', async () => {
38+
await render(<MyComponent />, { wrapper: Wrapper });
39+
});
40+
```
41+
42+
### Testing hooks
43+
44+
```tsx
45+
import { renderHook } from '@rstest/browser-react';
46+
import { useState } from 'react';
47+
48+
test('useState hook', async () => {
49+
const { result, rerender } = await renderHook(() => useState(0));
50+
51+
expect(result.current[0]).toBe(0);
52+
53+
await result.current[1](1);
54+
await rerender();
55+
56+
expect(result.current[0]).toBe(1);
57+
});
58+
```
59+
60+
### Manual cleanup with pure entry
61+
62+
```tsx
63+
import { render, cleanup } from '@rstest/browser-react/pure';
64+
import { afterEach } from '@rstest/core';
65+
66+
// No auto-cleanup, manage it yourself
67+
afterEach(async () => {
68+
await cleanup();
69+
});
70+
```
71+
72+
### Enabling React strict mode
73+
74+
```tsx
75+
import { configure } from '@rstest/browser-react/pure';
76+
77+
configure({ reactStrictMode: true });
78+
```
79+
80+
## API
81+
82+
### `render(ui, options?)`
83+
84+
Renders a React element into the DOM.
85+
86+
**Returns:** `Promise<RenderResult>`
87+
88+
```typescript
89+
interface RenderResult {
90+
container: HTMLElement;
91+
baseElement: HTMLElement;
92+
unmount: () => Promise<void>;
93+
rerender: (ui: ReactNode) => Promise<void>;
94+
asFragment: () => DocumentFragment;
95+
}
96+
97+
interface RenderOptions {
98+
container?: HTMLElement;
99+
baseElement?: HTMLElement;
100+
wrapper?: JSXElementConstructor<{ children: ReactNode }>;
101+
}
102+
```
103+
104+
### `renderHook(callback, options?)`
105+
106+
Renders a custom React hook for testing.
107+
108+
**Returns:** `Promise<RenderHookResult>`
109+
110+
```typescript
111+
interface RenderHookResult<Result, Props> {
112+
result: { current: Result };
113+
rerender: (props?: Props) => Promise<void>;
114+
unmount: () => Promise<void>;
115+
act: (callback: () => unknown) => Promise<void>;
116+
}
117+
```
118+
119+
### `cleanup()`
120+
121+
Unmounts all mounted components. Called automatically before each test when using the default entry.
122+
123+
### `act(callback)`
124+
125+
Wraps a callback in React's `act()` for proper state updates.
126+
127+
### `configure(options)` (pure entry only)
128+
129+
Configure render behavior.
130+
131+
```typescript
132+
interface RenderConfiguration {
133+
reactStrictMode: boolean;
134+
}
135+
```
136+
137+
## Using with @testing-library/dom
138+
139+
This package provides React rendering utilities. For DOM queries (`getByRole`, `getByText`, etc.), install `@testing-library/dom`:
140+
141+
```bash
142+
npm install @testing-library/dom
143+
```
144+
145+
```tsx
146+
import { render } from '@rstest/browser-react';
147+
import { screen, fireEvent } from '@testing-library/dom';
148+
149+
test('button click', async () => {
150+
await render(<Counter />);
151+
152+
const button = screen.getByRole('button');
153+
fireEvent.click(button);
154+
155+
expect(screen.getByText('1')).toBeTruthy();
156+
});
157+
```
158+
159+
## Compatibility
160+
161+
- React 17, 18, and 19
162+
- Node.js >= 18.12.0
163+
164+
## License
165+
166+
MIT

packages/browser/package.json

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,14 @@
4040
"dev": "rslib build --watch"
4141
},
4242
"dependencies": {
43-
"@rsbuild/core": "1.7.1",
43+
"@jridgewell/trace-mapping": "0.3.31",
44+
"convert-source-map": "^2.0.0",
4445
"open-editor": "^4.0.0",
46+
"pathe": "^2.0.3",
4547
"sirv": "^2.0.4",
4648
"ws": "^8.18.3"
4749
},
4850
"devDependencies": {
49-
"@jridgewell/trace-mapping": "0.3.31",
5051
"@rslib/core": "^0.19.0",
5152
"@rstest/browser-ui": "workspace:*",
5253
"@rstest/core": "workspace:*",
@@ -56,8 +57,6 @@
5657
"@types/ws": "^8.18.1",
5758
"@vitest/snapshot": "^3.2.4",
5859
"birpc": "2.9.0",
59-
"convert-source-map": "^2.0.0",
60-
"pathe": "^2.0.3",
6160
"picocolors": "^1.1.1",
6261
"picomatch": "^4.0.3",
6362
"playwright": "^1.49.1"

0 commit comments

Comments
 (0)