Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
27 changes: 27 additions & 0 deletions .claude/skills/pipeline-rules/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
name: pipeline-rules
description: Frontend (Next.js/TypeScript) lint, format, test, and build checks that mirror what CI enforces on this repo — ESLint, Prettier, Vitest, and a Next build. Use whenever files under web/ are added, edited, or reviewed, before considering the work done.
metadata:
type: workflow
when_to_use: "finishing a frontend change, editing a file under web/, before saying a frontend task is done, reviewing a TS/TSX diff, formatting check, eslint, prettier, vitest, next build"
---

# Frontend pipeline rules

Before treating any task that touches files under `web/` as finished, run the same checks CI would run — in this order, from the `web/` directory:

1. **Format** — `pnpm format`
Auto-fixes via Prettier. Use `pnpm format:check` instead if you only want to verify without rewriting files.

2. **Lint** — `pnpm lint`
Runs ESLint. Fix everything it reports rather than leaving it for CI to catch.

3. **Test** — `pnpm test`
Runs the Vitest suite. Scope it to the affected files when the full run is slow and the change is narrow.

4. **Build** — `pnpm build`
Run this when the change is nontrivial or touches shared types/config — the Next build's type-checking catches errors that lint and unit tests don't.

Format first, then lint, then test/build — formatting can shift lines lint doesn't care about, but do it before the final checks so the diff you hand back is already clean.

Run this for every frontend change, not only ones that look formatting-related. Code that runs correctly locally but isn't linted, formatted, or type-clean still fails CI.
143 changes: 143 additions & 0 deletions .claude/skills/react-testing-library/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# React Testing Library Best Practices

A comprehensive skill for writing maintainable, user-centric tests with React Testing Library.

## Overview

This skill contains 43 rules across 9 categories, prioritized by impact to guide test writing and code review. It covers query selection, async handling, user interactions, assertions, and common anti-patterns.

### Structure

```
react-testing-library/
├── SKILL.md # Entry point with quick reference
├── metadata.json # Version, org, references
├── README.md # This file
├── references/
│ ├── _sections.md # Category definitions
│ ├── query-*.md # Query selection rules (CRITICAL)
│ ├── async-*.md # Async handling rules (CRITICAL)
│ ├── anti-*.md # Anti-pattern rules (CRITICAL)
│ ├── user-*.md # User interaction rules (HIGH)
│ ├── assert-*.md # Assertion rules (HIGH)
│ ├── setup-*.md # Component setup rules (MEDIUM)
│ ├── struct-*.md # Test structure rules (MEDIUM)
│ ├── debug-*.md # Debugging rules (LOW-MEDIUM)
│ └── a11y-*.md # Accessibility rules (LOW)
└── assets/
└── templates/
└── _template.md # Template for new rules
```

## Getting Started

```bash
# Install dependencies (if in a project with validation scripts)
pnpm install

# Build compiled documents
pnpm build

# Validate skill structure
pnpm validate
```

## Creating a New Rule

1. Choose the appropriate category prefix based on the rule's focus area
2. Create a new file in `references/` with the naming pattern `{prefix}-{description}.md`
3. Copy the template from `assets/templates/_template.md`
4. Fill in all required sections

### Prefix Reference

| Prefix | Category | Impact |
| --------- | --------------------- | ---------- |
| `query-` | Query Selection | CRITICAL |
| `async-` | Async Handling | CRITICAL |
| `anti-` | Common Anti-Patterns | CRITICAL |
| `user-` | User Interaction | HIGH |
| `assert-` | Assertions | HIGH |
| `setup-` | Component Setup | MEDIUM |
| `struct-` | Test Structure | MEDIUM |
| `debug-` | Debugging | LOW-MEDIUM |
| `a11y-` | Accessibility Testing | LOW |

## Rule File Structure

Each rule file must include:

````markdown
---
title: Rule Title Here
impact: CRITICAL|HIGH|MEDIUM|LOW-MEDIUM|LOW
impactDescription: Quantified impact (e.g., "2-10× improvement")
tags: category-prefix, technique, tool, concept
---

## Rule Title Here

Brief explanation of WHY this matters.

