PL

playwright-automation

Provides a robust framework for writing Playwright tests and automating data population workflows.

Install

mkdir -p .claude/skills/playwright-automation && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/15935" && unzip -o skill.zip -d .claude/skills/playwright-automation && rm skill.zip

Installs to .claude/skills/playwright-automation

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Playwright for E2E/component/API tests and data automation. Use when: writing tests, automating data population, testing user flows, validating UI interactions, or seeding test data.
182 chars · catalog description✓ has a “when” trigger
Intermediate

Key capabilities

  • Write End-to-End (E2E) tests for complete user flows
  • Create component tests for isolated UI elements
  • Develop API tests for backend endpoints
  • Automate data population and seeding for test environments
  • Create reusable fixtures for authentication and database setup
  • Implement Page Objects for UI element management

How it works

The skill guides the user through setting up Playwright, creating basic authentication fixtures, writing E2E tests, and developing data automation scripts using Page Objects and shared fixtures.

Inputs & outputs

You give it
description of desired tests (e.g., 'e2e', 'component', 'api') or data automation tasks
You get back
Playwright test files, fixtures, helpers, and seed data scripts

When to use playwright-automation

  • Testing user flows
  • Seeding test databases
  • Automating data entry
  • Writing component tests

About this skill

Playwright Automation & Testing

Padrões completos para usar Playwright tanto para testes (E2E, Component, API) quanto para automação de dados e seed de teste.

Princípios

  1. E2E First: Teste fluxos reais do usuário
  2. Data Automation: Script para popular dados rapidamente
  3. Reutilização: Fixtures e helpers reutilizáveis
  4. Manutenibilidade: Page objects para evitar duplicação
  5. Performance: Testes paralelos quando possível
  6. Clareza: Testes legíveis e autodocumentados

Quando Usar Esta Skill

  1. E2E Tests: Testar fluxos completos (login → adicionar transação → visualizar)
  2. Component Tests: Testar componentes isolados
  3. API Tests: Testar endpoints backend
  4. Seed Data: Popular banco de dados com dados de teste
  5. Data Automation: Automatizar preenchimento de dados via UI
  6. Fixtures: Criar helpers para reutilizar em múltiplos testes

Procedimento Rápido

1. Setup Inicial

Instale Playwright:

npm install -D @playwright/test
npx playwright install

Estrutura de pastas:

tests/
├── e2e/               # E2E tests
│   ├── auth.spec.ts
│   ├── transactions.spec.ts
│   └── dashboard.spec.ts
├── api/               # API tests
│   └── transactions.api.spec.ts
├── fixtures/          # Fixtures compartilhadas
│   ├── auth.fixture.ts
│   ├── database.fixture.ts
│   └── pages.fixture.ts
├── helpers/           # Helpers reutilizáveis
│   ├── seed-data.ts
│   ├── auth-helper.ts
│   └── transaction-helper.ts
└── playwright.config.ts

2. Fixture Básica (Autenticação)

Use auth fixture template:

// tests/fixtures/auth.fixture.ts
import { test as base } from '@playwright/test';

type AuthFixtures = {
  authenticatedPage: Page;
};

export const test = base.extend<AuthFixtures>({
  authenticatedPage: async ({ page }, use) => {
    // Login
    await page.goto('http://localhost:8000/login/');
    await page.fill('input[name="email"]', '[email protected]');
    await page.fill('input[name="password"]', 'senha123');
    await page.click('button:has-text("Entrar")');
    
    // Esperar dashboard carregar
    await page.waitForURL('**/dashboard/**');
    
    await use(page);
    
    // Cleanup
    await page.close();
  },
});

export { expect } from '@playwright/test';

3. E2E Test - Adicionar Transação

// tests/e2e/transactions.spec.ts
import { test, expect } from '../fixtures/auth.fixture';

test.describe('Adicionar Transação', () => {
  test('deve adicionar uma saída com sucesso', async ({ authenticatedPage: page }) => {
    // Arrange: Navegar até dashboard
    await page.goto('http://localhost:8000/dashboard/');
    
    // Act: Clicar em adicionar
    await page.click('button:has-text("+ Adicionar")');
    
    // Modal abre
    await expect(page.locator('#modalTransacao')).toBeVisible();
    
    // Preencher formulário
    await page.click('button:has-text("Saída")');
    await page.fill('input[name="valor"]', '85.50');
    await page.selectOption('select[name="categoria"]', 'alimentacao');
    await page.fill('input[name="data"]', '2024-03-25');
    await page.fill('input[name="descricao"]', 'Supermercado');
    
    // Salvar
    await page.click('button:has-text("Salvar")');
    
    // Assert: Verificar sucesso
    await expect(page.locator('text=Transação salva com sucesso')).toBeVisible();
    
    // Verificar se aparece na lista
    await expect(page.locator('text=Supermercado')).toBeVisible();
    
    // Verificar se saldo atualizou
    const novoSaldo = await page.locator('text=R\\$ 2.365').first();
    await expect(novoSaldo).toBeVisible();
  });
});

4. Automação de Dados (Seed Script)

Use seed data helper:

// tests/helpers/seed-data.ts
import { Page, Browser } from '@playwright/test';

export class SeedDataHelper {
  constructor(private page: Page) {}

