
frontend-testing
Generate Vitest + React Testing Library tests for frontend components, hooks, and utilities. Triggers on testing, spec files, coverage, Vitest, RTL, unit tests, integration tests, or write/review test requests.
- Installs
- 71
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/pageai-pro/ralph-loop --skill frontend-testing- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads frontend-testing automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
This skill enables Claude to generate high-quality, comprehensive frontend tests following established conventions and best practices.
When to Apply This Skill
Apply this skill when the user:
- Asks to write tests for a component, hook, or utility
- Asks to review existing tests for completeness
- Mentions Vitest, React Testing Library, RTL, or spec files
- Requests test coverage improvement
- Mentions testing, unit tests, or integration tests for frontend code
- Wants to understand testing patterns in the frontend codebase
Do NOT apply when:
- User is asking about E2E tests (Playwright)
- User is only asking conceptual questions without code context
Quick Reference
Tech Stack
| Tool | Version | Purpose |
|---|---|---|
| Vitest | 4+ | Test runner |
| React Testing Library | 16+ | Component testing |
| jsdom | - | Test environment |
| TypeScript | 5+ | Type safety |
Note: keep this list up to date with the project's dependencies.
Key Commands
Always prefer running specific tests over the entire suite for faster feedback:
# Run ALL tests (avoid during development)
npx vitest run
# ✅ PREFERRED: Run specific file
npx vitest run src/components/Button.spec.tsx
# ✅ PREFERRED: Run tests matching a pattern
npx vitest run --grep "Button"
npx vitest run -t "should render"
# ✅ PREFERRED: Run specific describe block
npx vitest run --grep "Button > Rendering"
# ✅ Run tests in a directory
npx vitest run src/components/
# ✅ Run single test by name
npx vitest run -t "should disable button when loading"
Watch Mode (Background Testing)
Use watch mode for efficient iterative development:
# ✅ Watch mode - reruns on file changes
npx vitest
# ✅ Watch specific file
npx vitest src/components/Button.spec.tsx
# ✅ Watch tests matching pattern
npx vitest --grep "Button"
File Naming
- Test files:
ComponentName.spec.tsx(same directory as component)
Test Structure Template
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import Component from './index'
// ✅ Import real project components (DO NOT mock these)
// import Loading from '@/app/components/base/loading'
// import { ChildComponent } from './child-component'
// ✅ Mock external dependencies only
vi.mock('@/service/api')
vi.mock('next/navigation', () => ({
useRouter: () => ({ push: vi.fn() }),
usePathname: () => '/test',
}))
// Shared state for mocks (if needed)
let mockSharedState = false
describe('ComponentName', () => {
beforeEach(() => {
vi.clearAllMocks() // ✅ Reset mocks BEFORE each test
mockSharedState = false // ✅ Reset shared state
})
// Rendering tests (REQUIRED)
describe('Rendering', () => {
it('should render without crashing', () => {
// Arrange
const props = { title: 'Test' }
// Act
render(<Component {...props} />)
// Assert
expect(screen.getByText('Test')).toBeInTheDocument()
})
})
// Props tests (REQUIRED)
describe('Props', () => {
it('should apply custom className', () => {
render(<Component className="custom" />)
expect(screen.getByRole('button')).toHaveClass('custom')
})
})
// User Interactions
describe('User Interactions', () => {
it('should handle click events', () => {
const handleClick = vi.fn()
render(<Component onClick={handleClick} />)
fireEvent.click(screen.getByRole('button'))
expect(handleClick).toHaveBeenCalledTimes(1)
})
})
// Edge Cases (REQUIRED)
describe('Edge Cases', () => {
it('should handle null data', () => {
render(<Component data={null} />)
expect(screen.getByText(/no data/i)).toBeInTheDocument()
})
it('should handle empty array', () => {
render(<Component items={[]} />)
expect(screen.getByText(/empty/i)).toBeInTheDocument()
})
})
})
Testing Workflow (CRITICAL)
⚠️ Incremental Approach Required
NEVER generate all test files at once. For complex components or multi-file directories:
- Analyze & Plan: List all files, order by complexity (simple → complex)
- Process ONE at a time: Write test → Run test → Fix if needed → Next
- Verify before proceeding: Do NOT continue to next file until current passes
For each file:
┌────────────────────────────────────────────────┐
│ 1. Write test │
│ 2. Run: npm run test-unit <file>.spec.tsx │
│ 3. PASS? → Mark complete, next file │
│ FAIL? → Fix first, then continue │
└────────────────────────────────────────────────┘
Complexity-Based Order
Process in this order for multi-file testing:
- 🟢 Utility functions (simplest)
- 🟢 Custom hooks
- 🟡 Simple components (presentational)
- 🟡 Medium components (state, effects)
- 🔴 Complex components (API, routing)
- 🔴 Integration tests (index files - last)
When to Refactor First
- Medium Complexity: Break into smaller pieces before testing
- 500+ lines: Consider splitting before testing
- Many dependencies: Extract logic into hooks first
Testing Strategy
Path-Level Testing (Directory Testing)
When assigned to test a directory/path, test ALL content within that path:
- Test all components, hooks, utilities in the directory (not just
indexfile) - Use incremental approach: one file at a time, verify each before proceeding
- Goal: 100% coverage of ALL files in the directory
Integration Testing First
Prefer integration testing when writing tests for a directory:
- ✅ Import real project components directly (including base components and siblings)
- ✅ Only mock: API services (
@/service/*),next/navigation, complex context providers - ❌ DO NOT mock base components (
@/app/components/base/*) - ❌ DO NOT mock sibling/child components in the same directory
Core Principles
1. AAA Pattern (Arrange-Act-Assert)
Every test should clearly separate:
- Arrange: Setup test data and render component
- Act: Perform user actions
- Assert: Verify expected outcomes
2. Black-Box Testing
- Test observable behavior, not implementation details
- Use semantic queries (getByRole, getByLabelText)
- Avoid testing internal state directly
- Prefer pattern matching over hardcoded strings in assertions:
// ❌ Avoid: hardcoded text assertions
expect(screen.getByText('Loading...')).toBeInTheDocument()
// ✅ Better: role-based queries
expect(screen.getByRole('status')).toBeInTheDocument()
// ✅ Better: pattern matching
expect(screen.getByText(/loading/i)).toBeInTheDocument()
3. Single Behavior Per Test
Each test verifies ONE user-observable behavior:
// ✅ Good: One behavior
it('should disable button when loading', () => {
render(<Button loading />)
expect(screen.getByRole('button')).toBeDisabled()
})
// ❌ Bad: Multiple behaviors
it('should handle loading state', () => {
render(<Button loading />)
expect(screen.getByRole('button')).toBeDisabled()
expect(screen.getByText('Loading...')).toBeInTheDocument()
expect(screen.getByRole('button')).toHaveClass('loading')
})
4. Semantic Naming
Use should <behavior> when <condition>:
it('should show error message when validation fails')
it('should call onSubmit when form is valid')
it('should disable input when isReadOnly is true')
Required Test Scenarios
Always Required (All Components)
- Rendering: Component renders without crashing
- Props: Required props, optional props, default values
- Edge Cases: null, undefined, empty values, boundary conditions
Conditional (When Present)
| Feature | Test Focus |
|---|---|
useState | Initial state, transitions, cleanup |
useEffect | Execution, dependencies, cleanup |
| Event handlers | All onClick, onChange, onSubmit, keyboard |
| API calls | Loading, success, error states |
| Routing | Navigation, params, query strings |
useCallback/useMemo | Referential equality |
| Context | Provider values, consumer behavior |
| Forms | Validation, submission, error display |
Coverage Goals (Per File)
For each test file generated, aim for:
- ✅ 100% function coverage
- ✅ 100% statement coverage
- ✅ >95% branch coverage
- ✅ >95% line coverage
Note: For multi-file directories, process one file at a time with full coverage each. See
references/workflow.md.
Detailed Guides
For more detailed information, refer to:
references/workflow.md- Incremental testing workflow (MUST READ for multi-file testing)references/mocking.md- Mock patterns and best practicesreferences/async-testing.md- Async operations and API callsreferences/common-patterns.md- Frequently used testing patternsreferences/checklist.md- Test generation checklist and validation steps
Project Configuration
vitest.config.ts- Vitest configurationvitest.setup.ts- Test environment setup- Modules are not mocked automatically. Global mocks live in
vitest.setup.ts(for examplereact-i18next,next/image); mock other modules likekyormimelocally in test files.
FAQ
What does the frontend-testing skill do?
Generate Vitest + React Testing Library tests for frontend components, hooks, and utilities. Triggers on testing, spec files, coverage, Vitest, RTL, unit tests, integration tests, or write/review test requests.
How do I install frontend-testing?
Run npx skills add https://github.com/pageai-pro/ralph-loop --skill frontend-testing in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/frontend-testing/ (personal) or .claude/skills/frontend-testing/ (project).
Which AI agents can use frontend-testing?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is frontend-testing safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains frontend-testing?
It is published by pageai-pro in pageai-pro/ralph-loop. It has 71 recorded installs.
More from pageai-pro/ralph-loop
prd-creator
pageai-pro/ralph-loop
Guides creation of comprehensive Product Requirement Documents (PRDs) for software projects through structured questioning and validation, then generates implementation task lists in JSON format. Use when users want to document a software idea, create specifications for development, plan a new application feature/bug, or break down requirements into actionable tasks. Transforms ideas into implementation-ready documents with verifiable pass criteria.
vitest-best-practices
pageai-pro/ralph-loop
Comprehensive vitest testing patterns covering test structure, AAA pattern, parameterized tests, assertions, mocking, test doubles, error handling, async testing, and performance optimization. Use when writing, reviewing, or refactoring vitest tests, or when user mentions vitest, testing, TDD, test coverage, mocking, assertions, or test files (.test.ts, .spec.ts).
e2e-tester
pageai-pro/ralph-loop
Open the skill to read its SKILL.md instructions.
frontend-code-review
pageai-pro/ralph-loop
Trigger when the user requests a review of frontend files (e.g., .tsx, .ts, .js). Support both pending-change reviews and focused file reviews while applying the checklist rules.
component-refactoring
pageai-pro/ralph-loop
Refactor high-complexity React components in frontend. Use when the user asks for code splitting, hook extraction, or complexity reduction, or when you come across a component that is too complex to understand and refactor it.
mysql
pageai-pro/ralph-loop
Open the skill to read its SKILL.md instructions.
Popular testing & qa skills
tdd
mattpocock/skills
Test-driven development. Use when the user wants to build features or fix bugs test-first, mentions "red-green-refactor", or wants integration tests.
grilling
mattpocock/skills
Grill the user relentlessly about a plan, decision, or idea. Use when the user wants to stress-test their thinking, or uses any 'grill' trigger phrases.
migrate-to-shoehorn
mattpocock/skills
Migrate test files from as type assertions to @total-typescript/shoehorn. Use when user mentions shoehorn, wants to replace as in tests, or needs partial test data.
run-train
lllllllama/rigorpilot-skills
Rigor Train skill for deep learning research repositories. Use when a documented or selected training command should be run conservatively for startup verification, short-run verification, full kickoff, or resume, with command, config, seed, log, checkpoint, status, and metric evidence written to standardized trainoutputs/. Do not use for environment setup, exploratory sweeps, speculative idea implementation, or end-to-end orchestration.
test-driven-development
obra/superpowers
Use when implementing any feature or bugfix, before writing implementation code
finishing-a-development-branch
obra/superpowers
Use when implementation is complete, all tests pass, and you need to decide how to integrate the work