testing-web
| Type | Skill |
| Plugin | awl-testing · v0.0.27 |
| Invoke | /awl-testing:testing-web |
| Tools | Read, Write, Edit, Bash, Glob, Grep |
| Source | plugins/awl-testing/skills/testing-web/SKILL.md |
When Claude uses it
Section titled “When Claude uses it”Writes and debugs JavaScript/TypeScript tests using Jest, Vitest, Testing Library, and Playwright. Use when “write jest tests”, “vitest test”, “react testing library”, “playwright test”, “test typescript”, “test javascript”, “component test”, “e2e test web”, “mock api”, “test react component”, “test vue component”, “test node.js”, “fix jest test”, “debug vitest”, “accessibility test”, “a11y”, “axe”, “sveltekit e2e”.
Trigger phrases: write jest tests · vitest test · react testing library · playwright test · test typescript · test javascript · component test · e2e test web · mock api · test react component · test vue component · test node.js · fix jest test · debug vitest · accessibility test · a11y · axe · sveltekit e2e
Definition
Section titled “Definition”Quick Start
Section titled “Quick Start”describe('UserService', () => { it('should return user when ID exists', async () => { // Arrange const mockUser = { id: 1, name: 'Alice' }; vi.spyOn(api, 'fetchUser').mockResolvedValue(mockUser);
// Act const user = await userService.getUser(1);
// Assert expect(user).toEqual(mockUser); });});Run tests:
npm testnpm run test:watchnpx playwright testWhen to Use
Section titled “When to Use”| Task | This Skill Helps With |
|---|---|
| Unit tests | Functions, services, utilities |
| Component tests | React, Vue, Svelte components |
| E2E tests | Full user flows with Playwright |
| Test failures | Debugging red tests, fixing assertions |
| Mocking | APIs, modules, timers |
Naming Conventions
Section titled “Naming Conventions”Suites: describe('ComponentName' | 'functionName')
Tests: it('should <behavior> when <condition>')
Examples:
it('should render button with correct text')it('should return false when email is invalid')it('should call onClick handler when clicked')
Core Patterns
Section titled “Core Patterns”Unit Test
Section titled “Unit Test”describe('validateEmail', () => { it('should return true for valid email', () => { expect(validateEmail('test@example.com')).toBe(true); });
it('should return false for invalid email', () => { expect(validateEmail('invalid')).toBe(false); });});Component Test (Testing Library)
Section titled “Component Test (Testing Library)”import { render, screen, fireEvent } from '@testing-library/react';
describe('Button', () => { it('should call onClick when clicked', () => { const handleClick = vi.fn(); render(<Button onClick={handleClick}>Click me</Button>);
fireEvent.click(screen.getByRole('button', { name: /click me/i }));
expect(handleClick).toHaveBeenCalledTimes(1); });});E2E Test (Playwright)
Section titled “E2E Test (Playwright)”import { test, expect } from '@playwright/test';
test('user can login', async ({ page }) => { await page.goto('/login'); await page.fill('input[name="email"]', 'user@example.com'); await page.fill('input[name="password"]', 'password123'); await page.click('button[type="submit"]');
await expect(page).toHaveURL('/dashboard'); await expect(page.locator('h1')).toContainText('Welcome');});Async Testing
Section titled “Async Testing”it('should fetch data', async () => { const data = await fetchData(); expect(data).toEqual({ id: 1 });});
it('should reject with error', async () => { await expect(fetchInvalidData()).rejects.toThrow('Not found');});Mocking
Section titled “Mocking”Function Mocks
Section titled “Function Mocks”const mockFn = vi.fn();mockFn.mockReturnValue(42);mockFn.mockResolvedValue({ id: 1 });mockFn.mockRejectedValue(new Error('Failed'));
expect(mockFn).toHaveBeenCalled();expect(mockFn).toHaveBeenCalledWith('arg1', 'arg2');Module Mocks
Section titled “Module Mocks”// Vitestvi.mock('./api', () => ({ fetchUser: vi.fn(),}));
// Jestjest.mock('./api', () => ({ fetchUser: jest.fn(),}));Timer Mocks
Section titled “Timer Mocks”it('should debounce calls', () => { vi.useFakeTimers(); const callback = vi.fn(); const debounced = debounce(callback, 1000);
debounced(); debounced(); expect(callback).not.toHaveBeenCalled();
vi.advanceTimersByTime(1000); expect(callback).toHaveBeenCalledTimes(1);
vi.useRealTimers();});Setup & Teardown
Section titled “Setup & Teardown”describe('Database tests', () => { let db: Database;
beforeEach(async () => { db = await createTestDatabase(); });
afterEach(async () => { await db.close(); });});Common Assertions
Section titled “Common Assertions”expect(value).toBe(expected);expect(value).toEqual(expected); // Deep equalityexpect(value).toBeTruthy();expect(value).toBeFalsy();expect(value).toBeNull();expect(value).toBeDefined();expect(array).toContain(item);expect(array).toHaveLength(3);expect(fn).toHaveBeenCalled();expect(fn).toHaveBeenCalledWith(arg);Testing Library Queries
Section titled “Testing Library Queries”screen.getByRole('button', { name: /submit/i });screen.getByLabelText(/email/i);screen.getByText(/welcome/i);screen.getByTestId('user-card');await screen.findByText(/loaded/i); // AsyncTroubleshooting
Section titled “Troubleshooting”Test Not Found
Section titled “Test Not Found”# Check pattern matchesnpm test -- --listTests
# Vitestnpx vitest --reporter=verboseMock Not Working
Section titled “Mock Not Working”// BAD: Import before mockimport { api } from './api';vi.mock('./api');
// GOOD: Mock hoisted automatically in Vitestvi.mock('./api');import { api } from './api';Async Test Timeout
Section titled “Async Test Timeout”// Increase timeoutit('slow test', async () => { ... }, 10000);
// Or globally in configtest: { timeout: 10000 }Element Not Found
Section titled “Element Not Found”// BAD: Query immediately after renderrender(<AsyncComponent />);expect(screen.getByText('data')).toBeInTheDocument();
// GOOD: Wait for elementrender(<AsyncComponent />);expect(await screen.findByText('data')).toBeInTheDocument();Act Warning
Section titled “Act Warning”// Wrap state updatesawait act(async () => { fireEvent.click(button);});Best Practices
Section titled “Best Practices”- AAA Pattern - Arrange-Act-Assert structure
- Test behavior - Not implementation details
- Accessibility queries -
getByRole,getByLabelTextfirst - userEvent over fireEvent - More realistic interactions
- Independent tests - No shared state between tests
- Mock boundaries - APIs, databases, not internal modules
- Fast tests - Unit tests in milliseconds
Running Tests
Section titled “Running Tests”# Vitestnpm test # Run oncenpm run test:watch # Watch modenpm run test:coverage # Coverage
# Jestnpm test -- --watchnpm test -- --coverage
# Playwrightnpx playwright testnpx playwright test --ui # UI modenpx playwright show-reportReferences
Section titled “References”For advanced patterns and complete examples:
- FRONTEND.md - Component testing, E2E, mocking strategies
- BACKEND.md - Node.js API testing, database patterns
- EXAMPLES.md - Complete working examples
- AWL_PLAYWRIGHT.md -
@awl/playwright-a11yand@awl/playwright-sveltekit; read when the project is a SvelteKit app or needs accessibility checks in e2e

