Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Dev] Support showing CSS inside test snapshots #225

Merged
merged 2 commits into from
Aug 21, 2017
Merged

[Dev] Support showing CSS inside test snapshots #225

merged 2 commits into from
Aug 21, 2017

Conversation

orta
Copy link
Contributor

@orta orta commented Aug 21, 2017

This makes PRs make more sense when looking at the results of tests 👍

@alloy
Copy link
Contributor

alloy commented Aug 21, 2017

Groovy 👌

@alloy alloy merged commit 7a3face into master Aug 21, 2017
@artsy-peril
Copy link
Contributor

artsy-peril bot commented Aug 21, 2017

Warnings
⚠️

New dependencies added: jest-styled-components.

jest-styled-components

Author: Michele Bertoli

Description: Jest utilities for Styled Components

Homepage: https://github.com/styled-components/jest-styled-components#readme

Created5 months ago
Last Updated2 days ago
LicenseMIT
Maintainers2
Releases59
Direct Dependenciescss
README [![NPM version](https://img.shields.io/npm/v/jest-styled-components.svg)](https://www.npmjs.com/package/jest-styled-components) [![Join the community on Spectrum](https://withspectrum.github.io/badge/badge.svg)](https://spectrum.chat/styled-components/jest)

Build Status
tested with jest
styled with prettier

Jest Styled Components

A set of utilities for testing Styled Components with Jest.
This package improves the snapshot testing experience and provides a brand new matcher to make expectations on the style rules.

Quick Start

Installation

yarn add --dev jest-styled-components

Usage

import React from 'react'
import styled from 'styled-components'
import renderer from 'react-test-renderer'
import 'jest-styled-components'

const Button = styled.button`
  color: red;
`

test('it works', () => {
  const tree = renderer.create(<Button />).toJSON()
  expect(tree).toMatchSnapshot()
  expect(tree).toHaveStyleRule('color', 'red')
})

Snapshot Testing

Jest snapshot testing is an excellent way to test React components (or any serializable value) and make sure things don't change unexpectedly.
It works with Styled Components but there are a few problems that this package addresses and solves.

For example, suppose we create this styled Button:

import styled from 'styled-components'

const Button = styled.button`
  color: red;
`

Which we cover with the following test:

import React from 'react'
import renderer from 'react-test-renderer'

test('it works', () => {
  const tree = renderer.create(<Button />).toJSON()
  expect(tree).toMatchSnapshot()
})

When we run our test command, Jest generates a snapshot containing a few class names (which we didn't set) and no information about the style rules:

exports[`it works 1`] = `
<button
  className="sc-bdVaJa rOCEJ"
/>
`;

Consequently, changing the color to green:

const Button = styled.button`
  color: green;
`

Results in the following diff, where Jest can only tell us that the class names are changed.
Although we can assume that if the class names are changed the style rules are also changed, this is not optimal (and is not always true).

- Snapshot
+ Received

 <button
-  className="sc-bdVaJa rOCEJ"
+  className="sc-bdVaJa hUzqNt"
 />

Here's where Jest Styled Components comes to rescue.

We just import the package into our test file:

import 'jest-styled-components'

When we rerun the test, the output is different: the style rules are included in the snapshot, and the hashed class names are substituted with placeholders that make the diffs less noisy:

- Snapshot
+ Received

+.c0 {
+  color: green;
+}
+
 <button
-  className="sc-bdVaJa rOCEJ"
+  className="c0"
 />

This is the resulting snapshot:

exports[`it works 1`] = `
.c0 {
  color: green;
}

<button
  className="c0"
/>
`;

Now, suppose we change the color again to blue:

const Button = styled.button`
  color: blue;
`

Thanks to Jest Styled Components, Jest is now able to provide the exact information and make our testing experience even more delightful 💖:

- Snapshot
+ Received

 .c0 {
-  color: green;
+  color: blue;
 }

 <button
   className="c0"
 />

Enzyme

enzyme-to-json is necessary to generate snapshots using Enzyme's shallow or full DOM rendering.

yarn add --dev enzyme-to-json

It can be enabled globally in the package.json:

"jest": {
  "snapshotSerializers": [
    "enzyme-to-json/serializer"
  ]
}

Or imported in each test:

import toJson from 'enzyme-to-json'

// ...

expect(toJson(wrapper)).toMatchSnapshot()

Jest Styled Components works with shallow rendering:

import { shallow } from 'enzyme'

test('it works', () => {
  const wrapper = shallow(<Button />)
  expect(wrapper).toMatchSnapshot()
})

And full DOM rendering as well:

import { mount } from 'enzyme'

test('it works', () => {
  const wrapper = mount(<Button />)
  expect(wrapper).toMatchSnapshot()
})

toHaveStyleRule

The toHaveStyleRule matcher is useful to test if a given rule is applied to a component.
The first argument is the expected property, the second is the expected value (string or RegExp).

test('it works', () => {
  const tree = renderer.create(<Button />).toJSON()
  expect(tree).toHaveStyleRule('color', 'red')
})

The matcher supports a third options parameter which makes it possible to search for rules nested within an At-rule (media and supports) or to add modifiers to the class selector. This feature is supported in React only, and more options are coming soon.

const Button = styled.button`
  @media (max-width: 640px) {
    &:hover {
      color: red;
    }
  }
`

test('it works', () => {
  const tree = renderer.create(<Button />).toJSON()
  expect(tree).toHaveStyleRule('color', 'red', {
    media: '(max-width: 640px)',
    modifier: ':hover',
  })
})

This matcher works with trees serialized with react-test-renderer and shallow renderered or mounted with Enzyme.
It checks the style rules applied to the root component it receives, therefore to make assertions on components further in the tree they must be provided separately (Enzyme's find might help).

To use the toHaveStyleRule matcher with React Native, change the import statement to:

import 'jest-styled-components/native'

styled-components < v2

To use this package with styled-components < v2 (e.g. v1.4.6) the following annotation must be added at the top of the test files.
Consequently, it won't be possible to use Enzyme's full DOM rendering.

/**
 * @jest-environment node
 */

Contributing

Please open an issue and discuss with us before submitting a PR.

Generated by 🚫 dangerJS

@alloy alloy deleted the styled-jest branch October 20, 2017 10:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants