americanexpress / jest-image-snapshot

✨ Jest matcher for image comparisons. Most commonly used for visual regression testing.
Apache License 2.0
3.85k stars 200 forks source link

Automatically detect Jest jsdom/canvas environment #279

Open mbullington opened 3 years ago

mbullington commented 3 years ago

Hello! Thanks for open sourcing jest-image-snapshot and working with the community on it!

I'm trying to use this for Image from jsdom, which you can automatically set up in Jest https://jestjs.io/docs/configuration#testenvironment-string and with the peerdep canvas. https://github.com/jsdom/jsdom#canvas-support

I wrote this little blurb to automatically detect a JSDOM Image in the toMatchImageSnapshot snapshot and think it would be useful if it was unstreamed. Here is my setupFilesAfterEnv file:

/**
 * Takes a JSDOM image and returns a Node.js buffer to use
 * with jest-image-snapshot.
 */
function imageToBuffer(image: HTMLImageElement): Buffer {
  const canvas = document.createElement('canvas');
  canvas.width = image.width;
  canvas.height = image.height;

  const ctx = canvas.getContext('2d');

  ctx.drawImage(image, 0, 0);

  const base64 = canvas.toDataURL().split(',')[1];
  return Buffer.from(base64, 'base64');
}

expect.extend({
  toMatchImageSnapshot: function (received, options) {
    // If these checks pass, assume we're in a JSDOM environment with the 'canvas' package.
    if (
      received &&
      received.constructor &&
      received.constructor.name === 'HTMLImageElement'
    ) {
      received = imageToBuffer(received);
    }

    return toMatchImageSnapshot.call(this, received, options);
  }
});

Best,