Chart.js Test Utilities
chartjs-test-utils is a dedicated utility package designed to simplify and standardize the testing of Chart.js applications and plugins. It provides specialized tools such as fixture management for rendering charts in isolated DOM environments, mock contexts to control canvas behavior, and custom Jasmine matchers like `toEqualImageData` and `toEqualOptions` for asserting chart rendering and configuration. The package is currently at v0.5.0, with releases typically driven by dependency updates or minor feature enhancements rather than a strict schedule. Its primary differentiator is its deep integration with Chart.js's internal rendering and configuration, making it indispensable for maintaining visual and functional correctness across Chart.js ecosystem projects, particularly when used with Karma and Jasmine.
Common errors
-
TypeError: expect(...).toEqualImageData is not a function
cause The Jasmine custom matcher provided by `chartjs-test-utils` has not been properly registered or imported into the test environment.fixEnsure `chartjs-test-utils` is imported or required in a way that allows its matchers to be registered, typically by including `import 'chartjs-test-utils'` at the top of your test file or through a global setup in Karma/Jasmine. -
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
cause An asynchronous operation, such as `triggerMouseEvent` or `fixture.run`, was called without `await`, causing the test to complete before the async function resolved.fixPrepend `await` to calls to `triggerMouseEvent` and `fixture.run`. If the test function itself is not `async`, change its declaration to `it('should do something', async () => { ... });`. -
ERROR in ./test/specs/my-test.js Module not found: Error: Can't resolve 'chartjs-test-utils' in ...
cause The `chartjs-test-utils` package is not installed or incorrectly referenced in the project's `node_modules`.fixRun `npm install chartjs-test-utils` or `yarn add chartjs-test-utils` to ensure the package is correctly installed.
Warnings
- breaking The `toEqualImageData` matcher was updated in v0.3.0 to include size verification, potentially causing tests to fail if chart dimensions changed or were previously not strictly checked.
- breaking In v0.2.0, `triggerMouseEvent` became an asynchronous function and `fixture.run` was updated to return a Promise instead of using a callback. This change requires tests to use `await` with these functions.
- gotcha This package relies heavily on peer dependencies (`jasmine`, `karma`, `karma-jasmine`). Mismatched or outdated versions of these peer dependencies can lead to runtime errors or unexpected behavior during test execution.
- gotcha When using `fixture.run()`, remember to call `fixture.cleanup()` in your `afterEach` or `afterAll` hooks to prevent DOM contamination between tests and ensure isolated environments.
Install
-
npm install chartjs-test-utils -
yarn add chartjs-test-utils -
pnpm add chartjs-test-utils
Imports
- fixture
const fixture = require('chartjs-test-utils').fixtureimport { fixture } from 'chartjs-test-utils' - triggerMouseEvent
import triggerMouseEvent from 'chartjs-test-utils'
import { triggerMouseEvent } from 'chartjs-test-utils' - toEqualImageData
import 'chartjs-test-utils'
Quickstart
import { fixture, triggerMouseEvent } from 'chartjs-test-utils';
import { Chart } from 'chart.js';
describe('MyChart integration', () => {
let chart, canvas, wrapper;
// Add global matchers provided by chartjs-test-utils
beforeAll(() => {
// Assuming chartjs-test-utils is imported globally or its matchers are explicitly added
// For this example, we'll assume a global setup or 'import "chartjs-test-utils"' handles it.
});
beforeEach(async () => {
// fixture.run creates a new DOM environment for each test
const result = await fixture.run('<canvas id="myChart" width="400" height="400"></canvas>');
canvas = result.querySelector('#myChart');
wrapper = result;
chart = new Chart(canvas, {
type: 'bar',
data: {
labels: ['Red', 'Blue', 'Yellow'],
datasets: [{
label: 'Votes',
data: [12, 19, 3],
backgroundColor: ['red', 'blue', 'yellow']
}]
},
options: {
responsive: false
}
});
});
afterEach(() => {
if (chart) {
chart.destroy();
}
fixture.cleanup(); // Cleans up the DOM environment
});
it('should render correctly', () => {
// Use custom matcher to check image data. Requires a baseline image or pixel comparison logic.
// expect(canvas).toEqualImageData('my-chart-baseline'); // Example usage with a baseline
expect(chart.data.datasets[0].data[0]).toBe(12);
});
it('should trigger mouse events and update chart', async () => {
// Simulate a mouse click on the canvas
await triggerMouseEvent(canvas, 'mousemove', 100, 100); // Simulate hover
await triggerMouseEvent(canvas, 'click', 100, 100); // Simulate click
// In a real test, you'd assert changes caused by the event, e.g., tooltip visibility.
// For demonstration, we just ensure the event can be triggered without error.
expect(true).toBe(true);
});
});