---
name: strongtie-test
description: "Generate comprehensive test suites for React components with accessibility testing. Use when: (1) Creating tests for new components, (2) Adding tests to existing components, (3) Fixing failing tests."
---

# Test Generation Skill

Generate comprehensive test suites for React components following Simpson Strong-Tie patterns.

## When to Use This Skill

- Creating tests for new React components
- Adding tests to existing components
- Fixing failing tests
- Understanding test patterns

## Workflow Overview

1. **Analyze Component** - Understand props, variants, and behavior
2. **Create Test File** - In `tests/component-name.test.tsx`
3. **Write Rendering Tests** - Default and variant rendering
4. **Write Props Tests** - className, ref forwarding, prop spreading
5. **Write Interaction Tests** - Click, keyboard, focus
6. **Write Accessibility Tests** - vitest-axe, keyboard navigation

## Test File Structure

```typescript
import { render, screen } from "@testing-library/react"
import userEvent from "@testing-library/user-event"
import { axe } from "vitest-axe"
import { describe, expect, it, vi } from "vitest"
import { Component } from "@/components/component"

describe("Component", () => {
  // 1. Rendering tests
  describe("rendering", () => {
    it("renders correctly with default props", () => {...})
    it("renders with different variants", () => {...})
    it("renders children correctly", () => {...})
  })

  // 2. Props tests
  describe("props", () => {
    it("accepts and applies custom className", () => {...})
    it("forwards additional props", () => {...})
    it("forwards ref", () => {...})
  })

  // 3. Interaction tests
  describe("interactions", () => {
    it("handles click events", async () => {...})
    it("handles keyboard events", async () => {...})
  })

  // 4. Accessibility tests
  describe("accessibility", () => {
    it("should have no accessibility violations", async () => {...})
    it("should be focusable with keyboard", async () => {...})
  })
})
```

## Test Patterns

### Rendering Tests

```typescript
it("renders correctly with default props", () => {
  render(<Button>Click me</Button>)
  expect(screen.getByRole("button", { name: "Click me" })).toBeInTheDocument()
})

it("renders with different variants", () => {
  const { rerender } = render(<Button variant="default">Button</Button>)
  expect(screen.getByRole("button")).toHaveAttribute("data-variant", "default")
  
  rerender(<Button variant="destructive">Button</Button>)
  expect(screen.getByRole("button")).toHaveAttribute("data-variant", "destructive")
})
```

### Props Tests

```typescript
it("accepts and applies custom className", () => {
  render(<Button className="custom-class">Button</Button>)
  expect(screen.getByRole("button")).toHaveClass("custom-class")
  expect(screen.getByRole("button")).toHaveClass("button") // semantic class
})

it("forwards ref", () => {
  const ref = vi.fn()
  render(<Button ref={ref}>Button</Button>)
  expect(ref).toHaveBeenCalled()
})

it("forwards additional props", () => {
  render(<Button data-testid="test-button" aria-label="Test">Button</Button>)
  expect(screen.getByTestId("test-button")).toBeInTheDocument()
  expect(screen.getByRole("button")).toHaveAttribute("aria-label", "Test")
})
```

### Interaction Tests

```typescript
it("handles click events", async () => {
  const onClick = vi.fn()
  render(<Button onClick={onClick}>Click me</Button>)
  await userEvent.click(screen.getByRole("button"))
  expect(onClick).toHaveBeenCalledTimes(1)
})

it("does not trigger click when disabled", async () => {
  const onClick = vi.fn()
  render(<Button onClick={onClick} disabled>Click me</Button>)
  await userEvent.click(screen.getByRole("button"))
  expect(onClick).not.toHaveBeenCalled()
})

it("handles keyboard activation", async () => {
  const onClick = vi.fn()
  render(<Button onClick={onClick}>Press me</Button>)
  screen.getByRole("button").focus()
  await userEvent.keyboard("{Enter}")
  expect(onClick).toHaveBeenCalledTimes(1)
})
```

### Accessibility Tests

```typescript
it("should have no accessibility violations", async () => {
  const { container } = render(<Button>Accessible Button</Button>)
  const results = await axe(container)
  expect(results.violations).toHaveLength(0)
})

it("should be focusable with keyboard", async () => {
  render(<Button>Focus me</Button>)
  await userEvent.tab()
  expect(screen.getByRole("button")).toHaveFocus()
})

it("should have visible focus indicator", async () => {
  render(<Button>Focus me</Button>)
  await userEvent.tab()
  const button = screen.getByRole("button")
  expect(button).toHaveFocus()
  // Focus styles are applied via CSS, verify element is focusable
})
```

## Composite Component Tests

For components with sub-components (Card, Alert, etc.):

```typescript
describe("Card", () => {
  it("renders all sub-components correctly", () => {
    render(
      <Card>
        <CardHeader>
          <CardTitle>Title</CardTitle>
          <CardDescription>Description</CardDescription>
        </CardHeader>
        <CardContent>Content</CardContent>
        <CardFooter>Footer</CardFooter>
      </Card>
    )
    
    expect(screen.getByText("Title")).toBeInTheDocument()
    expect(screen.getByText("Description")).toBeInTheDocument()
    expect(screen.getByText("Content")).toBeInTheDocument()
    expect(screen.getByText("Footer")).toBeInTheDocument()
  })

  it("applies semantic classes to all parts", () => {
    const { container } = render(
      <Card>
        <CardHeader>Header</CardHeader>
      </Card>
    )
    
    expect(container.querySelector(".card")).toBeInTheDocument()
    expect(container.querySelector(".card-header")).toBeInTheDocument()
  })
})
```

## Running Tests

```bash
# Run all tests
npm run test

# Run tests in watch mode
npm run test:watch

# Run tests with coverage
npm run test -- --coverage

# Run specific test file
npm run test -- tests/button.test.tsx
```

## Test Checklist

- [ ] Rendering tests for default props
- [ ] Rendering tests for all variants
- [ ] Props tests for className
- [ ] Props tests for ref forwarding
- [ ] Props tests for prop spreading
- [ ] Interaction tests for click/keyboard
- [ ] Accessibility tests with vitest-axe
- [ ] Keyboard navigation tests
- [ ] Disabled state tests (if applicable)
- [ ] Composite component tests (if applicable)

## Reference

- Test setup: `packages/design-system/vitest.setup.ts`
- Example tests: `packages/design-system/tests/button.test.tsx`
- Testing library docs: https://testing-library.com/docs/react-testing-library/intro
- vitest-axe docs: https://github.com/chaance/vitest-axe
