This document describes the comprehensive automated testing infrastructure for ObjectUI components and renderers. The tests are designed to automatically discover display, accessibility, and structural issues in UI components.
A suite of helper functions that provide automated checks for common display issues:
Renders a component from its schema definition for testing.
const { container } = renderComponent({
type: 'button',
label: 'Click Me',
});Validates accessibility attributes and identifies common a11y issues:
- Missing ARIA labels on interactive elements
- Missing form labels
- Missing alt attributes on images
Returns:
{
hasRole: boolean;
hasAriaLabel: boolean;
hasAriaDescribedBy: boolean;
issues: string[]; // List of detected issues
}Analyzes DOM structure for potential issues:
- Empty components
- Excessive nesting (>20 levels)
- Missing content
Returns:
{
hasContent: boolean;
isEmpty: boolean;
hasChildren: boolean;
nestedDepth: number;
issues: string[]; // List of detected issues
}Validates component styling:
- Class presence
- Tailwind CSS usage
- Inline styles
Returns:
{
hasClasses: boolean;
hasTailwindClasses: boolean;
hasInlineStyles: boolean;
classes: string[];
}Verifies component registration in ComponentRegistry:
- Component is registered
- Has configuration
- Has renderer function
- Has label and inputs
- Has default props
Returns:
{
isRegistered: boolean;
hasConfig: boolean;
hasRenderer: boolean;
hasLabel: boolean;
hasInputs: boolean;
hasDefaultProps: boolean;
config: any;
}Comprehensive check that runs all validation checks and returns aggregated issues:
const issues = getAllDisplayIssues(container);
// Returns array of issue descriptionsThe test suite covers all major component categories:
-
Basic Components (
basic-renderers.test.tsx)- Text, Div, Span, Image, Icon, Separator, HTML
-
Form Components (
form-renderers.test.tsx)- Button, Input, Textarea, Select, Checkbox, Switch
- Radio Group, Slider, Label, Email, Password
-
Layout Components (
layout-data-renderers.test.tsx)- Container, Grid, Flex
-
Data Display Components (
layout-data-renderers.test.tsx)- List, Tree View, Badge, Avatar, Alert
- Breadcrumb, Statistic, Kbd
-
Feedback Components (
feedback-overlay-renderers.test.tsx)- Loading, Spinner, Progress, Skeleton, Empty, Toast
-
Overlay Components (
feedback-overlay-renderers.test.tsx)- Dialog, Alert Dialog, Sheet, Drawer
- Popover, Tooltip, Dropdown Menu, Context Menu
- Hover Card, Menubar
-
Disclosure Components (
complex-disclosure-renderers.test.tsx)- Accordion, Collapsible, Toggle Group
-
Complex Components (
complex-disclosure-renderers.test.tsx)- Timeline, Data Table, Chatbot, Carousel
- Scroll Area, Resizable, Filter Builder, Calendar View, Table
Every component should be properly registered:
it('should be properly registered', () => {
const validation = validateComponentRegistration('button');
expect(validation.isRegistered).toBe(true);
expect(validation.hasConfig).toBe(true);
expect(validation.hasLabel).toBe(true);
});Components should render without throwing errors:
it('should render without issues', () => {
const { container } = renderComponent({
type: 'button',
label: 'Test',
});
expect(container).toBeDefined();
});Components should be accessible:
it('should have proper accessibility', () => {
const { container } = renderComponent({
type: 'button',
label: 'Click Me',
});
const issues = getAllDisplayIssues(container);
const a11yIssues = issues.filter(i => i.includes('accessible'));
expect(a11yIssues).toHaveLength(0);
});Components should have valid DOM structure:
it('should have valid structure', () => {
const { container } = renderComponent({
type: 'container',
body: [{ type: 'text', content: 'Content' }],
});
const domCheck = checkDOMStructure(container);
expect(domCheck.hasContent).toBe(true);
expect(domCheck.isEmpty).toBe(false);
expect(domCheck.nestedDepth).toBeLessThan(20);
});Components should support their documented props:
it('should support variants', () => {
const variants = ['default', 'secondary', 'destructive'];
variants.forEach(variant => {
const { container } = renderComponent({
type: 'button',
label: 'Test',
variant,
});
expect(container).toBeDefined();
});
});pnpm testpnpm vitest run packages/components/src/__tests__/pnpm vitest run packages/components/src/__tests__/form-renderers.test.tsxpnpm test:watchpnpm test:coveragepnpm test:uiCurrent test coverage:
- 150 total tests across all component categories
- 140 passing (93% pass rate)
- 10 failing - identifying real schema/prop mismatches that need fixing
The failing tests are valuable as they automatically discovered:
- Components with missing props
- Schema mismatches (e.g.,
contentvshtml,textvscontent) - Missing default values
- Incorrect prop expectations
When adding a new component, create tests following this pattern:
describe('MyComponent Renderer', () => {
it('should be properly registered', () => {
const validation = validateComponentRegistration('my-component');
expect(validation.isRegistered).toBe(true);
expect(validation.hasConfig).toBe(true);
});
it('should render without issues', () => {
const { container } = renderComponent({
type: 'my-component',
// ... required props
});
expect(container).toBeDefined();
const issues = getAllDisplayIssues(container);
expect(issues).toHaveLength(0);
});
it('should support required props', () => {
const { container } = renderComponent({
type: 'my-component',
requiredProp: 'value',
});
expect(container.textContent).toContain('value');
});
});Add specific checks for known issues:
it('should not have excessive nesting', () => {
const { container } = renderComponent({
type: 'complex-component',
data: complexData,
});
const domCheck = checkDOMStructure(container);
expect(domCheck.nestedDepth).toBeLessThan(20);
});
it('should have proper ARIA attributes', () => {
const { container } = renderComponent({
type: 'interactive-component',
});
const button = container.querySelector('button');
const a11y = checkAccessibility(button);
expect(a11y.issues).toHaveLength(0);
});This testing infrastructure provides:
- Automated Issue Detection - Tests automatically find display and accessibility issues
- Regression Prevention - Catches breaking changes in component rendering
- Documentation - Tests serve as examples of how components should be used
- Confidence - High test coverage ensures components work as expected
- Quick Feedback - Fast test execution helps during development
Potential improvements:
- Visual regression testing with screenshot comparison
- Performance benchmarking for complex components
- Cross-browser testing
- Responsive design testing
- Theme variation testing
- Integration tests with SchemaRenderer