Default configuration and README for visual regression testing
- Overview of BackstopJS
- Using a JavaScript Config File
- BackstopJS Setup for Local Machines
- BackstopJS Commands and Use
- Sites with Basic Auth
- Using BackstopJS for Feature Branches
- Using BackstopJS for Deploys
- Using BackstopJS to Compare Two Different Environments
- Additional Notes
BackstopJS is an npm package used for visual regression testing. It creates screenshot references based on CSS selectors, and runs subsequent tests against those screenshots to check for changes. More information and documentation can be found here, including how to re-run a reference for a single item, instead of the entire config file.
By default, BackstopJS uses JSON config files. This setup means that you need a separate config file for different environments, which gets pretty tedious if you need to update URL paths. Instead, we've started using JavaScript config files, which allow us to create an array of relative URLs to use against any environment, based on arguments used in your BackstopJS commands. Many thanks to Tom Phippen for his blog post on Javascript config setup.
This is for a fresh setup of BackstopJS on a project. See BackstopJS Commands and Use below for information on running visual regression tests when BackstopJS is already set up on a project.
- Make sure you have
npm
andnode
installed - Create a feature branch for this setup, so you can merge in the changes once you're done
- Create a
/tests/backstop
directory in the project root - Copy over the contents inside this
visual-regression
directory to the project'stests/backstop
directory. That should include:- generic
.env
file - generic
backstop.js
file - generic
Makefile
package-lock.json
package.json
- generic
paths.js
- generic
- Run
npm install
to get local packages, includingbackstopJS
,dotenv
(used for sites with basic auth) andminimist
(used to implement our custom JS config instead of the default JSON config)- NOTE: With the current version of BackstopJS (as of June 2018), Puppeteer is the recommended engine to use for screenshots.
- Add
/tests/backstop/backstop_data
and/tests/backstop/node_modules
to the.gitignore
in the project root - In the
backstop.js
file, update the genericdev URL
,staging URL
, andprod URL
values. - If desired, update the
delay
andmisMatchThreshold
values in thescenarios.push
array - If desired, update or add viewport settings in the
module.exports
- In the
paths.js
file, add your relative URLs to thepathConfig
array - Create a README in
<project root>/tests/backstop
, and just add a link back to the visual regression README.- This is to make viz reg updates simpler; instead of having a visual regression README per project, there will just be a single source of truth README in the main Visual Regression repo.
This section is for using BackstopJS after it's already been set up on a project. If you need information about setting up a project with BackstopJS, please see the BackstopJS Setup for Local Machines section above.
If BackstopJS is already set up on a project, but you haven't used it yet, you'll need to run through the following steps first:
npm install -g backstopjs
- Navigate to the
/tests/backstop
folder and runnpm install
NOTE: The project's .gitignore
file includes /tests/backstop/backstop_data
, so you won't see this when you visit the project for the first time. The backstop_data
folder is created automatically when you run references and tests, and its location in the backstop
directory is determined by the saveDirectories
variable in the backstop.js
configuration.
The Makefile allows us to vastly simplify the commands, as far as what you actually have to remember to type in. Make commands are only for comparing an environment against itself, and only for dev, staging, and prod environments.
If you're comparing two different environments, you'll need to check out the section below on Using BackstopJS to Compare Two Different Environments.
If you're using BackstopJS to check on regressions during local development, you'll want to check out the section on Using BackstopJS for Feature Branches.
Make commands look like this:
make prod-reference
ormake prod-test
Although the Makefile replaces these commands when comparing the same environment, it's good to know what the Makefile is actually doing.
The full BackstopJS commands look something like this:
- References:
backstop reference --configPath=backstop.js --pathFile=paths --env=<environment> --refHost=<environment URL>
- Tests:
backstop test --configPath=backstop.js --pathFile=paths --env=<environment> --testHost=<environment URL>
- Reports:
backstop openReport --configPath=backstop.js --env=<environment>
- After the test completes, BackstopJS should automatically open the visual regression report in a new browser window. You would run the
openReport
command in order to manually open the report.
- After the test completes, BackstopJS should automatically open the visual regression report in a new browser window. You would run the
Let's break that down:
configPath
: The BackstopJS configuration filepathFile
: The filename (without the file extension) that contains the array of relative URLsenv
: The environment you're testing:local
,dev
,staging
, orprod
- This value determines the screenshots' filenames, and the directory names where the screenshots are stored
- Remember that the
env
argument needs to be the same for both reference and test commands - You can use something generic like
screenshots
if you're comparing two different environments
refHost
/testHost
: The base URL of the website that you're testing
So if you're running references on the dev environment of a website, your command would be something like: backstop reference --configPath=backstop.js --pathFile=paths --env=dev
. Note that there isn't a refHost
argument here. That's because our config file sets the URL based on the --env
value, IF you use dev
, staging
, or prod
.
If the site you're using BackstopJS for has basic auth, you'll need to add a few things.
-
Make sure the
package-lock.json
includes the dotenv package.- If the package is already listed in the file, it'll be installed when you run
npm install
in thebackstop
directory. - If the package hasn't been installed yet, but the
package-lock.json
file already exists, you'll need to runnpm install dotenv --save
to add it - If there isn't currently a
package-lock.json
file, it'll be created when you runnpm install dotenv
.
- If the package is already listed in the file, it'll be installed when you run
-
After you have a
package-lock.json
file with thedotenv
package included, copy over the .env file from the Visual Regression repo into the project'sbackstop
directory. -
In the
.env
file, replace the placeholder values forBASIC_AUTH
with the relevant values for the project site. -
In
backstop.js
, replace the relevant environment URLs.- Example:
'dev': 'http://dev-site.com'
would become'dev': 'http://'+process.env.BASIC_AUTH+'\@dev-site.com'
- Example:
-
In the project's
.gitignore
file, add the updated.env
file so you don't commit basic auth to the repo. -
In the
backstop.js
file, uncomment the linevar dotenv = require('dotenv').config();
.
- Check out the dev branch, or whichever branch you want to use as source of truth
- Seed with whichever database is source of truth
- Make sure your local site is functional. It's terrible to spend the time running BackstopJS on a borked site.
- Navigate to
<project root>/tests/backstop
and run thereference
command. - When the reference screenshots are done, check out the feature branch and run any necessary updates, such as feature reverts, database updates, and CSS compiling
- Make sure you're back in
<project root>/tests/backstop
, and run thetest
command.
When deploying up the environments to prod, you'll want to re-run references and tests against each environment to ensure no visual regressions are introduced. Since you're not testing locally, it won't matter what branch you're on. Using the staging environment as an example, the general practice for this would be:
- Navigate to the project root
- Run the appropriate
make
command to get the pre-deploy reference screenshots. - Once the references have finished running, deploy the code and make any necessary updates, like indexing Solr or clearing caches
- Again from the project root, run the appropriate
make
command for the post-deploy test screenshots - Check the report and make sure nothing's borked
OR
- Navigate back to
<project root>/tests/backstop
- Run the BackstopJS
reference
command to get the pre-deploy screenshots. - Once the references have finished running, deploy the code and make any necessary changes, like indexing Solr or clearing caches
- Run the BackstopJS
test
command - Check the report and make sure nothing's borked
You can use BackstopJS with different environments for reference and test. This could be useful in a few cases, one of which is launching a new site. With this setup, you can run references against staging environment, and then run a test against prod on the initial prod deploy to make sure it looks like you expect.
When comparing different environments, make sure you use the same value for your --env
argument. Remember that the --env
value determines the directory naming for screenshots and reports, which is how BackstopJS compares the images and generates the report. I'd suggest using something generic like screenshots
to avoid confusion.
Commands:
- Reference (staging):
backstop reference --configPath=backstop.js --pathFile=paths --env=screenshots --refHost=http://staging-site.com
- Test (prod):
backstop test --configPath=backstop.js --pathFile=paths --env=screenshots --testHost=http://prod-site.com
While running the BackstopJS test, you may receive an error in Terminal similar to:
Error: ENFILE: file table overflow, open '/Users/<user>/Sites/<project>/backstop_data/bitmaps_test/20160502-170325/49_18_footer_3_desktop.png'
at Error (native)
The solution for this is to: Open /etc/sysctl.conf
in an IDE (or create sysctl.conf
in your /etc folder, if it doesn't already exist) and insert the following settings:
kern.sysv.shmmax=1073741824
kern.sysv.shmmin=1
kern.sysv.shmmni=4096
kern.sysv.shmseg=32
kern.sysv.shmall=1179648
kern.maxfilesperproc=65536
kern.maxfiles=65536