# Component Test-Driven Development Loop ## Principle Start every UI change with a failing component test (`cy.mount`, Playwright component test, or RTL `render`). Follow the Red-Green-Refactor cycle: write a failing test (red), make it pass with minimal code (green), then improve the implementation (refactor). Ship only after the cycle completes. Keep component tests under 100 lines, isolated with fresh providers per test, and validate accessibility alongside functionality. ## Rationale Component TDD provides immediate feedback during development. Failing tests (red) clarify requirements before writing code. Minimal implementations (green) prevent over-engineering. Refactoring with passing tests ensures changes don't break functionality. Isolated tests with fresh providers prevent state bleed in parallel runs. Accessibility assertions catch usability issues early. Visual debugging (Cypress runner, Storybook, Playwright trace viewer) accelerates diagnosis when tests fail. ## Pattern Examples ### Example 1: Red-Green-Refactor Loop **Context**: When building a new component, start with a failing test that describes the desired behavior. Implement just enough to pass, then refactor for quality. **Implementation**: ```typescript // Step 1: RED - Write failing test // Button.cy.tsx (Cypress Component Test) import { Button } from './Button'; describe('Button Component', () => { it('should render with label', () => { cy.mount(; }; // Run test: PASSES - Component renders and handles clicks // Step 3: REFACTOR - Improve implementation // Add disabled state, loading state, variants type ButtonProps = { label: string; onClick?: () => void; disabled?: boolean; loading?: boolean; variant?: 'primary' | 'secondary' | 'danger'; }; export const Button = ({ label, onClick, disabled = false, loading = false, variant = 'primary' }: ButtonProps) => { return ( ); }; // Step 4: Expand tests for new features describe('Button Component', () => { it('should render with label', () => { cy.mount(