**Incorrect (what's wrong):**

```tsx
// Bad code example
```
````

**Correct (what's right):**

```tsx
// Good code example
```

Reference: [Source](URL)

```

## File Naming Convention

Rule files follow the pattern: `{prefix}-{description}.md`

- **prefix**: 3-8 character category identifier (e.g., `query`, `async`, `anti`)
- **description**: kebab-case description of the rule (e.g., `prefer-role`, `await-findby`)

Examples:

- `query-prefer-role.md` - Query selection rule about preferring getByRole
- `async-await-findby.md` - Async handling rule about awaiting findBy queries
- `anti-container-queries.md` - Anti-pattern rule about avoiding container queries

## Impact Levels

| Level | Description |
|-------|-------------|
| **CRITICAL** | Fundamental issues that cause test failures, false positives, or major maintenance burden |
| **HIGH** | Important patterns that significantly improve test quality and reliability |
| **MEDIUM** | Good practices that improve maintainability and readability |
| **LOW-MEDIUM** | Helpful patterns for specific situations |
| **LOW** | Nice-to-have improvements and advanced techniques |

## Scripts

| Command | Description |
|---------|-------------|
| `pnpm build` | Generate AGENTS.md compiled document |
| `pnpm validate` | Check skill structure against guidelines |
| `pnpm validate --strict` | Fail on warnings as well as errors |

## Contributing

1. Read existing rules to understand the expected format and quality
2. Follow the template structure exactly
3. Include realistic code examples (avoid `foo`, `bar`, generic names)
4. Quantify impact where possible (e.g., "2-10× improvement", "prevents X")
5. Run validation before submitting

## Acknowledgments

- [Testing Library](https://testing-library.com) - Official documentation
- [Kent C. Dodds](https://kentcdodds.com) - Creator guidance and best practices
- [jest-dom](https://github.com/testing-library/jest-dom) - Custom matchers
```
128 changes: 128 additions & 0 deletions .claude/skills/react-testing-library/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
---
name: react-testing-library
description: React Testing Library mechanics for testing React components and hooks — query selection, async handling, user interaction, assertions, provider setup, and the anti-patterns that make tests brittle. Use for any test that renders a React component or a hook, including choosing between getBy/queryBy/findBy, userEvent flows, waitFor usage, renderHook, custom render wrappers, and reviewing RTL tests for implementation-detail assertions.
metadata:
version: "1.1.0"
tags: "react, testing, rtl, components, hooks"
author: Ship Shit Dev
when_to_use: "test a React component, test a React hook, render a component in a test, getByRole, getByLabelText, queryBy vs getBy, findBy, waitFor, userEvent, fireEvent, renderHook, custom render with providers, screen.debug, my component test is brittle, review these RTL tests, testing-library anti-patterns"
---

# React Testing Library Best Practices

43 rules across 9 categories for testing React components with Testing Library, prioritized by impact to guide test writing and code review.

## Scope

This skill owns React component and hook testing mechanics. For
framework-agnostic questions — which level a behavior belongs at, what a coverage
number means, how to choose test data, how to kill a flake — use
`testing-expert`.

## When to Apply

- Writing new component tests with React Testing Library
- Selecting queries (getByRole, getByLabelText, etc.)
- Handling async operations in tests (findBy, waitFor)
- Simulating user interactions (userEvent)
- Reviewing tests for anti-patterns and implementation detail testing

## Rule Categories by Priority

| Priority | Category | Impact | Prefix |
| -------- | --------------------- | ---------- | --------- |
| 1 | Query Selection | CRITICAL | `query-` |
| 2 | Async Handling | CRITICAL | `async-` |
| 3 | Common Anti-Patterns | CRITICAL | `anti-` |
| 4 | User Interaction | HIGH | `user-` |
| 5 | Assertions | HIGH | `assert-` |
| 6 | Component Setup | MEDIUM | `setup-` |
| 7 | Test Structure | MEDIUM | `struct-` |
| 8 | Debugging | LOW-MEDIUM | `debug-` |
| 9 | Accessibility Testing | LOW | `a11y-` |

## Quick Reference

### 1. Query Selection (CRITICAL)

- [`query-prefer-role`](references/query-prefer-role.md) - Prefer getByRole over other queries
- [`query-avoid-testid`](references/query-avoid-testid.md) - Avoid getByTestId as primary query
- [`query-use-screen`](references/query-use-screen.md) - Use screen for queries
- [`query-label-text-forms`](references/query-label-text-forms.md) - Use getByLabelText for form fields
- [`query-role-name-option`](references/query-role-name-option.md) - Use name option with getByRole
- [`query-get-vs-query`](references/query-get-vs-query.md) - Use getBy for present, queryBy for absent
- [`query-within-scope`](references/query-within-scope.md) - Use within() to scope queries

### 2. Async Handling (CRITICAL)

- [`async-findby-over-waitfor`](references/async-findby-over-waitfor.md) - Use findBy instead of waitFor + getBy
- [`async-await-findby`](references/async-await-findby.md) - Always await findBy queries
- [`async-single-assertion-waitfor`](references/async-single-assertion-waitfor.md) - Single assertion in waitFor
- [`async-no-side-effects-waitfor`](references/async-no-side-effects-waitfor.md) - Avoid side effects in waitFor
- [`async-waitfor-disappear`](references/async-waitfor-disappear.md) - Use waitForElementToBeRemoved

### 3. Common Anti-Patterns (CRITICAL)

- [`anti-unnecessary-act`](references/anti-unnecessary-act.md) - Avoid unnecessary act() wrapping
- [`anti-manual-cleanup`](references/anti-manual-cleanup.md) - Remove manual cleanup calls
- [`anti-implementation-details`](references/anti-implementation-details.md) - Avoid testing implementation details
- [`anti-empty-waitfor`](references/anti-empty-waitfor.md) - Avoid empty waitFor callbacks
- [`anti-container-queries`](references/anti-container-queries.md) - Avoid using container for queries
- [`anti-redundant-roles`](references/anti-redundant-roles.md) - Avoid adding redundant ARIA roles

### 4. User Interaction (HIGH)

- [`user-prefer-userevent`](references/user-prefer-userevent.md) - Use userEvent over fireEvent
- [`user-setup-before-render`](references/user-setup-before-render.md) - Setup userEvent before render
- [`user-await-interactions`](references/user-await-interactions.md) - Always await userEvent interactions
- [`user-keyboard-for-special-keys`](references/user-keyboard-for-special-keys.md) - Use keyboard() for special keys
- [`user-clear-before-type`](references/user-clear-before-type.md) - Use clear() before retyping

### 5. Assertions (HIGH)

- [`assert-jest-dom-matchers`](references/assert-jest-dom-matchers.md) - Use jest-dom matchers
- [`assert-visible-over-in-document`](references/assert-visible-over-in-document.md) - Use toBeVisible() for visibility
- [`assert-text-content`](references/assert-text-content.md) - Use toHaveTextContent() for text
- [`assert-have-value`](references/assert-have-value.md) - Use toHaveValue() for inputs
- [`assert-accessible-description`](references/assert-accessible-description.md) - Use toHaveAccessibleDescription()

### 6. Component Setup (MEDIUM)

- [`setup-wrapper-providers`](references/setup-wrapper-providers.md) - Use wrapper option for providers
- [`setup-custom-render`](references/setup-custom-render.md) - Create custom render with providers
- [`setup-mock-modules`](references/setup-mock-modules.md) - Mock modules at module level
- [`setup-fake-timers`](references/setup-fake-timers.md) - Configure userEvent with fake timers
- [`setup-render-hook`](references/setup-render-hook.md) - Use renderHook for testing hooks

### 7. Test Structure (MEDIUM)

- [`struct-arrange-act-assert`](references/struct-arrange-act-assert.md) - Follow Arrange-Act-Assert pattern
- [`struct-one-behavior-per-test`](references/struct-one-behavior-per-test.md) - Test one behavior per test
- [`struct-descriptive-names`](references/struct-descriptive-names.md) - Use descriptive test names
- [`struct-avoid-beforeeach-render`](references/struct-avoid-beforeeach-render.md) - Avoid render() in beforeEach

### 8. Debugging (LOW-MEDIUM)

- [`debug-screen-debug`](references/debug-screen-debug.md) - Use screen.debug() to inspect DOM
- [`debug-logroles`](references/debug-logroles.md) - Use logRoles to find available roles
- [`debug-testing-playground`](references/debug-testing-playground.md) - Use Testing Playground for queries

### 9. Accessibility Testing (LOW)

- [`a11y-role-queries-verify`](references/a11y-role-queries-verify.md) - Role queries verify accessibility
- [`a11y-verify-focus`](references/a11y-verify-focus.md) - Test focus management
- [`a11y-test-aria-states`](references/a11y-test-aria-states.md) - Test ARIA states and properties

## How to Use

Read individual reference files for detailed explanations and code examples:

- [Section definitions](references/_sections.md) - Category structure and impact levels
- [Rule template](assets/templates/_template.md) - Template for adding new rules

## Reference Files

| File | Description |
| --------------------------------------------------------------- | --------------------------------- |
| [references/\_sections.md](references/_sections.md) | Category definitions and ordering |
| [assets/templates/\_template.md](assets/templates/_template.md) | Template for new rules |
42 changes: 42 additions & 0 deletions .claude/skills/react-testing-library/assets/templates/_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
title: Rule Title Here
impact: CRITICAL|HIGH|MEDIUM-HIGH|MEDIUM|LOW-MEDIUM|LOW
impactDescription: Quantified impact (e.g., "prevents flaky tests", "2-10× improvement")
tags: category-prefix, technique, tool, concept
---

## Rule Title Here

Brief explanation (1-3 sentences) of WHY this matters. Focus on testing implications and user confidence.

**Incorrect (what's wrong):**

```tsx
// Bad code example - production-realistic, not strawman
// Comment explaining the problem/cost
```

**Correct (what's right):**

```tsx
// Good code example - minimal diff from incorrect
// Comment explaining the benefit
```

**Alternative (context):**

```tsx
// Alternative approach when applicable
```

**When NOT to use this pattern:**

- Exception 1
- Exception 2

**Benefits:**

- Benefit 1
- Benefit 2

Reference: [Reference Title](URL)
12 changes: 12 additions & 0 deletions .claude/skills/react-testing-library/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "react-testing-library",
"version": "1.1.0",
"description": "React Testing Library mechanics for component and hook tests: queries, async, interaction.",
"author": {
"name": "Ship Shit Dev",
"email": "hello@shipshit.dev",
"url": "https://shipshit.dev"
},
"license": "MIT",
"skills": "."
}
Loading
Loading