Snapshot-test D3.js charts - D3 generates SVG (not Canvas, per d3js.org getting-started); use `outerHTML` snapshot for static structure, `toHaveScreenshot` for rendered SVG; jsdom for headless render in unit tests; disable transitions for stable snapshots; per-element data-binding correctness tests. Use when a project renders charts with `d3.create('svg')` or D3 selections and the emitted SVG structure or update join needs regression coverage - including before a D3 major-version upgrade.
76
96%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Deeper D3 test patterns split out of the SKILL spine: the update join (enter / update / exit) and SVG accessibility metadata.
D3's update join (enter / update / exit) is the hardest D3
concept to test. Test the three states:
test('update join handles insert + remove + reorder', async ({ page }) => {
await page.goto('https://localhost:3000/d3-update');
// Initial: [A, B, C]
await page.evaluate(() => (window as any).updateChart(['A', 'B', 'C']));
expect(await page.locator('rect[data-key="A"]').count()).toBe(1);
// After: [A, B, D] - remove C, add D
await page.evaluate(() => (window as any).updateChart(['A', 'B', 'D']));
expect(await page.locator('rect[data-key="C"]').count()).toBe(0);
expect(await page.locator('rect[data-key="D"]').count()).toBe(1);
// After: [B, D, A] - reorder; element identity preserved
await page.evaluate(() => (window as any).updateChart(['B', 'D', 'A']));
// 'A' should be the same DOM node (just repositioned)
// Verify via attribute or event listener attached pre-reorder
});Use a stable key function: data-bind by .data(arr, d => d.id).
D3 generates SVG; SVG has accessibility primitives. Tests verify:
test('chart has title + desc for screen readers', async ({ page }) => {
await page.goto('https://localhost:3000/d3-bar');
await expect(page.locator('svg.bar-chart > title')).toContainText('Revenue by Quarter');
await expect(page.locator('svg.bar-chart > desc')).toContainText('Bar chart showing');
});
test('rects have aria-labels', async ({ page }) => {
const labels = await page.locator('svg.bar-chart rect').evaluateAll(els =>
els.map(el => el.getAttribute('aria-label'))
);
expect(labels[0]).toBe('Q1 revenue: $10k');
});Cross-ref qa-accessibility plugin for broader a11y patterns.