claudegoodies
Skill

e2e-testing

From affaan-m

Patrones de pruebas E2E con Playwright, Page Object Model, configuración, integración CI/CD, gestión de artefactos y estrategias para pruebas inestables.

Provides Playwright E2E testing patterns: Page Object Model, config, flaky-test handling, artifacts, and CI/CD setup.

Use it when

  • Setting up a new Playwright test suite with Page Object Model structure
  • Debugging flaky tests via retries, screenshots, traces, or video
  • Configuring playwright.config.ts for multi-browser/mobile projects
  • Wiring Playwright into a GitHub Actions CI/CD pipeline

Skip it if

  • Only useful if your stack is TypeScript/JavaScript with Playwright
  • Reference/snippet collection, not an executable tool or automation
  • Doesn't cover other E2E frameworks like Cypress or Selenium

Facts

Repository
affaan-m/ECC
Status
Actively maintained
Last commit

Source preview

The instructions Claude Code reads when this skill runs.

# Patrones de Pruebas E2E

Patrones completos de Playwright para construir suites de pruebas E2E estables, rápidas y mantenibles.

## Organización de Archivos de Prueba

```
tests/
├── e2e/
│   ├── auth/
│   │   ├── login.spec.ts
│   │   ├── logout.spec.ts
│   │   └── register.spec.ts
│   ├── features/
│   │   ├── browse.spec.ts
│   │   ├── search.spec.ts
│   │   └── create.spec.ts
│   └── api/
│       └── endpoints.spec.ts
├── fixtures/
│   ├── auth.ts
│   └── data.ts
└── playwright.config.ts
```

## Page Object Model (POM)

```typescript
import { Page, Locator } from '@playwright/test'

export class ItemsPage {
  readonly page: Page
  readonly searchInput: Locator
  readonly itemCards: Locator
  readonly createButton: Locator

  constructor(page: Page) {
    this.page = page
    this.searchInput = page.locator('[data-testid="search-input"]')
    this.itemCards = page.locator('[data-testid="item-card"]')
    this.createButton = page.locator('[data-testid="create-btn"]')
  }

  async goto() {
    await this.page.goto('/items')
    await this.page.waitForLoadState('networkidle')
  }

  async search(query: string) {
    await this.searchInput.fill(query)
    await this.page.waitForResponse(resp => resp.url().includes('/api/search'))
    await this.page.waitForLoadState('networkidle')
  }

  async getItemCount() {
    return await this.itemCards.count()
  }
}
```

## Estructura de
View full source on GitHub →

Other skills