Rahul
Rahul

Reputation: 849

HTML Canvas Testing With Jest-Puppeteer (Javascript)

I have a signature component (React.js) that requires testing with the automation suite I've built with Jest-Puppeteer. The component is a <canvas> HTML element.

<canvas width="1316" height="500" style="width: 100%; touch-action: none;"></canvas>

I have found this npm package: https://www.npmjs.com/package/jest-canvas-mock and another solution on StackOverflow: HTML Canvas Unit testing

But, I was wondering if someone could give a much more comprehensive explanation of how exactly one could automate a process on a <canvas> tag and then assert it ideally with Jest-Puppeteer, i.e. how does ctx work, it's properties, etc.

Thank you!

Upvotes: 3

Views: 3631

Answers (2)

Aaron Watters
Aaron Watters

Reputation: 2846

An HTML5 canvas is quite a feature rich thing, but for testing purposes one thing to look at is the toDataURL method https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL which will give you a string representing an image of the canvas contents. You can pass this string back to the Puppeteer/node context and inspect it to see if the canvas looks right (maybe by converting it back into an image or array).

Also the getImageData method https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/getImageData will get the image array directly but you will have to convert the ImageData https://developer.mozilla.org/en-US/docs/Web/API/ImageData Uint8ClampedArray to a list in order to pass it from the "browser" to the "node" context (I think)


// This runs in the browser context

var get_canvas_data_json_object = function() {
    // get the 4 by 4 upper left pixel values from the canvas_context
    var image_data = canvas_context.getImageData(0,0,4,4);
    var data_array = image_data.data;
    // 4 8-bit RGBA color values by 4 rows by 4 columns as a serializable list
    var data_list = Array.from(data_array);
    return data_list;
};

Then call this function from puppeteer like this

// this runs in the puppeteer/node context
const data = await page.evaluate("get_canvas_data_json_object()")

Here is a similar working example from

https://github.com/flatironinstitute/radiation_viz

which gets data from a WebGL canvas in a browser context here:

https://github.com/flatironinstitute/radiation_viz/blob/master/docs/main.js#L322

and reads it in puppeteer/node context here:

https://github.com/flatironinstitute/radiation_viz/blob/master/image_capturer/scrape_images.js#L66

Hope that helps or gets you started.

Upvotes: 3

Admiral Potato
Admiral Potato

Reputation: 110

Since you mentioned that you're using your canvas in a "signature" component, the ctx that you're referring to is probably the CanvasRenderingContext2D.

You can think of a CanvasRenderingContext2D as a stateful drawing robot that can paint on the Canvas instance that created it. You can set properties on the robot like paint color and brush width, and then call its methods to move it around and draw onto the Canvas it belongs to.

As with all browser APIs, Mozilla Developer Network is probably the best possible reference for you to learn with, as they have "How to" as well as "List of everything", and even "X works in Y browser" types of documentation. This link should help you get started!

https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D

Upvotes: -1

Related Questions