TanStack
Guides

Testing and Debugging

A useful chart test answers more than “did a surface appear?” Test at the narrowest layer that owns the behavior.

Test the scene first

createChartScene gives static definitions a deterministic, DOM-free result:

ts
import { createChartScene } from '@tanstack/charts'

const scene = createChartScene(definition, {
  width: 640,
  height: 360,
})

expect(scene.points).toHaveLength(rows.length)
expect(scene.scales.x.domain).toEqual(expectedDates)
expect(scene.chart.width).toBeGreaterThan(0)

For responsive definitions, create a runtime and call render with an exact surface size. Scene tests are suited to:

  • materialized domains and ticks;
  • mark and guide geometry;
  • clipping and margins;
  • focus-point metadata;
  • stable node keys;
  • deterministic themes and gradients.

Avoid asserting the complete scene object when only one semantic invariant matters.

Test serialized SVG

Use renderChartSvg to verify:

  • accessible name and description;
  • resource ID scoping;
  • expected SVG element kinds;
  • absence of invalid numeric output;
  • deterministic server markup.

Prefer structural assertions over a full string snapshot. A formatting change should not obscure a geometry regression.

Test the DOM host

Mount into a real or sufficiently complete DOM when behavior depends on:

  • responsive measurement;
  • pointer or keyboard focus;
  • sticky tooltips;
  • selection callbacks;
  • keyed reconciliation;
  • interrupted animation;
  • font-driven relayout;
  • export of computed styles.

Always call destroy() and verify observers, frames, tooltip nodes, and event listeners do not survive.

Run the same focus, keyboard, tooltip, selection, responsive-update, and destroy sequences against SVG and Canvas when renderer parity matters. Those behaviors belong to the shared host; renderer tests should concentrate on surface adoption, coordinate conversion, paint, and cleanup.

For Canvas, test deterministic server-shell markup without installing Canvas APIs. Use a Canvas 2D mock for draw-call and device-pixel-ratio assertions, then use browser screenshots for representative paths, clipping, gradients, text, themes, and focus-overlay composition. Do not use a raw pixel or data-URL snapshot as the only semantic assertion.

Test interaction as a sequence

Describe the user path and its semantic assertion:

  1. Move to a known chart coordinate.
  2. Verify the resolved datum and grouped points.
  3. Select or pin it.
  4. Update, resize, reorder, or filter the chart.
  5. Verify focus is preserved when the key survives and cleared when it does not.
  6. Verify keyboard access reaches the same information.

This catches state-preservation failures that a static screenshot cannot.

Visual regression tests

Use screenshots for painted properties that are hard to express as numbers:

  • label overlap;
  • automatic margins;
  • curve and area crossings;
  • gradients and clipping;
  • high-density aliasing;
  • light and dark themes.

Fix fonts, viewport, device scale, animation state, locale, time zone, and data revision. Pair the screenshot with geometry assertions so a visually small but semantically important error cannot hide in the diff threshold.

Accessibility tests

At minimum verify:

  • the SVG or Canvas root has a meaningful accessible name;
  • descriptions summarize the current chart, not every point;
  • keyboard focus can enter and traverse the chart when enabled;
  • focus and selection callbacks expose the same data as pointer interaction;
  • reduced-motion disables nonessential animation;
  • an adjacent table or summary exists when exact values are required.

See Accessibility.

Diagnose by layer

When output is wrong, inspect in this order:

  1. Prepared rows and intervals.
  2. Materialized mark channels.
  3. Resolved scale domains, ranges, bandwidths, and ticks.
  4. scene.chart bounds and margins.
  5. Scene nodes and interaction points.
  6. Renderer input and static output.
  7. Mounted surface and application styling.

If the scene is correct but the surface is wrong, the defect belongs to rendering, reconciliation or paint, or styling. If the channel values are wrong, changing the renderer will not fix the cause.

Performance tests need correctness gates

A timed run is valid only if it also verifies:

  • the requested revision painted;
  • expected nodes and points exist;
  • representative geometry is finite and in bounds;
  • no page or lifecycle errors occurred;
  • the interaction result belongs to the latest scene.

Exclude invalid attempts from rankings. Report warmup, sample count, percentile, environment, data size, and renderer capability. See Bundle Size and Performance.