Playwright mit Claude Code: Fortgeschrittenes E2E-Testing 2026
Playwright ist der Standard für moderne E2E-Tests — cross-browser, schnell, zuverlässig. Claude Code schreibt Playwright-Tests auf Prompt: Page Objects, API-Mocking, Auth-State-Management, Visual Regression Testing und CI-Optimierung.
Page Object Model mit TypeScript
POMWartbare Test-Struktur
// Prompt: "Erstelle Page Objects für Login und Dashboard"
// pages/LoginPage.ts
import { type Page, type Locator, expect } from '@playwright/test';
export class LoginPage {
readonly page: Page;
readonly emailInput: Locator;
readonly passwordInput: Locator;
readonly submitButton: Locator;
readonly errorMessage: Locator;
constructor(page: Page) {
this.page = page;
this.emailInput = page.getByRole('textbox', { name: 'E-Mail' });
this.passwordInput = page.getByRole('textbox', { name: 'Passwort' });
this.submitButton = page.getByRole('button', { name: 'Anmelden' });
this.errorMessage = page.getByRole('alert');
}
async goto() {
await this.page.goto('/login');
}
async login(email: string, password: string) {
await this.emailInput.fill(email);
await this.passwordInput.fill(password);
await this.submitButton.click();
}
async expectErrorVisible(message: string) {
await expect(this.errorMessage).toBeVisible();
await expect(this.errorMessage).toContainText(message);
}
}
// tests/login.spec.ts
import { test, expect } from '@playwright/test';
import { LoginPage } from '../pages/LoginPage';
test.describe('Login Flow', () => {
test('erfolgreicher Login leitet weiter', async ({ page }) => {
const loginPage = new LoginPage(page);
await loginPage.goto();
await loginPage.login('user@test.de', 'password123');
await expect(page).toHaveURL(/dashboard/);
});
test('falsches Passwort zeigt Fehler', async ({ page }) => {
const loginPage = new LoginPage(page);
await loginPage.goto();
await loginPage.login('user@test.de', 'falsch');
await loginPage.expectErrorVisible('Ungültige Zugangsdaten');
});
});
Auth-State speichern: Login-Overhead vermeiden
AuthEinmal einloggen, alle Tests nutzen
// playwright.config.ts
export default defineConfig({
projects: [
{
name: 'setup',
testMatch: '**/auth.setup.ts',
},
{
name: 'chromium',
dependencies: ['setup'],
use: {
storageState: 'playwright/.auth/user.json',
},
},
],
});
// tests/auth.setup.ts
import { test as setup } from '@playwright/test';
setup('authenticate', async ({ page }) => {
await page.goto('/login');
await page.getByLabel('E-Mail').fill(process.env.TEST_EMAIL!);
await page.getByLabel('Passwort').fill(process.env.TEST_PASSWORD!);
await page.getByRole('button', { name: 'Anmelden' }).click();
await page.waitForURL('**/dashboard');
// Auth-State für alle Tests speichern (Cookies + LocalStorage):
await page.context().storageState({ path: 'playwright/.auth/user.json' });
});
// → Login nur EINMAL! Alle anderen Tests starten direkt eingeloggt
API-Mocking mit route()
// Prompt: "Mocke externe API-Calls in Playwright-Tests"
test('Dashboard zeigt Daten aus API', async ({ page }) => {
// API-Request intercepten und Mock-Daten zurückgeben:
await page.route('**/api/dashboard/stats', route => {
route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
revenue: 12500,
users: 342,
growth: 15.3,
}),
});
});
await page.goto('/dashboard');
await expect(page.getByText('12.500 €')).toBeVisible();
await expect(page.getByText('342 Nutzer')).toBeVisible();
});
// API-Fehler simulieren:
test('zeigt Fehler-State bei API-Ausfall', async ({ page }) => {
await page.route('**/api/**', route => route.fulfill({ status: 500 }));
await page.goto('/dashboard');
await expect(page.getByText('Fehler beim Laden')).toBeVisible();
});
// Request abfangen und modifizieren:
await page.route('**/api/users', async route => {
const response = await route.fetch();
const json = await response.json();
json.users.push({ id: 'test', name: 'Test User' });
await route.fulfill({ response, json });
});
Visual Regression Testing
VisualScreenshot-Vergleiche automatisieren
// Prompt: "Visual Tests für alle UI-Komponenten"
test('Button-Komponente — alle Varianten', async ({ page }) => {
await page.goto('/storybook/button');
// Ganzseitiger Screenshot-Vergleich:
await expect(page).toHaveScreenshot('button-variants.png', {
fullPage: true,
threshold: 0.1, // 10% Toleranz für Anti-Aliasing
});
});
test('Dashboard im Dark Mode', async ({ page }) => {
await page.emulateMedia({ colorScheme: 'dark' });
await page.goto('/dashboard');
await page.waitForLoadState('networkidle');
await expect(page).toHaveScreenshot('dashboard-dark.png');
});
# Screenshots initial erstellen (Baseline):
npx playwright test --update-snapshots
# Vergleichen (CI):
npx playwright test
# Diff-Report bei Unterschieden:
npx playwright show-report
Playwright Prompt-Tipp: "Erstelle einen vollständigen E2E-Test für den Checkout-Flow: Produkt auswählen → Warenkorb → Bezahlen → Bestätigungsseite. Mocke Stripe-API-Calls." Claude Code schreibt den kompletten Test inkl. API-Mocking, Assertions und Fehler-Szenarien.
Testing-Modul im Kurs
Im Claude Code Mastery Kurs: vollständiges Playwright-Modul mit Page Objects, Auth-State, API-Mocking, Visual Tests, Component Testing und CI-Integration — inkl. Testdaten-Management und Parallel-Optimierung.
14 Tage kostenlos testen →