frontend-testing
Skill795 starsChanged 2 months agoMITView on GitHub
Generate Vitest + React Testing Library tests for Dify frontend components, hooks, and utilities. Triggers on testing, spec files, coverage, Vitest, RTL, unit tests, integration tests, or write/review test requests.
We split this skill into the rules it gives an agent
14 rules. 0 are common, 12 are distinctive, and 2 are very specific to this project.
0
Common
Most of the 14 edited versions we read keep these.
12
Distinctive
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 24
Do NOT apply: when:
- Very specific: line 66
Test files: ComponentName.spec.tsx (same directory as component)
- Distinctive: line 154
Process ONE at a time: Write test → Run test → Fix if needed → Next
- Distinctive: line 155
Verify before proceeding: Do NOT continue to next file until current passes
- Distinctive: line 181
500+ lines: Consider splitting before testing
- Distinctive: line 190
When assigned to test a directory/path, test ALL content within that path:
- Very specific: line 192
Test all components, hooks, utilities in the directory (not just index file)
- Distinctive: line 193
Use incremental approach: one file at a time, verify each before proceeding
- Distinctive: line 198
Prefer integration testing: when writing tests for a directory:
- Distinctive: line 211
Every test should clearly separate:
- Distinctive: line 215
Assert: Verify expected outcomes
- Distinctive: line 219
Test observable behavior, not implementation details
- Distinctive: line 220
Use semantic queries (getByRole, getByLabelText)
- Distinctive: line 221
Avoid testing internal state directly
“Common” is measured: kept by at least 6 in 10 of the 14 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Dify Frontend Testing Skill
This skill enables Claude to generate high-quality, comprehensive frontend tests for the Dify project following established conventions and best practices.
⚠️ Authoritative Source: This skill is derived from
web/testing/testing.md. Use Vitest mock/timer APIs (vi.*).
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
- Uses
pnpm analyze-componentoutput as context - Mentions testing, unit tests, or integration tests for frontend code
- Wants to understand testing patterns in the Dify codebase
Do NOT apply when:
- User is asking about backend/API tests (Python/pytest)
- User is asking about E2E tests (Playwright/Cypress)
- User is only asking conceptual questions without code context
Quick Reference
Tech Stack
| Tool | Version | Purpose |
| Vitest | 4.0.16 | Test runner |
| React Testing Library | 16.0 | Component testing |
| jsdom | - | Test environment |
| nock | 14.0 | HTTP mocking |
| TypeScript | 5.x | Type safety |
Key Commands
# Run all tests
pnpm test
# Watch mode
pnpm test:watch
# Run specific file
pnpm test path/to/file.spec.tsx
# Generate coverage report
pnpm test:coverage
# Analyze component complexity
pnpm analyze-component <path>
# Review existing test
pnpm analyze-component <path> --reviewFile Naming
- Test files:
ComponentName.spec.tsx(same directory as component) - Integration tests:
web/__tests__/directory
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',
}))
// ✅ Zustand stores: Use real stores (auto-mocked globally)
// Set test state with: useAppStore.setState({ ... })
// 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: pnpm test <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
- Complexity > 50: Break into smaller pieces before testing
- 500+ lines: Consider splitting before testing
- Many dependencies: Extract logic into hooks first
📖 See
references/workflow.mdfor complete workflow details and todo list format.
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
See Test Structure Template for correct import/mock patterns.
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, Zustand store testing, and best practicesreferences/async-testing.md- Async operations and API callsreferences/domain-components.md- Workflow, Dataset, Configuration testingreferences/common-patterns.md- Frequently used testing patternsreferences/checklist.md- Test generation checklist and validation steps
Authoritative References
Primary Specification (MUST follow)
web/testing/testing.md- The canonical testing specification. This skill is derived from this document.
Reference Examples in Codebase
web/utils/classnames.spec.ts- Utility function testsweb/app/components/base/button/index.spec.tsx- Component testsweb/__mocks__/provider-context.ts- Mock factory example
Project Configuration
web/vitest.config.ts- Vitest configurationweb/vitest.setup.ts- Test environment setupweb/scripts/analyze-component.js- Component analysis tool- Modules are not mocked automatically. Global mocks live in
web/vitest.setup.ts(for examplereact-i18next,next/image); mock other modules likekyormimelocally in test files.
Other versions15 projects use a version of this.
Word for word · 1
- peakdong68/my-skills★ 0100% same
Edited · 3
- nilecui/SkillsBase★ 2799% same
- jpoindexter/theft-kit★ 177% same
- LiuRoi/skills★ 192% same
Wrote their own version · 11
- langgenius/dify★ 160ksame name
- langflow-ai/langflow★ 156ksame name
- YFGaia/dify-plus★ 2.3ksame name
- theexperiencecompany/gaia★ 320same name
- mcowger/plexus★ 237same name
- nightscout/nocturne★ 147same name
- bestdeejay-design/agent-skills★ 6same name
- aboio-labs/aboio-skills★ 3same name
- lobomfz/skills★ 2same name
- factor241/ketos-bot★ 1same name
1 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
Used alongsideProjects with it also use backend-code-review and receiving-code-review.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
jpoindexterSkillbackend-code-review
Review backend code for quality, security, maintainability, and best practices based on established checklist rules. Use when the user requests a review, analysis, or improvement of backend files (e.g., `.py`) under the `api/` directory. Do NOT use for frontend files (e.g., `.tsx`, `.ts`, `.js`). Supports pending-change review, code snippets review, and file-focused review.
Also in 4 projects that use this
CloudflareSkillreceiving-code-review
Use when receiving code review feedback, before implementing suggestions, especially if feedback seems unclear or technically questionable - requires technical rigor and verification, not performative agreement or blind implementation
Also in 3 projects that use this
In this repository39 other files it gives its agents.
- AGENTS.mdAGENTS.md
- .agents/skills/vercel-react-best-practices/AGENTS.mdAGENTS.md
- .claude/skills/vercel-react-best-practices/AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- banner-designSkill
- brandSkill
- component-docSkill
- component-refactoringSkill
- designSkill
- design-systemSkill
- design-taste-frontendSkill
- doc-coauthoringSkill
- feature-devSkill
- frontend-code-reviewSkill
- frontend-designSkill
- frontend-testingSkill
- migrate-nativewind-to-uniwindSkill
- migrate-oxfmtSkill
- migrate-oxlintSkill
- native-component-docSkill
- senior-frontendSkill
- skill-creatorSkill
- skyroc-admin-prd-prototypeSkill
- slidesSkill
- ui-stylingSkill
- ui-ux-pro-maxSkill
- uniwindSkill
- vercel-react-best-practicesSkill
- component-docSkill
- component-refactoringSkill
- doc-coauthoringSkill
- feature-devSkill
- frontend-code-reviewSkill
- frontend-designSkill
- native-component-docSkill
- senior-frontendSkill
- skill-creatorSkill
- ui-ux-pro-maxSkill
- vercel-react-best-practicesSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

