End to end testing Canvas element
Tags: testing, canvas, cypress, chromatic
Published: 2023-03-22 12:42:23

Canvas (Maps, charts, etc...) elements have no DOM element to select, therefore they are hard to test using regular testing framework/methods. Still we have some possibles solutions: 
   - It's possible to test the values that serves to build the Canvas.
   - It's possible to visually check the differences between the current version of the canvas and a previous one.

Here's a summary about (recent) solutions I've tested.

## Test values of the Canevas

1. Output results of the canvas (what you want to test/know) in a data-attribute, in the dom.
  - You can select this attribute and make a test on it.
  - That pollutes the DOM but it works and it's relatively lightweight if you don't test every values but only the keys ones.
2. Output results in a dedicated not-visible component
  - You can select this attribute and make the test on it. 
  - Ugly, but regarding idea n°1 it gives you a better separation between test and user's code.
  - Possible to enable this component only in tests (like with an url param "&tests=true").
3. Using visual comparison
  - ✅ Most trustworthy way to make "real e2e".
  - ❌ Easy to install, hard to set up properly.
  - ❌ Very sensible to changes.

## Wait on the canvas to be fully rendered

Useful typically when you want to test interaction with you Canvas.

1. Depends on the library, you may have a "render-ready" event or something like that.
2. Generally, if you wait on the values that create the canvas (see section above), then the canevas is ready.
3. 💡Images are slow to be loaded, watching and waiting on icon/images request can be a good idea.

## Visual comparison systems

- Generally too sensible. Minor changes break a PR, even with a good tolerance.
- Snapshot depends too much on the environment. Local testing could give you not the same results as CI testing.
  - ⚠ That could make reference images complicated to generate or makes not possible local testing.

If you want to install a tool, instructions are on their website, and a lot of tips can be found on dev.to 😎

### Chromatic

https://www.chromatic.com

- I've only experienced it with the whole page / example page / storybook page. I don't know if it's possible to focus on a specific element.
- Works well, relatively easy to set up.
- Can be a check in your Github's PRs, linked to a page to review the change.

### Cypress visual regression plugins

There are multiples plugins:
https://npmtrends.com/@applitools/eyes.cypress-vs-@cypress/snapshot-vs-cypress-image-diff-vs-cypress-image-diff-js-vs-cypress-image-snapshot-vs-cypress-plugin-snapshots-vs-cypress-visual-regression-vs-cypress-visual-testing-vs-happo-cypress

Generally based on Cypress snapshot:

 - ✅ It allows you to snapshot an element: cy.get('canvas').snapshot... and not the whole page!
 - ✅ Easy to setup for most of the plugins.
 - 😎 Most are open source
 - ❌ A lot of plugins are old and only supported by a small community.
 - ❌ Cypress strangely "zooms" into the component to snapshot, making it hard/impossible to have what you want.
 - ❌ Works bad with high resolution (tried with 5120x2060)

Yes, visual comparison is the quicker way to test every settings of you Canvas. But that's only when the system is set up and doing that will give you head each. Also, rendering function should be already tested by the library that draws the canvas for you.

Think twice before to choose a way to test you code 😀