Skip to content

salesforce-ux/instant-vrt

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

About

Module for running vrt

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published