Agent skill
testing
Expert at Playwright E2E tests, Vitest unit tests, Storybook interaction tests. Use when writing tests, debugging test failures, or improving test coverage.
Install this agent skill to your Project
npx add-skill https://github.com/aiskillstore/marketplace/tree/main/skills/crazyswami/testing
SKILL.md
Testing Specialist
You are an expert at testing TypeScript/React applications using Playwright, Vitest, and Storybook.
When To Use
Claude should automatically use this skill when:
- User asks to write tests or improve coverage
- User mentions Playwright, Vitest, E2E, unit tests
- Debugging test failures
- Setting up test infrastructure
Testing Stack
| Tool | Purpose | Location |
|---|---|---|
| Playwright | E2E browser tests | e2e/*.spec.ts |
| Vitest | Unit/integration tests | src/**/*.test.ts |
| Storybook | Component visual tests | src/**/*.stories.tsx |
CRITICAL: Read Before Write (Reconnaissance-Then-Action)
Before writing ANY E2E test, you MUST:
- Read the component source file (e.g.,
Toolbar.tsx,Editor.tsx) - Identify stable selectors in this priority order:
data-testidattributes (explicit testing contract)titleattributes (accessibility, stable)aria-labelattributes (accessibility)- Text content (fragile, last resort)
- Extract exact values from the source - never guess or assume
Selector Priority (Playwright Official)
| Priority | Method | Example | Stability |
|---|---|---|---|
| 1 | data-testid | page.getByTestId('save-btn') |
Most stable |
| 2 | role + name | page.getByRole('button', { name: 'Save' }) |
Stable |
| 3 | title | page.locator('[title="Save"]') |
Stable |
| 4 | text | page.getByText('Save') |
Fragile |
NEVER use: CSS classes, XPath, or auto-generated IDs
Anti-Pattern: Speculative Selectors
// ❌ WRONG - Guessing without reading source
await editor.clickToolbarButton('B'); // Assumes button text is "B"
// ✅ CORRECT - After reading Toolbar.tsx:54 shows title="Bold (Cmd+B)"
await editor.clickToolbarButton('Bold (Cmd+B)');
data-testid Convention
When adding test IDs to components, use format: {scope}-{element}-{type}
data-testid="toolbar-bold-button"
data-testid="editor-content-area"
data-testid="sidebar-note-list"
Playwright E2E Tests
File Structure
e2e/
├── fixtures/
│ └── editor-helpers.ts # Shared test utilities
├── editor.spec.ts # Editor functionality
├── formatting.spec.ts # Text formatting
├── headings.spec.ts # Heading toggles
├── lists.spec.ts # List operations
├── blocks.spec.ts # Block elements
├── keyboard-shortcuts.spec.ts
├── toolbar.spec.ts
└── history.spec.ts
Test Pattern
import { test, expect } from '@playwright/test';
import { EditorHelper } from './fixtures/editor-helpers';
test.describe('Feature Name', () => {
let editor: EditorHelper;
test.beforeEach(async ({ page }) => {
editor = new EditorHelper(page);
await editor.goto();
});
test('descriptive test name', async () => {
await editor.type('test content');
await editor.selectAll();
// Use title from Toolbar.tsx - NOT guessed text
await editor.clickToolbarButton('Bold (Cmd+B)');
await editor.expectElement('strong');
});
});
EditorHelper Methods
editor.goto() // Navigate to app
editor.clear() // Clear editor content
editor.type(text) // Type text
editor.selectAll() // Select all (Cmd+A)
editor.clickToolbarButton(title) // Click toolbar button by title attribute
editor.isToolbarButtonActive(title) // Check button state by title
editor.expectText(text) // Assert text exists
editor.expectElement(selector) // Assert element exists
editor.pressShortcut(key) // Press keyboard shortcut
Toolbar Button Titles (from Toolbar.tsx)
| Button | Title Attribute |
|---|---|
| Bold | Bold (Cmd+B) |
| Italic | Italic (Cmd+I) |
| Underline | Underline (Cmd+U) |
| Strike | Strikethrough |
| H1 | Heading 1 |
| H2 | Heading 2 |
| H3 | Heading 3 |
| Bullet List | Bullet List |
| Numbered List | Numbered List |
| Task List | Task List |
| Quote | Quote |
| Code | Code Block |
| Undo | Undo (Cmd+Z) |
| Redo | Redo (Cmd+Shift+Z) |
| New | New Document |
| Open | Open Document |
| Save | Save Document |
Commands
pnpm test:e2e # Run all E2E tests
pnpm test:e2e:ui # Open Playwright UI
pnpm test:e2e:headed # Run with browser visible
pnpm test:e2e:chromium # Chrome only
pnpm test:e2e:webkit # Safari only
Vitest Unit Tests
File Naming
- Component:
ComponentName.test.tsx - Hook:
useHookName.test.ts - Utility:
utilName.test.ts
Test Pattern
import { describe, it, expect, vi } from 'vitest';
import { functionName } from './module';
describe('functionName', () => {
it('should do something', () => {
const result = functionName(input);
expect(result).toBe(expected);
});
it('should handle edge case', () => {
expect(() => functionName(null)).toThrow();
});
});
Hook Testing
import { renderHook, act } from '@testing-library/react';
import { useHookName } from './useHookName';
describe('useHookName', () => {
it('should return initial state', () => {
const { result } = renderHook(() => useHookName());
expect(result.current.value).toBe(initial);
});
it('should update on action', async () => {
const { result } = renderHook(() => useHookName());
await act(async () => {
await result.current.doAction();
});
expect(result.current.value).toBe(updated);
});
});
Storybook Interaction Tests
import { within, userEvent, expect } from '@storybook/test';
export const WithInteraction: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
// Find and interact with elements
const button = canvas.getByRole('button', { name: 'Submit' });
await userEvent.click(button);
// Assert results
await expect(canvas.getByText('Success')).toBeInTheDocument();
},
};
Test Checklist
When writing tests:
- Test happy path (expected behavior)
- Test edge cases (empty, null, boundary values)
- Test error handling
- Test loading/async states
- Use descriptive test names
- Keep tests focused and isolated
- Mock external dependencies
- Avoid testing implementation details
Coverage Goals
| Type | Target |
|---|---|
| E2E | Critical user flows |
| Unit | Business logic, utilities |
| Component | Visual states, interactions |
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
perigon-backend
Perigon ASP.NET Core + EF Core + Aspire conventions
perigon-agent
Pointers for Copilot/agents to apply Perigon conventions
perigon-angular
Angular 21+ standalone/Material/signal conventions for Perigon WebApp
fastapi-mastery
Comprehensive FastAPI development skill covering REST API creation, routing, request/response handling, validation, authentication, database integration, middleware, and deployment. Use when working with FastAPI projects, building APIs, implementing CRUD operations, setting up authentication/authorization, integrating databases (SQL/NoSQL), adding middleware, handling WebSockets, or deploying FastAPI applications. Triggered by requests involving .py files with FastAPI code, API endpoint creation, Pydantic models, or FastAPI-specific features.
context7-efficient
Token-efficient library documentation fetcher using Context7 MCP with 86.8% token savings through intelligent shell pipeline filtering. Fetches code examples, API references, and best practices for JavaScript, Python, Go, Rust, and other libraries. Use when users ask about library documentation, need code examples, want API usage patterns, are learning a new framework, need syntax reference, or troubleshooting with library-specific information. Triggers include questions like "Show me React hooks", "How do I use Prisma", "What's the Next.js routing syntax", or any request for library/framework documentation.
browser-use
Browser automation using Playwright MCP. Navigate websites, fill forms, click elements, take screenshots, and extract data. Use when tasks require web browsing, form submission, web scraping, UI testing, or any browser interaction.
Didn't find tool you were looking for?