Skip to content
This repository has been archived by the owner on Jun 11, 2024. It is now read-only.

Latest commit

 

History

History
343 lines (266 loc) · 10.8 KB

README.md

File metadata and controls

343 lines (266 loc) · 10.8 KB

Happo Version Badge

Build Status dependency status dev dependency status License Downloads

npm badge

Happo (formerly Diffux-CI) is a command-line tool to visually diff JavaScript components. Read more.

Installation

Happo comes bundled as an npm module. To install it, run

npm install -g happo

You'll also need Firefox installed on the machine. Happo uses selenium-webdriver under the hood, and will support whatever version Selenium supports. Happo currently works best with Firefox 47.0.1.

Introduction

You begin by defining a set of examples that Happo will grab snapshots for. If a previous snapshot exists for a component, Happo will diff the new snapshot with the previous. If a diff is found, a visual representation of the changes will be constructed. You can then use that diff image to decide whether a visual regression has been introduced or not, and take appropriate action based on that information.

Demo of Happo in action

Defining examples

You define your examples in a JavaScript file and include it in the sourceFiles configuration option.

Here's an example of a button component being added to a Happo suite:

happo.define('button', function() {
  var elem = document.createElement('button');
  elem.setAttribute('class', '.button');
  elem.innerHTML = 'Submit';
  document.body.appendChild(elem);
});

Here's an example using React) and ES6:

happo.define('<MyReactComponent>', function() {
  const div = document.createElement('div');
  document.body.appendChild(div);
  const component = (
    <MyReactComponent
      foo={1}
      bar='baz'
    />
  );
  ReactDOM.render(component, div);
});

Examples are responsible themselves for rendering the element into the DOM. This is because a lot of frameworks (e.g. React) like to stay in control over the DOM. A helper method to reduce some of the boilerplate is probably a good idea in your project.

During development, you might want to zoom in/focus on a single example. In those situations, you can use the happo.fdefine function instead of happo.define. Using fdefine will cause happo to only run for the examples that are using fdefine and skip all examples using define.

Setting viewport sizes

By default, Happo renders examples in a 1024 wide window. If you have components that render differently depending on available screen size you can use the viewports option in the object passed in as the second argument to happo.define. These need to correspond to configured viewports in the .happo.yaml file. Happo comes pre-configured with three default sizes: large (1024x768), medium (640x888), and small (320x444).

happo.define('responsive component', function() {
  var elem = document.createElement('div');
  elem.setAttribute('class', '.responsive-component');
  document.body.appendChild(elem);
}, { viewports: ['large', 'small'] });

Async examples

If your examples need to do something asynchronous before they finish render, you can return a Promise from your define method.

happo.define('async component', function() {
  return new Promise(function(resolve) {
    var elem = document.createElement('div');
    document.body.appendChild(elem);
    setTimeout(function() {
      elem.innerHTML = 'Async content loaded';
      resolve();
    }, 100);
  });
});

Alternatively, use the done callback passed in to the define method.

happo.define('async component', function(done) {
  var elem = document.createElement('div');
  document.body.appendChild(elem);
  setTimeout(function() {
    elem.innerHTML = 'Async content loaded';
    done();
  }, 100);
});

Cleaning up the DOM

Happo will clean up the DOM in between rendered examples. If you need more control over the clean-up process you can override happo.cleanOutElement with your own implementation. This is useful if you need to clean up event listeners for instance, or if you use React and need to unmount components.

happo.cleanOutElement = function(element) {
  React.unmountComponentAtNode(element);
};

Controlling root nodes

By default, Happo will compute a bounding rectangle used when snapshotting based on all root DOM nodes found in the <body> element. You can override this default by implementing a happo.getRootNodes function. If you use React you might want to use this to better control the size of the snapshot.

happo.getRootNodes = function() {
  return document.querySelectorAll('[data-reactroot]');
};

Configuration

Happo loads configuration in one of the following ways:

  • From a javascript file specified via a HAPPO_CONFIG_FILE environment variable
  • From .happo.js in the current working directory

Example configuration

