Receber por email
← Voltar para o catálogo

testing

Expert at Playwright E2E tests, Vitest unit tests, Storybook interaction tests. Use when writing tests, debugging test failures, or improving test coverage.

367estrelas
Atualizado há 4 meses

Ver no GitHub ↗

Como adicionar

/plugin marketplace add aiskillstore/marketplace

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/testing-mpszhsfd/svg)](https://www.skillteca.com.br/skills/testing-mpszhsfd)

Skills relacionadas

Ver todas de Desenvolvimento →

Alerta por categoria

Receba novas skills de Desenvolvimento toda segunda

1 email curto, só com as skills novas de Desenvolvimento. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

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:

  1. Read the component source file (e.g., Toolbar.tsx, Editor.tsx)
  2. Identify stable selectors in this priority order:
  3. data-testid attributes (explicit testing contract)
  4. title attributes (accessibility, stable)
  5. aria-label attributes (accessibility)
  6. Text content (fragile, last resort)
  7. 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 |

Compartilhar X LinkedIn