Testing
motif renders real elements, so most component tests are ordinary Testing Library tests. For the
cases where you need to assert on resolved styles, @usemotif/test-utils carries a conformance
suite and a pair of Vitest matchers.
Test components the ordinary way
A <Box> renders a real <div>; a <Pressable> renders a real button-like element with its
ARIA attributes set. There is nothing motif-specific to mock — render the component under a
<ThemeProvider> and assert with @testing-library/react as you would for any React component.
Query by role and label, not by class. motif's generated class names — m-1a2b3c — are stable
hashes, but they are an implementation detail; a test that asserts on them breaks the first time
a style prop changes. The accessible name and role are the contract worth testing.
Assert on resolved styles
When the thing under test is the styling — a styled() component with variants, a responsive
prop — assert on what resolved. @usemotif/test-utils ships two Vitest matchers for this.
Register them once in a setup file.
The matchers operate on a RendererOutput — the normalised, theme-resolved shape a renderer
adapter produces. toHaveStyle checks the unconditional style; toHaveStyleAt checks a scoped
rule, keyed by an @media, @container, or pseudo-selector prefix.
Both are subset matches — extra keys are tolerated, so a renderer adding delivery-specific styles does not break the assertion.
Run the conformance suite
@usemotif/test-utils exists for a larger job: proving that two renderers — web and native —
resolve the same props to the same styles. standardCases is the renderer-agnostic case list;
assertConformance renders one case through an adapter and throws on any mismatch.
This matters to you when you maintain a design system on top of motif and want to prove a wrapper
layer has not changed resolution, or when you author a custom renderer. The adapter is the seam:
it renders a ConformanceCase and normalises the result into RendererOutput. The internal
@usemotif/react and @usemotif/react-native packages each supply one; standardCases runs
unchanged against both.
To extend coverage, append your own cases — they are plain objects of the same shape.
defaultTestTheme is the small fixed theme the standard cases resolve against — reach for it
whenever a unit test needs a stable theme without pulling in the full @usemotif/tokens defaults.