Claude
Skills
Sign in
Back

typescript-component-testing

Included with Lifetime
$97 forever

Jest, Vitest, and React Testing Library patterns for component testing. PROACTIVELY activate for: (1) Writing React component tests, (2) Using Testing Library queries, (3) Testing user interactions, (4) Async component testing, (5) Accessibility-focused testing. Triggers: "jest", "vitest", "testing-library", "react test", "component test", "render", "screen", "userEvent"

Design

What this skill does


# TypeScript Component Testing Skill

## Metadata (Tier 1)

**Keywords**: jest, vitest, testing-library, react, component test, render

**File Patterns**: *.test.tsx, *.spec.ts, *.test.js

**Modes**: testing_frontend

---

## Instructions (Tier 2)

### React Testing Library Philosophy

**Core Principle**: Test from user's perspective, not implementation

### Query Priority
1. `getByRole` (accessible roles)
2. `getByLabelText` (form elements)
3. `getByPlaceholderText`
4. `getByText`
5. `getByTestId` (last resort)

### Basic Test Pattern

```typescript
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

test('submits login form', async () => {
  const handleSubmit = jest.fn();
  render(<LoginForm onSubmit={handleSubmit} />);

  await userEvent.type(screen.getByLabelText(/email/i), '[email protected]');
  await userEvent.type(screen.getByLabelText(/password/i), 'password123');
  await userEvent.click(screen.getByRole('button', { name: /log in/i }));

  expect(handleSubmit).toHaveBeenCalledWith({
    email: '[email protected]',
    password: 'password123'
  });
});
```

### Async Testing

```typescript
test('loads and displays data', async () => {
  render(<UserProfile userId="123" />);

  // Wait for data to load
  expect(await screen.findByText('John Doe')).toBeInTheDocument();
});

// Or with waitFor
await waitFor(() => {
  expect(screen.getByText('John Doe')).toBeInTheDocument();
});
```

### User Interactions (userEvent)

```typescript
// Preferred: userEvent (realistic)
await userEvent.click(button);
await userEvent.type(input, 'text');
await userEvent.selectOptions(select, ['option1']);

// Avoid: fireEvent (low-level)
fireEvent.click(button);
```

### Anti-Patterns

- Testing implementation details (state, methods)
- Using container.querySelector
- Not waiting for async updates
- Manually wrapping in act()

Related in Design