Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/macku/jest-puppe-shots
A Jest plugin for creating screenshots of React components with a little help of Puppeteer
https://github.com/macku/jest-puppe-shots
chrome css enzyme javascript jest jest-matchers js matcher puppet puppeteer react react-components screenshot snapshot testing unit-testing unittest visual-regression visual-testing
Last synced: 2 months ago
JSON representation
A Jest plugin for creating screenshots of React components with a little help of Puppeteer
- Host: GitHub
- URL: https://github.com/macku/jest-puppe-shots
- Owner: macku
- License: mit
- Created: 2018-02-04T22:04:33.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2020-01-05T21:40:37.000Z (almost 5 years ago)
- Last Synced: 2024-10-01T05:23:37.173Z (2 months ago)
- Topics: chrome, css, enzyme, javascript, jest, jest-matchers, js, matcher, puppet, puppeteer, react, react-components, screenshot, snapshot, testing, unit-testing, unittest, visual-regression, visual-testing
- Language: JavaScript
- Homepage:
- Size: 204 KB
- Stars: 85
- Watchers: 4
- Forks: 3
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
- awesome-list - jest-puppe-shots
- awesome-jest - jest-puppe-shots
README
jest-puppe-shots
=================[![NPM version](https://badge.fury.io/js/jest-puppe-shots.svg)](https://www.npmjs.com/package/jest-puppe-shots)
[![node](https://img.shields.io/node/v/jest-puppe-shots.svg)](https://www.npmjs.com/package/jest-puppe-shots)
[![Build Status](https://travis-ci.org/macku/jest-puppe-shots.svg?branch=master)](https://travis-ci.org/macku/jest-puppe-shots)
[![dependencies Status](https://david-dm.org/macku/jest-puppe-shots/status.svg?path=packages/jest-puppe-shots)](https://david-dm.org/macku/jest-puppe-shots?path=packages/jest-puppe-shots)
[![devDependencies Status](https://david-dm.org/macku/jest-puppe-shots/dev-status.svg?path=packages/jest-puppe-shots)](https://david-dm.org/macku/jest-puppe-shots?path=packages/jest-puppe-shots&type=dev)
[![peerDependencies Status](https://david-dm.org/macku/jest-puppe-shots/peer-status.svg?path=packages/jest-puppe-shots)](https://david-dm.org/macku/jest-puppe-shots?path=packages/jest-puppe-shots&type=peer)A [Jest](https://facebook.github.io/jest/) plugin for creating screenshots of [React](https://reactjs.org/) components with a little help of [Puppeteer](https://github.com/GoogleChrome/puppeteer)
How it works?
=============
A `jest-puppe-shots` is a **Jest** plugin that can help you create **Visual Regression** tests for your React components.
If you ever used [**Enzyme**](http://airbnb.io/enzyme/) or [**Snapshots**](https://facebook.github.io/jest/docs/en/snapshot-testing.html) you will love the `jest-puppe-shots`.The Snapshot testing approach is really awesome but it has one downside: it cannot be used to make visual regression tests of your components.
Thanks to the [Puppeteer API](https://github.com/GoogleChrome/puppeteer) it's now possible to use **Chromium browser** in Jest and create **real screenshots** of your components!Installation
============You can install the plugin using [**NPM**](https://www.npmjs.com):
```bash
npm install jest-puppe-shots --save-dev
```or by [**Yarn**](https://yarnpkg.com/):
```bash
yarn add jest-puppe-shots --dev
```## Additional dependencies
You will have to install [`jest`](https://www.npmjs.com/package/jest) and [`react-dom`](https://www.npmjs.com/package/react-dom) if you don't have them yet:```bash
npm install jest react-dom
```## Async/Await
The `jest-puppe-shots` API is written on top of the **Puppeteer** which means the currently supported version of **Node is 7.6+**.
You will also have to setup your **Babel** configuration to use the [Async/Await from ES7](https://developers.google.com/web/fundamentals/primers/async-functions).[Here you can find the tutorial](https://babeljs.io/docs/plugins/transform-async-to-generator/) how to setup your **Babel** settings to use it.
Jest Configuration
==================
Before starting using the `jest-puppe-shots` you will need to change your Jest configuration file.Open the `jest.config.json` file in your project and add additional entry:
```json
{
"preset": "jest-puppe-shots-preset"
}
```If you are are using the `jest.config.js` file, then instead adjust your configuration like this:
```js
module.exports = {
// You config goes herepreset: 'jest-puppe-shots-preset'
}
```Taking Screenshots
==================After setting up the configuration you can start writing your first integration test that will take screenshots.
The `jest-puppe-shots` it utilizing a couple of concepts and tools under the hood:- It's using [**Puppeteer**](https://github.com/GoogleChrome/puppeteer) to start Chromium browser in the headless mode
- It takes a Screenshot of the component and stores it as a **Snapshot** inside your repository under the `__image_snapshots__` directory.
If you are not familiar with the Jest Snapshots testing take a look at [Jest documentation page](https://facebook.github.io/jest/docs/en/snapshot-testing.html).
- Uses the [`.toMatchImageSnapshot()`](https://www.npmjs.com/package/jest-image-snapshot) matcher to compare the base screenshot with the current version token during the test execution.# Writing First Integration Test
Take a look at the example test code:```js
const { openNewPage } = require('jest-puppe-shots'); // 1. Require the jest-puppe-shots module into your test
import { openNewPage } from 'jest-puppe-shots'; // or use the ES module import if you likeimport MyComponent from './MyComponent'; // 2. Import your React component
let page;
beforeEach(async () => {
page = await openNewPage(); // 3. Open new page for taking screenshots
});test('should render component', async () => {
const component = await page.mount( // 4. Mount your component
Hello World!
);const screenshot = await page.takeScreenshot(component); // 5. Take a screenshot of your component
expect(screenshot).toMatchImageSnapshot(); // 6. Assert image snapshots and you're done!
});
```Running this code for the first time by Jest, will produce a **Base Screenshot** and store it inside the repository at `your-test-location/__image_snapshots__` directory.
To update the **Base Screenshot** run Jest with `--updateSnapshot` or `-u` parameter.
# Mounting additional CSS
If your components are based on additional CSS code from your code base like ex. `reset.css` you might like to mount the static content on the page:
```js
import path from 'path';
import { openNewPage } from 'jest-puppe-shots';let page;
beforeEach(async () => {
page = await openNewPage();
await page.mountCssContext(path.resolve('../path/to/my-assets-dir', [
'css/reset.css',
'css/custom-styles.css'
]))
});
```Mounting the CSS directory might also help you with loading static content files like **images** or **font**.
# Loading external CSS and JS files
You can also load and put an external CSS and JS files on your page:
```js
import { openNewPage } from 'jest-puppe-shots';let page;
beforeEach(async () => {
page = await openNewPage();
await page.loadExternalCss(
'https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css',
'https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css'
);await page.loadExternalJs(
'https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js'
);
});
```Both `loadExternalCss` and `loadExternalJs` function can accept multiple arguments so you can pass as URLs as you want.
Roadmap
=======- [ ] Transform the `*.less` and `*.sass` files into **CSS** code when importing component modules by Jest
- [ ] Better support for the [`Enzyme`](http://airbnb.io/enzyme) like API. You should be able to use ex. `get`, or `find` functions after
mounting component
- [ ] Making screenshots of component parts by ex. selecting DOM nodes
- [ ] More built-in renderers and support for custom renderers (pass a function)
- [ ] Debugging: allow to start test without the headless mode and see what browser is doingFAQ
===## What version of Jest do I need to use?
You will have to install Jest 22+. The main reason of that is [version 22 introduced](https://github.com/facebook/jest/blob/master/CHANGELOG.md#features-9) the [`globalSetup` and `globalTeardown`](https://github.com/facebook/jest/pull/4716) options APIs.## What Node version is supported?
Since both **Puppeteer** and `jest-puppe-shots` are heavily depending on the `async/await` API you will have to use **Node 7.6+** that [enabled the support for it](https://blog.readme.io/using-async-await-in-node-js-7-6-0/).## I don't want to run Puppeteer each time I'm running my tests. It takes *ages* to start Jest and it's getting slow!
No problem! You don't need to launch Puppeteer for you regular Unit Tests. You will just have to adjust your environment a little bit. Take a look at the example:
1. Edit your `package.json` file and provide additional entries for running screenshot tests:
### Before
```json
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch"
}
}
```### After
```json
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:screenshots": "cross-env TAKE_SCREENSHOTS=true jest",
"test:watch:screenshots": "cross-env TAKE_SCREENSHOTS=true jest --watch"
}
}
```We are using the [`cross-env`](https://www.npmjs.com/package/cross-env) package in order to set environment variables for all the operating systems.
2. Rename your `jest.config.json` to `jest.config.js` and adjust the source code to use `jest-puppe-shots` preset only when we need it.
### Before
```json
{
"preset": "jest-puppe-shots-preset"
}
```### After
```js
let config = {
/* Your Jest config goes here */
};if (process.env.TAKE_SCREENSHOTS) {
config.preset = 'jest-puppe-shots-preset';
}module.exports = config;
```3. Right now you can run unit tests as usual by `npm run test` and you can launch integration tests by running `npm run test:screenshots`
## I'm using `styled-components` to provide my CSS code. Is it supported?
That's fine. Good news for you is that `jest-puppe-shots` is supporting [`styled-components`](https://www.styled-components.com/).
All you need to do is to inform runner that you would like to use a custom renderer.Edit your Jest config file `jest.config.json` and add new `globals` entry to the configuration:
```json
{
"globals": {
"__JEST_PUPPE_SHOTS_RENDERER__": "STYLED_COMPONENTS"
}
}
```Currently, there are two supported renderers:
- `REACT_SERVER` (default) - It's using the [`react-dom/server`](https://www.npmjs.com/package/react-dom) package to render component as string
- `STYLED_COMPONENTS` - It's using the `ServerStyleSheet` from [`styled-components`](https://www.npmjs.com/package/styled-components) to intercept the produced CSS styles and inject them on the page