Marketplace testing
Expert at Playwright E2E tests, Vitest unit tests, Storybook interaction tests. Use when writing tests, debugging test failures, or improving test coverage.
install
source · Clone the upstream repo
git clone https://github.com/aiskillstore/marketplace
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/aiskillstore/marketplace "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/crazyswami/testing" ~/.claude/skills/aiskillstore-marketplace-testing-d4eaa4 && rm -rf "$T"
manifest:
skills/crazyswami/testing/SKILL.mdsource content
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 | |
| Vitest | Unit/integration tests | |
| Storybook | Component visual tests | |
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:
attributes (explicit testing contract)data-testid
attributes (accessibility, stable)title
attributes (accessibility)aria-label- 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 | | Most stable |
| 2 | role + name | | Stable |
| 3 | title | | Stable |
| 4 | text | | 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 | |
| Italic | |
| Underline | |
| Strike | |
| H1 | |
| H2 | |
| H3 | |
| Bullet List | |
| Numbered List | |
| Task List | |
| Quote | |
| Code | |
| Undo | |
| Redo | |
| New | |
| Open | |
| Save | |
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 |