• Stars
    star
    483
  • Rank 91,050 (Top 2 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 6 years ago
  • Updated over 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Module for adding visual regression testing to Cypress

Cypress Visual Regression

npm

github actions

Module for adding visual regression testing to Cypress.

Getting Started

Install:

$ npm install cypress-visual-regression

Add the following config to your cypress.config.js file:

const { defineConfig } = require("cypress");
const getCompareSnapshotsPlugin = require('cypress-visual-regression/dist/plugin');

module.exports = defineConfig({
  screenshotsFolder: './cypress/snapshots/actual',
  trashAssetsBeforeRuns: true,
  video: false,
  e2e: {
    setupNodeEvents(on, config) {
      getCompareSnapshotsPlugin(on, config);
    },
  },
});

Add the command to cypress/support/commands.js:

const compareSnapshotCommand = require('cypress-visual-regression/dist/command');

compareSnapshotCommand();

Make sure you import commands.js in cypress/support/e2e.js:

import './commands'

TypeScript

If you're using TypeScript, use files with a .ts extension, as follows:

cypress/cypress.config.ts

import { defineConfig } from 'cypress';
import getCompareSnapshotsPlugin from 'cypress-visual-regression/dist/plugin';

export default defineConfig({
  env: {
    screenshotsFolder: './cypress/snapshots/actual',
    trashAssetsBeforeRuns: true,
    video: false
  },
  e2e: {
    setupNodeEvents(on, config) {
      getCompareSnapshotsPlugin(on, config);
    },
  },
});

cypress/support/commands.ts

import compareSnapshotCommand from 'cypress-visual-regression/dist/command';

compareSnapshotCommand();

cypress/tsconfig.json

{
  "compilerOptions": {
    "types": [
      "cypress",
      "cypress-visual-regression"
    ]
  }
}

For more info on how to use TypeScript with Cypress, please refer to this document.

Options

failSilently is enabled by default. Add the following config to your cypress.config.js file to see the errors:

{
  env: {
    failSilently: false
  }
}

You can also pass default arguments to compareSnapshotCommand():

const compareSnapshotCommand = require('cypress-visual-regression/dist/command');

compareSnapshotCommand({
  capture: 'fullPage'
});

These will be used by default when no parameters are passed to the compareSnapshot command.

Configure snapshot paths

You can control where snapshots should be located by setting two environment variables:

Variable Description
SNAPSHOT_BASE_DIRECTORY Directory of the base snapshots
SNAPSHOT_DIFF_DIRECTORY Directory for the snapshot difference
INTEGRATION_FOLDER Used for computing correct snapshot directories

The actual directory always points to the configured screenshot directory.

For more information regarding INTEGRATION_FOLDER please refer to PR#139

Configure snapshot generation

In order to control the creation of diff images you may want to use the following environment variables which are typically set by using the field env in configuration in cypress.config.json.

Variable Description
ALWAYS_GENERATE_DIFF Boolean, defaults to true
ALLOW_VISUAL_REGRESSION_TO_FAIL Boolean, defaults to false

ALWAYS_GENERATE_DIFF specifies if diff images are generated for successful tests. If you only want the tests to create diff images based on your threshold without the tests to fail, you can set ALLOW_VISUAL_REGRESSION_TO_FAIL. If this variable is set, diffs will be computed using your thresholds but tests will not fail if a diff is found.

If you want to see all diff images which are different (based on your thresholds), use the following in your cypress.config.json:

{
  "env": {
    "ALWAYS_GENERATE_DIFF": false,
    "ALLOW_VISUAL_REGRESSION_TO_FAIL": true
  }
}

To Use

Add cy.compareSnapshot('home'); in your tests specs whenever you want to test for visual regressions, making sure to replace home with a relevant name. You can also add an optional error threshold: Value can range from 0.00 (no difference) to 1.00 (every pixel is different). So, if you enter an error threshold of 0.51, the test would fail only if > 51% of pixels are different.

More examples:

Threshold Fails when
.25 > 25%
.30 > 30%
.50 > 50%
.75 > 75%

Sample:

it('should display the login page correctly', () => {
  cy.visit('/03.html');
  cy.get('H1').contains('Login');
  cy.compareSnapshot('login', 0.0);
  cy.compareSnapshot('login', 0.1);
});

You can target a single HTML element as well:

cy.get('#my-header').compareSnapshot('just-header')

You can pass arguments as an object to cy.compareSnapshot(), rather than just an error threshold, as well:

it('should display the login page correctly', () => {
  cy.visit('/03.html');
  cy.compareSnapshot('login', {
    capture: 'fullPage',
    errorThreshold: 0.1
  });
});

Looking for more examples? Review docker/cypress/e2e/main.cy.js.

Take the base images:

$ ./node_modules/.bin/cypress run --env type=base --config screenshotsFolder=cypress/snapshots/base,testFiles=\"**/*regression-tests.js\"

# use comma separated format for multiple config commands
$ ./node_modules/.bin/cypress run \
  --env type=base \
  --config screenshotsFolder=cypress/snapshots/base,testFiles=\"**/*regression-tests.js\"

Find regressions:

$ ./node_modules/.bin/cypress run --env type=actual

Example

example

Tips & Tricks

Ignore some elements

Following function creates a command that allows you to hide elements of the page based on their className:

/**
 * To be called after you setup the command, in order to add a
 * hook that does stuff before the command is triggered
 */
function beforeCompareSnapshotCommand(
  /** Element you want to ignore */
  ignoredElementsQuerySelector: string,
  /** Main app element (if you want for the page to be loaded before triggering the command) */
  appContentQuerySelector: string = "body"
) {
  Cypress.Commands.overwrite("compareSnapshot", (originalFn, ...args) => {
    return cy
      // wait for content to be ready
      .get(appContentQuerySelector)
      // hide ignored elements
      .then($app => {
        return new Cypress.Promise((resolve, reject) => {
          setTimeout(() => {
            $app.find(ignoredElementsQuerySelector).css("visibility", "hidden");
            resolve();
            // add a very small delay to wait for the elements to be there, but you should
            // make sure your test already handles this
          }, 300);
        });
      })
      .then(() => {
        return originalFn(...args);
      });
  });
}

module.exports = beforeCompareSnapshotCommand;

You may then use this function like below:

const compareSnapshotCommand = require("cypress-visual-regression/dist/command");
const beforeCompareSnapshotCommand = require("./commands/beforeCompareSnapshots");
compareSnapshotCommand({
  errorThreshold: 0.1
});
// add a before hook to compareSnapshot (this must be called AFTER compareSnapshotCommand() so the command can be overriden)
beforeCompareSnapshotCommand(
  ".chromatic-ignore,[data-chromatic='ignore']",
  "._app-content"
);

In this example, we ignore the elements that are also ignored by 3rd party tool Chromatic.

More Repositories

1

awesome-fastapi

A curated list of awesome things related to FastAPI
5,592
star
2

flaskr-tdd

Flaskr: Intro to Flask, Test-Driven Development (TDD), and JavaScript
Python
2,259
star
3

awesome-flask

A curated list of awesome things related to Flask
1,143
star
4

python-ruby

Should I Learn Python or Ruby?
Python
317
star
5

passport-local-express4

check out the blog post
JavaScript
290
star
6

node-stripe-charge

node + stripe + express + bootstrap 4 (used for one time charges)
JavaScript
272
star
7

microservice-movies

JavaScript
248
star
8

sublime-setup-for-python

setting up sublime text for python development
JavaScript
241
star
9

flask-redis-queue

Example of how to handle background processes with Flask, Redis Queue, and Docker
Python
207
star
10

Scrapy-Samples

Scrapy examples crawling Craigslist
Python
196
star
11

thinkful-html

intro to html and css
HTML
163
star
12

thinkful-mentor

code samples, refactoring - for thinkful students
TSQL
158
star
13

thinkful-angular

AngularJS by Example - Building a Bitcoin Investment Calculator
JavaScript
130
star
14

node-koa-api

JavaScript
130
star
15

flask-tracking

http://www.realpython.com
Python
129
star
16

typescript-node-api

TypeScript
128
star
17

node-postgres-promises

JavaScript
104
star
18

flask-basic-registration

Basic user registration package for Flask.
Python
102
star
19

passport-examples

social auth for node
JavaScript
93
star
20

node-postgres-todo

JavaScript
93
star
21

Flask-Landing

simple landing page to collect prelaunch emails
Python
64
star
22

node-swagger-api

JavaScript
63
star
23

node-mocha-chai-tutorial

JavaScript
62
star
24

whiterspace

Another minimal theme for Octopress.
JavaScript
62
star
25

angular-gulp-browserify-seed

Angular starter featuring Gulp, Bower, and Browserify
JavaScript
58
star
26

node-docker-api

developing and testing microservices with docker
JavaScript
57
star
27

twitter-sentiment-analysis

Video tutorial and accompanying output for conducting text sentiment analysis in Twitter
R
56
star
28

mean-auth

User Auth with the MEAN Stack
JavaScript
54
star
29

testing-in-django

Example project for testing in Django.
JavaScript
53
star
30

efk-kubernetes

logging in kubernetes
JavaScript
52
star
31

node-postgres-sequelize

JavaScript
52
star
32

passport-local-knex

adding passport to a node app
JavaScript
51
star
33

angular-auth-ngrx

TypeScript
50
star
34

passport-social-auth

JavaScript
49
star
35

node-docker-workflow

http://mherman.org/blog/2015/03/06/node-with-docker-continuous-integration-and-delivery
JavaScript
48
star
36

passport-local

user authentication to Node.js with Passport.js.
JavaScript
43
star
37

node-express-ajax-craigslist

scraping craigslist
JavaScript
38
star
38

web2py

Intro to web2py
Python
38
star
39

sinatra-blog

Sinatra + PostgreSQL + Heroku - on the center stage
Ruby
38
star
40

flask-stripe

Flask + Stripe + User Registration
Python
34
star
41

flask-spark-docker

Just a boilerplate for PySpark and Flask
Python
33
star
42

python-decorators

into to python decorators
Python
33
star
43

java-for-javascript

Java for JavaScript Developers
Java
30
star
44

node-twitter-sentiment

sentiment analysis with node, express, and the twitter api
JavaScript
30
star
45

mocha-chai-knex

JavaScript
29
star
46

node-token-auth

jwt auth!
JavaScript
29
star
47

angular-testing-tutorial

welcome!
JavaScript
27
star
48

flask-intro

Introduction to Flask showing much of the basic functionality. Plus, I built a task manager application called FlaskTaskr.
Python
26
star
49

node-stripe-example

JavaScript
25
star
50

react-intro

just a basic react intro
JavaScript
24
star
51

flask-rethink

a todo list with flask and rethinkdb
Python
23
star
52

django-stripe

Django + Stripe + User Registration
Python
22
star
53

express-testing-mocha-knex

testing an express app
JavaScript
21
star
54

programming-exercises

Michael Herman's stash of programming exercises
JavaScript
20
star
55

koa-passport-example

koa + passport
JavaScript
17
star
56

noLogo

minimalist octopress theme.
JavaScript
16
star
57

node-grpc-crud

JavaScript
15
star
58

python-devtest

new developer test
Python
14
star
59

vue-intro

intro to vuejs
HTML
14
star
60

flow-node-api

JavaScript
14
star
61

node-getting-started

a little more than hello world!
JavaScript
14
star
62

pinky-promise

why sign an nda when you can just pinky swear instead?
CSS
12
star
63

node-workshop

learn javascript and node!
JavaScript
12
star
64

craigslist-housing-scraper

use sparingly, at your own risk
Python
12
star
65

ancestry-scraper

Python
12
star
66

twitter-sentiment-python

basic sentiment analysis in python
11
star
67

bootstrap3

getting started with bootstrap 3
CSS
11
star
68

flask-songs-api

Python
11
star
69

octoplate

Octopress theme based on Twitter Bootstrap 3
JavaScript
10
star
70

testcafe-example

JavaScript
10
star
71

flask-ajax-form

Generate a dynamic form in Flask with AJAX
JavaScript
9
star
72

TDD-Django

Blog post and associated code repo describing TDD with Django and PyVows.
Python
9
star
73

docker-workshop

JavaScript
8
star
74

django-1.5-template

django 1.5 + custom registration + bootstrap + heroku
CSS
8
star
75

testcafe-visual-regression

JavaScript
8
star
76

running-mate

simple MLOps tool for DS/ML teams
Python
8
star
77

flask-geolocation

that's right: flask and geolocation
Python
8
star
78

django-tutorial

Code from a brief tutorial showing the basics of installing Django and setting up a simple app.
Python
8
star
79

django-tastypie-tutorial

Super Basic REST API with django-tastypie
Python
8
star
80

node-express-swig-mongo

JavaScript
8
star
81

flask-scrapy-test

for kristjan
Python
7
star
82

bottle-plotly-python

bottle.py and the plot.ly API
Smarty
7
star
83

node-bootstrap3-template

node, express, bootstrap3, boilerplate, starter, template, mongo-ready
JavaScript
7
star
84

microservice-ping-pong

JavaScript
6
star
85

bottle-user-authentication

bottle.py user login/logout/authentication bootstrap3
Python
6
star
86

django-tdd

django 1.6 test driven development!
Python
6
star
87

express-crud-pg-promise

Just a basic Node + Express CRUD app with pg-promise
JavaScript
5
star
88

hibbert-django

mike hibbert
JavaScript
5
star
89

node-oauth-openid

JavaScript
5
star
90

node-request-cheerio-scraper

scraping HN => CSV
JavaScript
5
star
91

angular4-crud

TypeScript
5
star
92

job-scraper

indeed
Python
5
star
93

generator-herman-express

generator for a basic Node/Express boilerplate
JavaScript
5
star
94

docker-rails-ecs

deliver rails app to ecs
Ruby
5
star
95

mean-token-auth

JavaScript
5
star
96

textbook

learning management system
JavaScript
5
star
97

mjhea0.github.com

code for my blog, powered by github pages and jekyll
HTML
5
star
98

ultimate-craigslist-scraper

get jobs. lots of 'em.
Python
5
star
99

indeed-scraper

stay away
Python
4
star
100

web2py-heroku

heroku + web2py
4
star