  async addTransaction(data: {
    tipo: 'entrada' | 'saída';
    valor: number;
    categoria: string;
    descricao?: string;
    data?: string;
  }) {
    // Abrir modal
    await this.page.click('button:has-text("+ Adicionar")');
    await this.page.waitForSelector('#modalTransacao:not(.hidden)');

    // Selecionar tipo
    if (data.tipo === 'entrada') {
      await this.page.click('button:has-text("Entrada")');
    } else {
      await this.page.click('button:has-text("Saída")');
    }

    // Preencher campos
    await this.page.fill('input[name="valor"]', data.valor.toString());
    await this.page.selectOption('select[name="categoria"]', data.categoria);
    
    if (data.data) {
      await this.page.fill('input[name="data"]', data.data);
    }
    
    if (data.descricao) {
      await this.page.fill('input[name="descricao"]', data.descricao);
    }

    // Salvar
    await this.page.click('button:has-text("Salvar")');
    
    // Aguardar sucesso
    await this.page.waitForSelector('text=Transação salva');
    await this.page.waitForTimeout(500); // Aguardar animação
  }

  async populateTestData(count = 5) {
    const categorias = ['alimentacao', 'transporte', 'lazer', 'saude'];
    
    for (let i = 0; i < count; i++) {
      const tipo = i % 2 === 0 ? 'saída' : 'entrada';
      const valor = Math.floor(Math.random() * 1000) + 10;
      const categoria = categorias[Math.floor(Math.random() * categorias.length)];
      
      await this.addTransaction({
        tipo,
        valor,
        categoria,
        descricao: `Transação teste ${i + 1}`,
      });
    }
  }
}

export async function seedDatabase(page: Page) {
  const seedHelper = new SeedDataHelper(page);
  await seedHelper.populateTestData(10);
}

5. API Test (Backend)

// tests/api/transactions.api.spec.ts
import { test, expect } from '@playwright/test';

test.describe('Transactions API', () => {
  let token: string;
  const baseURL = 'http://localhost:8000/api';

  test.beforeAll(async () => {
    // Login e obter token
    const response = await fetch(`${baseURL}/auth/login/`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        email: '[email protected]',
        password: 'senha123',
      }),
    });
    const data = await response.json();
    token = data.token;
  });

  test('POST /transactions - criar transação', async () => {
    const response = await fetch(`${baseURL}/transactions/`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${token}`,
      },
      body: JSON.stringify({
        tipo: 'saída',
        valor: 85.50,
        categoria: 'alimentacao',
        descricao: 'Supermercado',
        data: '2024-03-25',
      }),
    });

    expect(response.status).toBe(201);
    const data = await response.json();
    expect(data.id).toBeDefined();
    expect(data.valor).toBe(85.50);
  });

  test('GET /transactions - listar transações', async () => {
    const response = await fetch(`${baseURL}/transactions/`, {
      headers: { 'Authorization': `Bearer ${token}` },
    });

    expect(response.status).toBe(200);
    const data = await response.json();
    expect(Array.isArray(data)).toBe(true);
  });
});

6. Config do Playwright

// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir: './tests',
  fullyParallel: true,
  forbidOnly: !!process.env.CI,
  retries: process.env.CI ? 2 : 0,
  workers: process.env.CI ? 1 : undefined,
  reporter: 'html',
  
  use: {
    baseURL: 'http://localhost:8000',
    trace: 'on-first-retry',
    screenshot: 'only-on-failure',
  },

  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },
    {
      name: 'firefox',
      use: { ...devices['Desktop Firefox'] },
    },
    {
      name: 'webkit',
      use: { ...devices['Desktop Safari'] },
    },
    {
      name: 'Mobile Chrome',
      use: { ...devices['Pixel 5'] },
    },
  ],

  webServer: {
    command: 'python manage.py runserver',
    url: 'http://localhost:8000',
    reuseExistingServer: !process.env.CI,
  },
});

7. Package.json Scripts

{
  "scripts": {
    "test": "playwright test",
    "test:e2e": "playwright test tests/e2e",
    "test:api": "playwright test tests/api",
    "test:debug": "playwright test --debug",
    "test:ui": "playwright test --ui",
    "test:headed": "playwright test --headed",
    "test:report": "playwright show-report",
    "seed:data": "playwright test tests/helpers/seed-data.ts --headed"
  }
}

Padrões Comuns

Page Object Pattern (Reutilizável)

// tests/pages/DashboardPage.ts
export class DashboardPage {
  constructor(private page: Page) {}

  async goto() {
    await this.page.goto('/dashboard/');
  }

  async getSaldo(): Promise<string> {
    return this.page.locator('text=Saldo Atual')
      .locator('..').locator('text="R\\$"').first().textContent();
  }

  async openAddTransactionModal() {
    await this.page.click('button:has-text("+ Adicionar")');
    await this.page.waitForSelector('#modalTransacao:not(.hidden)');
  }

  async fillTransactionForm(data: TransactionData) {
    await this.page.fill('input[name="valor"]', data.valor.toString());
    // ... outros campos
  }

  async submitTransaction() {
    await this.page.click('button:has-text("Salvar")');
    await this.page.waitForSelector('text=salva');
  }
}

Usar Page Object

test('adicionar transação com page object', async ({ authenticatedPage: page }) => {
  const dashboard = new DashboardPage(page);
  a

---

*Content truncated.*

When not to use it

  • When not using Playwright for testing or data automation
  • When not needing E2E, component, or API tests
  • When not requiring data seeding or UI automation

Limitations

  • Specific to Playwright framework for testing and automation
  • Requires `npm` for package installation
  • Assumes a project structure with `tests/` directory for organization

How it compares

This workflow provides a structured and principle-driven approach to Playwright automation, emphasizing E2E testing, data automation, and reusability through fixtures and Page Objects, which differs from ad-hoc scripting.

Compared to similar skills

playwright-automation side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
playwright-automation (this skill)04moReviewIntermediate
webapp-testing3533moReviewIntermediate
playwright-browser-automation298moReviewIntermediate
browser-daemon59moReviewIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

Search skills

Search the agent skills registry