A utility for taking Jest snapshots of React elements that use Styled Components.
This package does not work with v5 of Styled Components due to its use of React Hooks.
You can install Styled Snapshot with the command below.
yarn add styled-snapshot --dev
The library depends on React, Styled Components, Jest, and Enzyme, so these also need to be installed in your project, along with core-js, @babel/runtime and lodash.
yarn add react styled-components@^4 jest enzyme core-js @babel/runtime lodash
Styled Snapshot provides a wrapper around Enzyme and Jest with a custom serializer for taking shallow snapshots of React elements.
The tool snapshots the component itself and extracts the css generated by each Styled Component and any
interpolation rules passed into a component on css
and/or styles
props into their own snapshots.
It also has a number of configuration options that allow you to programmatically unwrap elements to get to the nested one you want to snapshot, omit specific elements from being included in the snapshot, and remove props from being included in the snapshot.
toMatchStyledSnapshot
takes three arguments, a description, the element to unwrap/snapshot, and an optional
configuration object. Under the hood the function uses Enzyme to shallow render the element and do
a base serialization, then it does its custom serialization, and finally generates the required it
blocks and runs
Jest's expect
and toMatchSnapshot
on the element and each set of css.
import { toMatchStyledSnapshot } from "styled-snapshot";
describe("ComponentToSnapshot >>", () => {
toMatchStyledSnapshot(
"Default state",
<ComponentToSnapshot />
);
});
For an example output of toMatchStyledSnapshot
, you can look at one of the library's own
test snapshots.
generateStyledSnapshot
is the function executed within toMatchStyledSnapshot
to generate the serialized
representation of the element and any sets of css. If you want more control over the descriptions in the it
blocks
you can use this function and pass the output to Jest's expect
and toMatchSnapshot
yourself.
It has the same configuration object as toMatchStyledSnapshot
.
import { generateStyledSnapshot } from "styled-snapshot";
describe("ComponentToSnapshot", () => {
const { component, styles } = generateStyledSnapshot(element, options);
it('should match the snapshot', () => {
expect(component).toMatchSnapshot())
});
styles.forEach(([displayName, css]) => {
it(`${displayName} should have the correct css`, () => expect(css).toMatchSnapshot());
});
});
Both the above functions have the following configuration options. These can be specified in a
styled-snapshot.config.js
file in the root of your project or passed into the functions themselves. Any options
passed into the functions take precedent over those defined in the styled-snapshot.config.js
.
type ValidElement = ComponentTypeElement | StyledComponentElement | MandatoryUnwrapElement | DomElement;
interface StyledSnapshotConfig {
contextKeySetter?: (consumer: AnyConsumer) => string | undefined;
elementsToIgnore?: string[];
elementsToUnwrap?: string[];
logLevel?: "error" | "warn" | "info";
reactTreeVisitor?: (node: ObjectMap) => void;
unwrapCustomizer?: (element: ValidElement, config: StyledSnapshotConfig) => ValidElement | ReactNode;
}
The tool will store any contexts it unwraps and provide them to any matching child providers and to the functions
that collate the css. Other than the Styled Components theme
prop key, the tool is not able to derive the prop key
of others context values. This prop provides a callback through which to do this.
This prop allows you to specify the display name of elements the tool should ignore when unwrapping. When, for example, the tool unwraps a component and is left with multiple children, it needs to know which child to unwrap/snapshot next. This prop helps guide the tool through the tree it is unwrapping.
You can also explicitly add a data-styled-ignore
attribute to elements you want to ignore. This is useful if the
element is a dom element and not a component-type element.
This prop allows you to specify the display name of elements the tool should unwrap. It will automatically unwrap fragments, contexts, memos, portals and forward refs that are not Styled Components, but it will not unwrap dom elements, Styled Component elements, functional component elements or class component elements unless they are specified.
You can also explicitly add a data-styled-unwrap
attribute to elements you want to unwrap. This is useful if the
element is a dom element and not a component-type element.
Sometimes you have large datasets such as the Styled Components theme or a menu taxonomy that you do not want to include in your snapshots due to their size. This prop allows you to recursively traverse the serialized element tree before taking a snapshot and execute a callback on each node in which you can remove/replace datasets.
You may find the default unwrap function does not fulfil your needs. In this case, you can pass in a custom unwrap
function that will be used instead of the default. The library exports the default unwrap function
defaultUnwrapChildren
so you can still use that within your custom unwrap function except for the edge cases in which
you need to do something differently.
Check out the features, fixes and more that go into each major, minor and patch version.
Styled Snapshot is MIT Licensed.