Skip to content

Checking access...

Visualization Testing Strategy ​

This document outlines the testing approach for chart and visualization components in founderyOS.

The Challenge ​

Visualization libraries like Recharts render SVG elements that are difficult to test in jsdom environments:

  • SVG paths and coordinates are computed at render time
  • Canvas-based charts don't render in jsdom
  • Visual correctness requires actual browser rendering
  • Test assertions on SVG output are brittle and maintenance-heavy

1. Unit Tests (Vitest + jsdom) ​

Focus on component logic and structure, not visual output:

typescript
// ✅ DO: Test component behavior
it('renders chart container with aria-label', () => {
  render(<BurndownChart data={data} totalPoints={20} />);
  const chart = screen.getByRole('img');
  expect(chart).toHaveAttribute('aria-label', expect.stringContaining('Burndown'));
});

// ✅ DO: Test edge cases
it('renders nothing when data is empty', () => {
  const { container } = render(<BurndownChart data={[]} totalPoints={20} />);
  expect(container.firstChild).toBeNull();
});

// ✅ DO: Test accessibility
it('has descriptive aria-label for screen readers', () => {
  render(<BurndownChart data={data} totalPoints={42} />);
  expect(screen.getByRole('img')).toHaveAttribute('aria-label', expect.stringContaining('42'));
});

// ❌ DON'T: Test SVG internals
it('renders line with correct path', () => {
  // This is brittle and breaks with library updates
  expect(container.querySelector('path')).toHaveAttribute('d', 'M0,100L50,80...');
});

What to test in unit tests:

  • Component renders/doesn't render based on props
  • Accessibility attributes (aria-label, role)
  • Data handling edge cases (empty, null, NaN values)
  • Loading and error states
  • Prop changes trigger re-renders

2. Browser-Based E2E Tests (Playwright) ​

Use Playwright for visual verification of chart rendering:

typescript
// E2E test with Playwright
test('burndown chart displays correctly', async ({ page }) => {
  await page.goto('/backlog');

  // Wait for chart to render
  await page.waitForSelector('[data-testid="burndown-chart"]');

  // Screenshot comparison
  await expect(page.locator('[data-testid="burndown-chart"]')).toHaveScreenshot('burndown-active.png');
});

test('burndown chart shows ideal and actual lines', async ({ page }) => {
  await page.goto('/backlog');

  // Verify SVG elements are present
  const chart = page.locator('[data-testid="burndown-chart"]');
  await expect(chart.locator('path')).toHaveCount(2); // ideal + actual lines
});

What to test in E2E tests:

  • Visual rendering matches expectations (screenshot comparison)
  • Interactive elements work (tooltips, hover states)
  • Chart updates when data changes
  • Responsive behavior at different viewport sizes

3. Manual QA Testing ​

For complex visualizations, browser-based QA verification is essential:

markdown
## QA Checklist for Charts

- [ ] Chart renders with mock data
- [ ] Chart handles empty data gracefully
- [ ] Axis labels are readable
- [ ] Legend displays correctly
- [ ] Tooltips appear on hover
- [ ] Chart is responsive (resize browser)
- [ ] Colors meet accessibility contrast requirements

Implementation Example ​

See think-tank-suite/src/components/backlog/__tests__/BurndownChart.test.tsx for a complete example.

Test coverage approach:

  • 20 unit tests for component logic
  • QA browser verification for visual correctness
  • E2E tests (future) for interactive behavior

Libraries Covered ​

This strategy applies to:

LibraryComponentTest Approach
RechartsBurndownChartUnit (logic) + QA (visual)
RechartsFuture chartsSame pattern
Chart.js(if used)Same pattern
D3.js(if used)Same pattern + E2E for interactions

References ​

Hello World DAO