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
Recommended Strategy
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 requirementsImplementation Example
See foundery-os-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:
| Library | Component | Test Approach |
|---|---|---|
| Recharts | BurndownChart | Unit (logic) + QA (visual) |
| Recharts | Future charts | Same pattern |
| Chart.js | (if used) | Same pattern |
| D3.js | (if used) | Same pattern + E2E for interactions |
References
- Recharts Testing Guide
- Playwright Visual Comparisons
- Testing Library Queries
- Source:
foundery-os-suite/src/components/backlog/__tests__/BurndownChart.test.tsx