Module for running vrt
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
__tests__
docs
.gitignore
LICENSE.txt
README.md
browser.js
compare.js
matcher.js
package-lock.json
package.json
report.js

README.md

Instant VRT

Visual regression testing based on HTML and computed styles.

Image processing can take time and Git may not be the best place to store binary files. Instead of pixel comparisons of images stored within your source code, this library stores the computed styles of every HTML node which allows you to compare versions with a text comparison instead of a pixel comparison. You can theoretically build out the original with the stored computed styles, too, and do a pixel comparison if needed.

test output

Installation

npm install @salesforce-ux/instant-vrt

Writing a Test

  it('snapshots the footer', () =>
    browser
    .getDOM('.landing__footer')
    .then(dom => assertMatchesDOM({ directory: __dirname, name: 'footer', dom }))
  )

There are 2 parts:

  • browser.getDOM('#mySelector')
  • assertMatchesDOM({ directory: __dirname, name: 'snapshotName', dom: dom, update: false })

The runner works with any test framework (jest, mocha, tape), but it depends on selenium-webdriver to gather the DOM.

You can use phantom, firefox, etc, but we recommend headless chrome. Here is an example of setup:

const getBrowser = () => {
  const options = webdriver.Capabilities.chrome();
  options.set('chromeOptions', { 'args': [ '--headless' ] })
  const chrome = new webdriver.Builder().forBrowser('chrome').withCapabilities(options)
  return decorate(chrome.build()) // decorate the browser with the getDOM function
}

If you don't want to decorate, the package also exposes the getDOM function directly It is curried to take a browser:

const getDOM = browser => selector => /*...*/`

Full Example

const express = require('express')
const chromedriver = require('chromedriver')
const webdriver = require('selenium-webdriver')
const By = webdriver.By
const until = webdriver.until
const path = require('path')

// if you don't want to decorate, this also exposes the getDOM function
const {decorate} = require('@salesforce-ux/instant-vrt/browser')
const {assertMatchesDOM} = require('@salesforce-ux/instant-vrt/matcher')

// Set up an express server to serve our site
const app = express()
app.use(express.static(path.resolve(__dirname, '../.www')));

// a helper function to setup webdriver
const getBrowser = () => {
  const options = webdriver.Capabilities.chrome();
  options.set('chromeOptions', { 'args': [ '--headless' ] })
  const chrome = new webdriver.Builder().forBrowser('chrome').withCapabilities(options)
  return decorate(chrome.build())
}

describe('VRT', () => {
  let server, browser

  beforeAll((done) => {
    server = app.listen(9000, done)
    browser = getBrowser()
    browser.manage().window().setSize(800, 600) // same window size is important
  })

  afterAll(() => {
    server.close()
    browser.quit()
  })

  describe('homepage', () => {
    beforeEach((done) => {
      browser.get('http://localhost:9000/')
      browser.wait(browser.findElements(By.css('.landing__primary-nav')), 2000).then(() => done())
    })

    it('snapshots the top nav', () =>
      browser
      .getDOM('.landing__top-nav')
      .then(dom => assertMatchesDOM({ directory: __dirname, name: 'top nav', dom }))
    )

    it('snapshots the side nav', () =>
      browser
      .getDOM('.landing__primary-nav')
      .then(dom => assertMatchesDOM({ directory: __dirname, name: 'side nav', dom }))
    )

    it('snapshots the footer', () =>
      browser
      .getDOM('.landing__footer')
      .then(dom => assertMatchesDOM({ directory: __dirname, name: 'footer', dom }))
    )
  })
})

Licenses

Source code is licensed under BSD 3-Clause