Files
Parsons/.claude/skills/write-tests/SKILL.md
Richie aa7cdeecf0 Add workflow infrastructure — ESLint, Prettier, Husky, Vitest, 7 new skills
Phase 1: Session log archived (1096→91 lines), D031 token access convention
Phase 2: ESLint v9 + Prettier + jsx-a11y, initial config and lint fixes
Phase 3: 7 new skills (polish, harden, normalize, clarify, typeset, quieter, adapt)
         + Vercel reference docs, updated audit/review-component refs
Phase 4: Husky + lint-staged pre-commit hooks, preflight updated to 8 checks
Phase 5: Vitest + Testing Library + /write-tests skill

- Badge.tsx colour maps unified to CSS variables (D031)
- 5 empty interface→type alias fixes (Switch, Radio, Divider, IconButton, Link)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:41:57 +11:00

3.8 KiB

name, description, user-invocable, argument-hint
name description user-invocable argument-hint
write-tests Write or update tests for a component — determines whether it needs unit tests (Vitest), interaction tests (Storybook play), or both, then generates appropriate test code. true [ComponentName]

Write tests for the specified component.

Component: $ARGUMENTS

Preparation

  1. Read docs/conventions/component-conventions.md for component patterns
  2. Read the component source file in src/components/
  3. Read the component's existing Storybook stories
  4. Check docs/memory/component-registry.md for component status and composition

Determine Test Strategy

Categorise the component:

Interactive components (need Storybook play functions)

Components with user interactions: clicks, toggles, keyboard navigation, form inputs, selection state changes.

Examples: Button, Input, SearchBar, ServiceOption, AddOnOption, Switch, Radio, FuneralFinder

For these, add play functions to existing stories:

import { expect, userEvent, within } from '@storybook/test';

export const ClickTest: Story = {
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);
    const button = canvas.getByRole('button');
    await userEvent.click(button);
    await expect(button).toBeVisible();
  },
};

What to test in play functions:

  • Click/tap fires expected callback
  • Disabled state prevents interaction
  • Keyboard navigation works (Enter, Space, Arrow keys)
  • Loading state disables interaction
  • Error states show correct feedback
  • Selection state changes visually
  • Form validation triggers on submit

Logic-heavy components (need Vitest unit tests)

Components with significant internal logic: conditional rendering, validation, state machines, computed values.

Examples: FuneralFinder (validation logic), PackageDetail (price calculations), ServiceSelector (selection management)

Create {ComponentName}.test.tsx alongside the component:

import { describe, it, expect } from 'vitest';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { ThemeProvider } from '@mui/material/styles';
import theme from '../../../theme';
import { ComponentName } from './ComponentName';

const renderWithTheme = (ui: React.ReactElement) =>
  render(<ThemeProvider theme={theme}>{ui}</ThemeProvider>);

describe('ComponentName', () => {
  it('renders with default props', () => {
    renderWithTheme(<ComponentName />);
    expect(screen.getByRole('...')).toBeInTheDocument();
  });
});

What to test in Vitest:

  • Conditional rendering logic (shows/hides elements based on props)
  • Validation rules (required fields, format checks)
  • Callback props fire with correct arguments
  • Accessibility: correct ARIA roles and states
  • Edge cases: empty data, maximum values, missing optional props

Display-only components (minimal testing needed)

Components that only render static content from props: Typography, Badge, Divider, Card (non-interactive).

For these, stories ARE the tests. Ensure stories cover all variants. No additional test files needed unless there's conditional rendering logic.

After Writing Tests

  1. Run npm run test to verify Vitest tests pass
  2. If Storybook play functions were added, verify they work in Storybook's test panel
  3. Update docs/memory/component-registry.md with test status note

Rules

  • Always wrap components in ThemeProvider with FA theme in Vitest tests
  • Use screen.getByRole() over getByTestId() — test what the user sees
  • Test behaviour, not implementation — don't test internal state directly
  • Keep tests focused: one assertion per test where practical
  • Don't test MUI internals — only test our component's API
  • Don't snapshot test — snapshots are too brittle for an evolving design system