module.exports = {
  // Control the interface on which the local server listens (defaults to 'localhost')
  // (default: 'localhost')
  bind: '0.0.0.0',

  // Control the port used for the local server
  // (default: 4567)
  port: 7777,

  // List javascript source files. These can be files or raw URLs.
  // (default: [])
  sourceFiles: [
    'https://unpkg.com/[email protected]',
    'application.js',
    'happo-examples.js',
  ],

  // List css source files. These can also be files or raw URLs.
  // (default: [])
  stylesheets: [
    'application.css',
  ],

  // List directories where public files are accessible (useful for e.g. font files)
  // (default: [])
  publicDirectories: [
    'public',
  ],

  // Specify the folder where snapshots are saved
  // (default: 'snapshots')
  snapshotsFolder: 'happo-snapshots',

  // Configure the window size when taking snapshots
  // (defaults shown below)
  viewports: {
    large: {
      width: 1024,
      height: 768,
    },
    medium: {
      width: 640,
      height: 888,
    },
    small: {
      width: 320,
      height: 444,
    },
  },
};

Command line tools

happo run

This command will fire up a Firefox instance and take snapshots of all your happo examples.

happo review

Once happo run has finished, run happo review from the command line. This will open a page that compares the latest run's snapshots against the previous snapshots.

happo debug

If you want to debug rendering your examples, you can run happo debug. This will open a browser window pointing at /debug, listing all your examples. If you click one of them, the example will be rendered in isolation and you can do use your developer tools to debug.

happo upload [<triggeredByUrl>]

Uploads all current diff images to an Amazon S3 account and reports back URLs to access those diff images. Requires that S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, and S3_BUCKET_NAME are specified as environment variables. S3_ACCESS_KEY_ID and S3_SECRET_ACCESS_KEY will be the credentials Happo uses to access the bucket named S3_BUCKET_NAME.

S3_BUCKET_PATH can be set as an environment variable to specify a directory path for where you want diff images uploaded within the S3 bucket.

Furthermore, S3_REGION controls what region is used to find or create the bucket.

``

You can set these in the session by using export:

export S3_ACCESS_KEY_ID=<YOUR_ACCESS_KEY_VALUE>
export S3_SECRET_ACCESS_KEY=<YOUR_SECRET_ACCESS_KEY_VALUE>
export S3_BUCKET_NAME=<YOUR_BUCKET_NAME>

happo upload

or by adding them in the beginning of the command:

S3_ACCESS_KEY_ID=<...> S3_SECRET_ACCESS_KEY=<...> ... happo upload

If you want the diff page to link back to a commit/PR, you can pass in a URL as the argument to happo upload_diffs. E.g.

happo upload "https://test.example"

To debug uploading, you can use the --debug flag. Additional information will then be printed to stderr.

happo upload-test

Uploads a small text file to an AWS S3 Account. This is useful if you want to test your S3 configuration. Uses the same configuration as happo upload does. As with happo upload, you can apply a --debug flag here for a more verbose output.

happo upload-test --debug

Running in a CI environment

The main purpose for Happo is for it to be run in a CI (Continuous Integration) environment. The command line tools provided are designed to be used as building blocks in a script that you can run in Travis, Jenkins and other Continuous Integration environments.

Below is an example of how you can use Happo to test if a commit introduces any visual change.

  1. Check out the commit previous to the one to test (e.g. git checkout HEAD^)
  2. (optionally) precompile your JavaScript and/or CSS
  3. Run happo run to generate previous snapshots
  4. Check out the commit to test
  5. (optionally) precompile your JavaScript and/or CSS
  6. Run happo run to diff against previously created snapshots
  7. Run happo upload to upload diffs to a publicly accessible location

There's an example script implementing these steps located in happo_example.sh. Use that as a starting point for your own CI script.

Headless Happo

Since Happo uses Firefox to generate its snapshots, you need a display. If you are on a build server, you usually don't have a screen. To run happo then, you can use a virtual display server such as xvfb. The example CI script as well as the internal Travis test run for Happo uses xvfb-run in order to obtain a virtual display.

In the wild

Organizations and projects using Happo.