jest-gl
contains various helper functions allow you to easily write browserless visual tests around your webGL code. The library uses headless-gl, looks-same, and pngjs2 packages to provide a small API for saving, diffing, and comparing images of a mocked webGL context.
- headless-gl
jest-gl
does not have a dependency on Jest. However, it was designed with Jest testing in mind.
npm i jest-gl --save-dev
yarn add jest-gl --dev
jest-gl
uses file name postfixes to distingush between visual testing images:
.spec
an image representing the desired look of the webGL application.head
an image representing the current look of the webGL applicaton.diff
an image representing a comparison of a .spec and .head file with highlighted differences
Names and the highlight color are all optionally configurable to match your organization's preferences. In your test file:
let jestGl = require('../index.js')({
specPostfix: '.spec', // postfix tag to spec images - default shown
headPostfix: '.head', // postfix tag to head images - default shown
diffPostfix: '.diff', // postfix tag to diff images - default shown
highlightColor: '#ff00ff', // diff highlight color - default shown (hot-pink)
})
jest-gl
helper functions are now available!
// create a headless-gl context (https://github.com/stackgl/headless-gl)
const gl = require('gl')(500, 300, {preserveDrawingBuffer: true})
describe('gl visual tests', () => {
beforeAll(() => {
// mock asynchronous shader requests by reading from the file system
http.get = jest.fn((url, responseType) =>
jestGl.fromFile(url, (originalUrl) =>
(originalUrl.indexOf('vs') > -1) ? './app/shaders/vs.glsl' : './app/shaders/fs.glsl'))
canvas = jestGl.mockCanvas(gl, {
width: {value: 300}, // does not indicate final PNG image size
height: {value: 150}, // does not indicate final PNG image size
clientWidth: {value: width}, // does not indicate final PNG image size
clientHeight: {value: height}, // does not indicate final PNG image size
})
})
it('initializes with a square and triangle', async () => {
await app.init(canvas, gl) //start my webGL application
let parity = await jestGl.imageParity(gl, __dirname, 'init', true, true)
expect(parity).toBe(true)
})
})
When you want to update your .spec.png
files, set the TEST_MODE environment variable to 'update'
.
process.env.TEST_MODE = 'update'
For an example of how to set up your test runner, check out ./runner.js. Example usage:
node runner.js # runs your tests
node runner.js -u # runs your tests but updates all .spec.png files
Mocks a network request by loading a local test fixture file instead.
-
String url requested url
-
Function pathMapFn function mapping url to a local resource
Returns a Promise containing a local test fixture file or error
Creates a mock canvas element to add to the mocked gl context
-
any gl the webGL context
-
Object defineProperties collection to map to Object.defineProperties calls
Takes a rendered PNG image of the glCotext
-
any gl the webGL context
-
String imagePath path to save the screenshot
-
Number width in px
-
Number height in px
Returns a Promise resolving to the saved image path
Tests that two glContexts are the same. If found, differences are highlighted in a diff image.
-
any gl the webGL context
-
String dirName the image comparison directory
-
String imageName the name of the image sans postfix and extension (test.spec.js => 'test')
-
boolean strict do strict comparison (default = true)
-
boolean errorDiff save a diff image on error (default = true)
jest-gl
creates and deletes intermediate files. Best to ignore*.head.png
and*.diff.png
from source control.
npm install
npm run build
npm run test
npm run test:watch