Skip to content
Back to skills

E2e Testing Expert

ASecurity

End-to-end testing with Playwright 1.50+, fixtures, and Vitest 3+ / Pengujian E2E dengan Playwright 1.50+, fixtures, dan Vitest 3+.

  • 125 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 12, 2026
ai-agentstypescriptrustgoreactnextjsnoderailstestingdebuggingcode-review

Works with

  • cli
  • api
  • mcp

Security analysis

A96/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned November 12, 2026

npx -y skills add roedyrustam/vibes-plug --skill e2e-testing-expert --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of E2e Testing Expert?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for E2e Testing Expert
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/roedyrustam-e2e-testing-expert-vibes-plug/badge)](https://www.skillsdirectory.com/skills/roedyrustam-e2e-testing-expert-vibes-plug)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: e2e-testing-expert
description: "End-to-end testing with Playwright 1.50+, fixtures, and Vitest 3+ / Pengujian E2E dengan Playwright 1.50+, fixtures, dan Vitest 3+."
author: "Roedy Rustam"
version: "4.8.0"

---

# E2E Testing Expert (Playwright 1.50+ & Vitest 3 Standard)

[English](#english) | [Bahasa Indonesia](#bahasa-indonesia)

---

<a name="english"></a>
## English

### Orchestration & Integration
- **TDD & Autonomous Debugging**: `autonomous-tdd-debugger`, `property-mutation-testing-expert`
- **Quality Gates & Anti-Slop**: `anti-slop`, `ai-code-review-autonomous`, `zero-tech-debt-auditor`
- **Accessibility & Browser Automation**: `accessibility-testing-expert`, `browser-automation-expert`
- **CI/CD & DevOps Automation**: `ci-cd-devops-architect`, `github-actions-expert`
- **Lifecycle & Governance**: `brainstorming`, `zero-to-prod-orchestrator`, `session-memory-manager`

### Description
Production-grade guide for automated browser and component testing using **Playwright 1.50+** and **Vitest 3+**. Covers virtual clock manipulation with `page.clock`, semantic accessibility assertions with `toMatchAriaSnapshot`, type-safe composable fixtures, dynamic UI banner interception (`page.addLocatorHandler`), session state reuse (`storageState`), and CI matrix sharding.

### Trigger Conditions
- Writing End-to-End (E2E) browser test suites for Next.js 15, React 19, or Svelte 5 applications.
- Testing time-sensitive UI (countdown timers, session expiries, debounced search) deterministically.
- Verifying WCAG accessibility tree structure using semantic `aria-snapshot`.
- Creating composable test fixtures with authenticated contexts and isolated database state.
- Setting up parallel CI test execution with artifact uploads on test failure.

---

### Playwright 1.50+ Core Architectural Patterns

#### 1. Deterministic Time Testing with the Clock API (`page.clock`)
Eliminate flaky `page.waitForTimeout` by freezing, fast-forwarding, or setting system time:
```typescript
// tests/e2e/timer.spec.ts
import { test, expect } from '@playwright/test';

test('advances countdown timer deterministically', async ({ page }) => {
  // 1. Install virtual clock fixed at specific timestamp
  await page.clock.install({ time: new Date('2026-03-01T12:00:00Z') });
  await page.goto('/promotions/flash-sale');

  // Verify initial state
  const countdown = page.getByRole('timer');
  await expect(countdown).toHaveText('24:00:00');

  // 2. Fast forward 6 hours in 1 millisecond without waiting!
  await page.clock.fastForward('06:00:00');
  await expect(countdown).toHaveText('18:00:00');

  // 3. Fast forward past expiration
  await page.clock.fastForward('18:00:01');
  await expect(page.getByRole('alert')).toHaveText('This promotion has ended.');
});
```

#### 2. Semantic Accessibility Assertions (`toMatchAriaSnapshot`)
Assert the rendered accessible role tree rather than fragile DOM classes:
```typescript
// tests/e2e/navigation.spec.ts
import { test, expect } from '@playwright/test';

test('navigation bar renders semantic accessible structure', async ({ page }) => {
  await page.goto('/');

  const header = page.locator('header');
  await expect(header).toMatchAriaSnapshot(`
    - banner:
      - link "Brand Logo":
        - /url: //
      - navigation:
        - link "Products"
        - link "Docs"
        - link "Pricing"
      - button "Sign in"
  `);
});
```

#### 3. Automatic Banner & Dialog Interception (`page.addLocatorHandler`)
Dismiss cookie banners or dynamic popups automatically whenever they appear:
```typescript
// tests/e2e/fixtures.ts
import { test as base, expect } from '@playwright/test';

export const test = base.extend({
  page: async ({ page }, use) => {
    // Automatically dismiss cookie consent modals whenever they overlay the page
    const consentButton = page.getByRole('button', { name: 'Accept all cookies' });
    await page.addLocatorHandler(consentButton, async () => {
      await consentButton.click();
    });

    await use(page);
  },
});
```

#### 4. Reusable Authentication State (`storageState`)
Authenticate once in a setup project and inject session cookies into all test suites:
```typescript
// tests/e2e/auth.setup.ts
import { test as setup, expect } from '@playwright/test';

const authFile = 'playwright/.auth/admin.json';

setup('authenticate admin user', async ({ page }) => {
  await page.goto('/login');
  await page.getByLabel('Email').fill('admin@enterprise.test');
  await page.getByLabel('Password').fill('VaultP@ssw0rd2026!');
  await page.getByRole('button', { name: 'Sign in' }).click();

  await page.waitForURL('/dashboard');
  await expect(page.getByRole('heading', { name: 'Overview' })).toBeVisible();

  // Persist storage state (cookies, localStorage, session tokens)
  await page.context().storageState({ path: authFile });
});
```

```typescript
// tests/e2e/billing.spec.ts
import { test, expect } from '@playwright/test';

// Reuse authenticated state automatically
test.use({ storageState: 'playwright/.auth/admin.json' });

test('admin can view billing invoices', async ({ page }) => {
  await page.goto('/billing/invoices');
  await expect(page.getByRole('heading', { name: 'Invoices' })).toBeVisible();
});
```

#### 5. CI Test Sharding in GitHub Actions
Split Playwright test executions across parallel workers in CI:
```yaml
# .github/workflows/e2e.yml
name: Playwright Tests
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        shardIndex: [1, 2, 3, 4]
        shardTotal: [4]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '22', cache: 'pnpm' }
      - run: pnpm install --frozen-lockfile
      - run: pnpm exec playwright install --with-deps chromium
      - name: Run Playwright Tests (Shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }})
        run: pnpm exec playwright test --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
      - uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: playwright-blob-${{ matrix.shardIndex }}
          path: blob-report/
```

#### 6. Zero-Console-Error / Uncaught-Page-Error Gate & Deterministic Route Mocking
Fail E2E tests automatically if the browser emits any uncaught runtime exception (`pageerror`) or `console.error`, while mocking third-party HTTP dependencies deterministically via `page.route`:

```typescript
import { test as base, expect } from '@playwright/test';

export const test = base.extend<{ assertZeroRuntimeErrors: void }>({
  assertZeroRuntimeErrors: [
    async ({ page }, use) => {
      const runtimeErrors: string[] = [];

      page.on('pageerror', (err) => {
        runtimeErrors.push(`[UncaughtPageError] ${err.message}`);
      });

      page.on('console', (msg) => {
        if (msg.type() === 'error') {
          runtimeErrors.push(`[ConsoleError] ${msg.text()}`);
        }
      });

      await use();
      expect(runtimeErrors, 'Expected zero uncaught page errors or console.error logs').toEqual([]);
    },
    { auto: true },
  ],
});

test('checkout flow handles deterministic payment gateway response cleanly', async ({ page }) => {
  await page.route('**/api/checkout/session', async (route) => {
    await route.fulfill({
      status: 200,
      contentType: 'application/json',
      body: JSON.stringify({
        sessionId: 'cs_test_99182736',
        status: 'READY',
        amountCents: 4900,
      }),
    });
  });

  await page.goto('/checkout');
  await page.getByRole('button', { name: 'Complete Order' }).click();
  await expect(page.getByRole('status')).toContainText('cs_test_99182736');
});
```

### Hard Guardrails (Declarative Invariants)
- **Zero Arbitrary Sleep Calls**: MUST ban `page.waitForTimeout(...)` in E2E suites; always synchronize using web-first assertions (`await expect(locator).toBeVisible()`) or virtual clock manipulation (`page.clock`).
- **Role & Accessible-Name Locators First**: MUST prioritize `page.getByRole()`, `page.getByLabel()`, and `toMatchAriaSnapshot()` over brittle CSS class or XPath selectors.
- **Zero Uncaught Page or Console Errors**: MUST attach `page.on('pageerror')` and `page.on('console')` guards in shared fixtures so unexpected runtime exceptions fail the test immediately.
- **Isolated Storage State & Per-Worker Tenancy**: MUST isolate authentication (`storageState`) and database fixtures per worker index so parallel shards never mutate shared state.
- **Deterministic External Boundary Mocking**: MUST intercept unstable third-party webhooks or external APIs via `page.route()` / HAR replay in CI runs.

### Sovereign Execution, Token Efficiency & Invariants
| Dimension | Sovereign Mandate & Deterministic Contract |
| :--- | :--- |
| **Frontier Model Cascade** | High Fast / High (`Grok 4.7 High Fast`, `Claude Sonnet 5.5 High`, `Gemini 4 Pro`) |
| **Availability Fallback** | `Gemini 4 Pro` -> `Gemini 3.8 Flash`; `Claude Opus 5.5` -> `Claude Opus 4.6`; `Grok 4.7` -> `Grok 4.6 High Fast` (Zero unhandled missing-model errors) |
| **KV-Cache & Token Protocol** | Pin static instructions & schemas at prompt prefix (`kv-cache-prefix-optimizer`); pass surgical `CONTEXT_MAP.md` slices (<250 tokens/call) during Swarm Fan-Out |
| **SaaT CLI & MCP Dispatch** | CLI: `vibes skill exec e2e-testing-expert <audit\|eval\|verify\|generate\|blueprint>` / MCP: `vibes_skill_dispatch`, `vibes_critic_validate`, `vibes_self_heal`, `vibes_eval_sandbox`, `vibes_verify_invariants` |
| **NFR & Anti-Slop Invariants** | Zero OWASP Top 10 vectors, 0 hardcoded secrets, >= 90% branch coverage on domain logic, 0 Anti-Slop violations; 100% complete zero-placeholder output verified via `node scripts/check-anti-slop.js --strict` |

---


---

<a name="bahasa-indonesia"></a>
## Bahasa Indonesia

### Integrasi Orkestrasi
- **TDD & Debugging Otonom**: `autonomous-tdd-debugger`, `property-mutation-testing-expert`
- **Gerbang Kualitas & Anti-Slop**: `anti-slop`, `ai-code-review-autonomous`, `zero-tech-debt-auditor`
- **Aksesibilitas & Otomasi Browser**: `accessibility-testing-expert`, `browser-automation-expert`
- **CI/CD & Otomasi DevOps**: `ci-cd-devops-architect`, `github-actions-expert`
- **Siklus Hidup & Tata Kelola**: `brainstorming`, `zero-to-prod-orchestrator`, `session-memory-manager`

### Deskripsi
Panduan produksi untuk pengujian browser dan komponen otomatis menggunakan **Playwright 1.50+** dan **Vitest 3+**. Mencakup manipulasi jam virtual deterministik dengan `page.clock`, asersi pohon aksesibilitas semantis dengan `toMatchAriaSnapshot`, pembuatan test fixture modular, penanganan banner modal dinamis (`page.addLocatorHandler`), penggunaan ulang sesi autentikasi (`storageState`), dan sharding paralel di CI.

### Kondisi Pemicu
- Menulis test suite E2E browser untuk aplikasi Next.js 15, React 19, atau Svelte 5.
- Menguji antarmuka berbasis waktu (countdown timer, kedaluwarsa sesi) secara deterministik tanpa jeda waktu riil.
- Memvalidasi struktur pohon aksesibilitas menggunakan asersi semantis `aria-snapshot`.
- Mengonfigurasi fixture pengujian dengan isolasi state autentikasi dan database.
- Menjalankan pipeline pengujian terdistribusi secara paralel di GitHub Actions.

---

### Pola Kunci Playwright 1.50+

#### 1. Pengujian Waktu Deterministik Menggunakan Clock API (`page.clock`)
Hilangkan ketergantungan pada `time.Sleep` atau `waitForTimeout` dengan memajukan jam virtual seketika:
```typescript
import { test, expect } from '@playwright/test';

test('menguji countdown diskon secara deterministik', async ({ page }) => {
  // 1. Pasang jam virtual pada tanggal tertentu
  await page.clock.install({ time: new Date('2026-03-01T12:00:00Z') });
  await page.goto('/promo');

  const timer = page.getByRole('timer');
  await expect(timer).toHaveText('24:00:00');

  // 2. Majukan waktu 6 jam secara instan (1 milidetik)
  await page.clock.fastForward('06:00:00');
  await expect(timer).toHaveText('18:00:00');

  // 3. Majukan hingga waktu promo berakhir
  await page.clock.fastForward('18:00:01');
  await expect(page.getByRole('alert')).toHaveText('Promo ini telah berakhir.');
});
```

#### 2. Asersi Aksesibilitas Semantis (`toMatchAriaSnapshot`)
Validasi struktur aksesibilitas UI tanpa terikat pada class CSS atau tag DOM yang rapuh:
```typescript
import { test, expect } from '@playwright/test';

test('navigasi memenuhi standar aksesibilitas', async ({ page }) => {
  await page.goto('/');

  await expect(page.locator('header')).toMatchAriaSnapshot(`
    - banner:
      - link "Logo":
        - /url: //
      - navigation:
        - link "Produk"
        - link "Dokumentasi"
        - link "Harga"
      - button "Masuk"
  `);
});
```

#### 3. Penanganan Banner Otomatis (`page.addLocatorHandler`)
Tutup banner persetujuan cookie atau modal promosi secara otomatis kapan pun elemen tersebut muncul:
```typescript
import { test as base } from '@playwright/test';

export const test = base.extend({
  page: async ({ page }, use) => {
    const tombolCookie = page.getByRole('button', { name: 'Setujui semua' });
    await page.addLocatorHandler(tombolCookie, async () => {
      await tombolCookie.click();
    });

    await use(page);
  },
});
```

### Matriks Eksekusi Berdaulat, Efisiensi Token & Invarian
| Dimensi | Mandat Berdaulat & Kontrak Deterministik |
| :--- | :--- |
| **Kaskade Model Frontier** | High Fast / High (`Grok 4.7 High Fast`, `Claude Sonnet 5.5 High`, `Gemini 4 Pro`) |
| **Invarian Fallback Ketersediaan** | `Gemini 4 Pro` -> `Gemini 3.8 Flash`; `Claude Opus 5.5` -> `Claude Opus 4.6`; `Grok 4.7` -> `Grok 4.6 High Fast` (Bebas gagal saat model belum tersedia/kuota penuh) |
| **Protokol Hemat Token & KV-Cache** | Kunci instruksi & skema statis di prefix awal (`kv-cache-prefix-optimizer`); kirim potongan `CONTEXT_MAP.md` (<250 token/panggilan) saat Fan-Out |
| **Eksekusi SaaT CLI & MCP** | CLI: `vibes skill exec e2e-testing-expert <audit\|eval\|verify\|generate\|blueprint>` / MCP: `vibes_skill_dispatch`, `vibes_critic_validate`, `vibes_self_heal`, `vibes_eval_sandbox`, `vibes_verify_invariants` |
| **Invarian NFR & Anti-Slop** | Nol celah OWASP Top 10, 0 kredensial hardcoded, cakupan pengujian >= 90% pada logika domain, 0 pelanggaran Anti-Slop; kode 100% tuntas tanpa placeholder diverifikasi melalui `node scripts/check-anti-slop.js --strict` |

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

View all in ai-agents →

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.