How to install react18-enzyme-to-rtl
npx skills add https://github.com/github/awesome-copilot --skill react18-enzyme-to-rtlFull instructions (SKILL.md)
Source of truth, from github/awesome-copilot.
name: react18-enzyme-to-rtl description: 'Provides exact Enzyme → React Testing Library migration patterns for React 18 upgrades. Use this skill whenever Enzyme tests need to be rewritten - shallow, mount, wrapper.find(), wrapper.simulate(), wrapper.prop(), wrapper.state(), wrapper.instance(), Enzyme configure/Adapter calls, or any test file that imports from enzyme. This skill covers the full API mapping and the philosophy shift from implementation testing to behavior testing. Always read this skill before rewriting Enzyme tests - do not translate Enzyme APIs 1:1, that produces brittle RTL tests.'
React 18 Enzyme → RTL Migration
Enzyme has no React 18 adapter and no React 18 support path. All Enzyme tests must be rewritten using React Testing Library.
The Philosophy Shift (Read This First)
Enzyme tests implementation. RTL tests behavior.
// Enzyme: tests that the component has the right internal state
expect(wrapper.state('count')).toBe(3);
expect(wrapper.instance().handleClick).toBeDefined();
expect(wrapper.find('Button').prop('disabled')).toBe(true);
// RTL: tests what the user actually sees and can do
expect(screen.getByText('Count: 3')).toBeInTheDocument();
expect(screen.getByRole('button', { name: /submit/i })).toBeDisabled();
This is not a 1:1 translation. Enzyme tests that verify internal state or instance methods don't have RTL equivalents - because RTL intentionally doesn't expose internals. Rewrite the test to assert the visible outcome instead.
API Map
For complete before/after code for each Enzyme API, read:
references/enzyme-api-map.md- full mapping: shallow, mount, find, simulate, prop, state, instance, configurereferences/async-patterns.md- waitFor, findBy, act(), Apollo MockedProvider, loading states, error states
Core Rewrite Template
// Every Enzyme test rewrites to this shape:
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import MyComponent from './MyComponent';
describe('MyComponent', () => {
it('does the thing', async () => {
// 1. Render (replaces shallow/mount)
render(<MyComponent prop="value" />);
// 2. Query (replaces wrapper.find())
const button = screen.getByRole('button', { name: /submit/i });
// 3. Interact (replaces simulate())
await userEvent.setup().click(button);
// 4. Assert on visible output (replaces wrapper.state() / wrapper.prop())
expect(screen.getByText('Submitted!')).toBeInTheDocument();
});
});
RTL Query Priority (use in this order)
getByRole- matches accessible roles (button, textbox, heading, checkbox, etc.)getByLabelText- form fields linked to labelsgetByPlaceholderText- input placeholdersgetByText- visible text contentgetByDisplayValue- current value of input/select/textareagetByAltText- image alt textgetByTitle- title attributegetByTestId-data-testidattribute (last resort)
Prefer getByRole over getByTestId. It tests accessibility too.
Wrapping with Providers
// Enzyme with context:
const wrapper = mount(
<ApolloProvider client={client}>
<ThemeProvider theme={theme}>
<MyComponent />
</ThemeProvider>
</ApolloProvider>
);
// RTL equivalent (use your project's customRender or wrap inline):
import { render } from '@testing-library/react';
render(
<MockedProvider mocks={mocks} addTypename={false}>
<ThemeProvider theme={theme}>
<MyComponent />
</ThemeProvider>
</MockedProvider>
);
// Or use the project's customRender helper if it wraps providers
Related skills
More from github/awesome-copilot and the wider catalog.

react18-legacy-context
Provides the complete migration pattern for React legacy context API (contextTypes, childContextTypes, getChildContext) to the modern createContext API. Use this skill whenever migrating legacy context in class components - this is always a cross-file migration requiring the provider AND all consumers to be updated together. Use it before touching any contextTypes or childContextTypes code, because migrating only the provider without the consumers (or vice versa) will cause a runtime failure. Always read this skill before writing any context migration - the cross-file coordination steps here prevent the most common context migration bugs.

react18-lifecycle-patterns
Provides exact before/after migration patterns for the three unsafe class component lifecycle methods - componentWillMount, componentWillReceiveProps, and componentWillUpdate - targeting React 18.3.1. Use this skill whenever a class component needs its lifecycle methods migrated, when deciding between getDerivedStateFromProps vs componentDidUpdate, when adding getSnapshotBeforeUpdate, or when fixing React 18 UNSAFE_ lifecycle warnings. Always use this skill before writing any lifecycle migration code - do not guess the pattern from memory, the decision trees here prevent the most common migration mistakes.

react18-string-refs
Provides exact migration patterns for React string refs (ref="name" + this.refs.name) to React.createRef() in class components. Use this skill whenever migrating string ref usage - including single element refs, multiple refs in a component, refs in lists, callback refs, and refs passed to child components. Always use this skill before writing any ref migration code - the multiple-refs-in-list pattern is particularly tricky and this skill prevents the most common mistakes. Use it for React 18.3.1 migration (string refs warn) and React 19 migration (string refs removed).

react19-concurrent-patterns
Preserve React 18 concurrent patterns and adopt React 19 APIs (useTransition, useDeferredValue, Suspense, use(), useOptimistic, Actions) during migration.

react19-source-patterns
Reference for React 19 source-file migration patterns, including API changes, ref handling, and context updates.

react19-test-patterns
Provides before/after patterns for migrating test files to React 19 compatibility, including act() imports, Simulate removal, and StrictMode call count changes.