Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Hands-on Playwright – E2E-Testing für Einsteige...

Hands-on Playwright – E2E-Testing für Einsteiger:innen

JavaScript & Angular Days Berlin, 12. Oktober 2026. In diesem halbtägigen Workshop lernst du, wie du mit Playwright stabile und effektive End-to-End-Tests für Webanwendungen erstellst. Wir richten Playwright von Grund auf ein und schreiben gemeinsam erste eigene Tests — ohne dass Vorkenntnisse erforderlich sind. Neben der Erstellung stabiler und verständlicher Tests steht das praxisnahe Arbeiten im Vordergrund: von grundlegenden Testabläufen über den Umgang mit verschiedenen Browsern bis hin zu Screenshots und paralleler Testausführung.

Avatar for Daniel Sogl

Daniel Sogl PRO

October 12, 2026

More Decks by Daniel Sogl

Other Decks in Programming

Transcript

  1. Playwright Workshop Modernes E2E-Testing leicht gemacht Daniel Sogl Head of

    AI Engineering & Developer Productivity · SHI GmbH Angular Days Berlin 2 × 90 Minuten
  2. Daniel Sogl Head of AI Engineering & Developer Productivity ·

    SHI GmbH Verantwortet KI-Engineering und Developer Productivity bei der SHI GmbH Schwerpunkte: Web, TypeScript, Testautomatisierung und generative KI Microsoft MVP für Developer & Web Technologies Tech Speaker und Workshop-Trainer Playwright TypeScript [email protected] Playwright Workshop SHI GmbH AI Engineering sogldaniel danielsogl 2 / 64
  3. Was du heute mitnimmst Schreiben Debuggen Strukturieren Mocken Stabile Tests

    mit UI Mode und Trace Fixtures und Page Backend per Locators und Assertions Viewer statt Raten Objects page.route() ersetzen Theorie in kleinen Häppchen, viel Live-Coding, vier Übungen zum Selbermachen. Playwright Workshop SHI GmbH 3 / 64
  4. Ablauf Session 1 · Tests schreiben & debuggen Session 2

    · Struktur, Mocking & KI Codegen & erster Test Fixtures & Page Objects Übung: Test aufnehmen Übung: Page Objects als Fixtures Locators & Assertions API-Mocking mit page.route() Übung: Locators aufräumen Übung: Backend mocken Fehler finden im Trace Viewer Ausblick: KI & Playwright Playwright Workshop SHI GmbH 4 / 64
  5. Das Projekt: die Demo-App Startseite Public News Suche API Liste

    & Filter Trefferzähler wird gemockt Alle Übungen bauen auf derselben App auf. Zurückgefallen? Jede Übung hat einen Startbranch mit allen früheren Lösungen. Playwright Workshop SHI GmbH 5 / 64
  6. Setup-Check 1 node -v # 22, 24 oder 26 2

    cd playwright-workshop 3 npm install 4 npx playwright test # startet die App selbst 5 npm run dev # App unter localhost:3000 Es hakt? Hand heben, wir klären es sofort. Playwright Workshop SHI GmbH 7 / 64
  7. Was ist Playwright? Open Source Drei Engines Fünf Sprachen Von

    Microsoft seit 2020, gebaut Chromium, Firefox und WebKit TypeScript und JavaScript, vom früheren Puppeteer-Team Python, .NET, Java Playwright spricht direkt mit dem Browser: CDP für Chromium, eigene Protokolle für Firefox und WebKit. Playwright Workshop SHI GmbH 9 / 64
  8. Warum Playwright? Schnell Cross-Browser Tooling TypeScript Parallel und isoliert, Chromium,

    Firefox Codegen, UI Mode Typen, Autocomplete Auto-Waiting gegen Flakiness und WebKit mit einer API und Trace Viewer inklusive und eigener TestRunner Kein Selenium-Grid, keine Treiber: npm init playwright@latest und los. Playwright Workshop SHI GmbH 10 / 64
  9. Mehr im Paket Netzwerk Mobile Moderne Apps KI-Tooling Requests abfangen,

    Geräteprofile, SPAs, Shadow DOM Test Agents, MCP- APIs mocken Viewports, Touch und iframes Server und CLI Jeder Test läuft in einem eigenen Browser-Context und beeinflusst die anderen nicht. Playwright Workshop SHI GmbH 11 / 64
  10. Test aufnehmen mit Codegen 1 npx playwright codegen http://localhost:3000 1

    2 3 Klicken Prüfen Übernehmen Aktionen im Browser ausführen Assertions per Toolbar ergänzen Code in die Spec kopieren und aufräumen Playwright Workshop SHI GmbH 12 / 64
  11. Die Codegen-Toolbar Assert Pick Locator Aria-Snapshot Record Sichtbarkeit, Text und

    Element anklicken, Ganze Bereiche für Aufnahme pausieren, Wert per Klick prüfen Locator nach Priorität übernehmen toMatchAriaSnapshot() um ohne neuen Code zu navigieren aufnehmen Codegen liefert einen Startpunkt. Locators prüfen, fachliche Assertions selbst ergänzen. Playwright Workshop SHI GmbH 13 / 64
  12. Codegen-Optionen 1 # Gerät und Farbschema emulieren 2 npx playwright

    codegen --device="iPhone 13" \ 3 --color-scheme=dark localhost:3000 4 5 # Login speichern, später eingeloggt starten 6 npx playwright codegen --save-storage=auth.json \ 7 8 9 localhost:3000/auth/signin npx playwright codegen --load-storage=auth.json \ localhost:3000 Mit gespeichertem Login nimmst du geschützte Seiten auf, ohne dich jedes Mal anzumelden. Playwright Workshop SHI GmbH 14 / 64
  13. Dein erster Test 1 import { test, expect } from

    '@playwright/test'; 2 3 test('öffnet die News', async ({ page }) => { 4 await page.goto('/'); 5 await page 6 .getByRole('link', { name: 'View Public News' }) 7 .click(); 8 9 await expect(page).toHaveURL('/news/public'); }); page ist eine Fixture: frisch pro Test, automatisch aufgeräumt. Playwright Workshop SHI GmbH 15 / 64
  14. Tests gruppieren 1 2 test.describe('Startseite', () => { test.beforeEach(async ({

    page }) => { 3 4 await page.goto('/'); }); 5 6 test('hat den richtigen Titel', async ({ page }) => { 7 await expect(page).toHaveTitle(/Playwright Demo/); 8 9 }); }); Mit test.step('Name', async () => …) benennst du Abschnitte für Report und Trace. Playwright Workshop SHI GmbH 16 / 64
  15. Tests ausführen 1 npx playwright test # headless, alle Projekte

    2 npx playwright test --ui # UI Mode 3 npx playwright test --headed # sichtbarer Browser 4 npx playwright test --debug # Inspector, Schritt für Schritt 5 npx playwright test -g "News" # nur passende Tests 6 npx playwright test --project chromium 7 npx playwright show-report # HTML-Report Im Alltag reicht --ui : Watch Mode, Filter und Time-Travel in einem Fenster. Playwright Workshop SHI GmbH 17 / 64
  16. Debuggen statt Raten UI Mode Inspector Trace Viewer Time-Travel durch

    jeden Schritt, Schritt für Schritt ausführen, Aufzeichnung für Fehler, die nur DOM-Snapshot, Locator-Picker Actionability-Log lesen in CI auftreten await page.pause() im Test hält an und öffnet den Inspector. Playwright Workshop SHI GmbH 18 / 64
  17. Übung 1b: Test mit Codegen aufnehmen 15 Min. git switch

    ex/01b-codegen exercises/01b-codegen.md 1 · Starten 2 · Aufnehmen App mit npm run dev starten, dann npx „View Public News“ playwright codegen localhost:3000 Kategorie „Technology" 3 · Prüfen 4 · Ausführen Per Toolbar Assertions für Überschrift, Suchfeld und Trefferzähler Code nach e2e/01b-codegen.spec.ts , dann npx Playwright Workshop SHI GmbH → „Playwright“ suchen → playwright test --ui 19 / 64
  18. Übung 1b: Tipps App muss laufen Codegen startet keinen Server.

    npm run dev im zweiten Terminal. baseURL nutzen Codegen schreibt http://localhost:3000/ . Ersetze das durch / . Hängst du fest? Mögliche Aufnahme: git switch ex/02-locators Playwright Workshop SHI GmbH 20 / 64
  19. Locators: in dieser Reihenfolge 1 getByRole So sieht es der

    Nutzer und der Screenreader 2 getByLabel · getByText Formularfelder und sichtbarer Text 3 getByTestId Stabiler Vertrag, wenn nichts anderes passt 4 CSS · XPath Letzter Ausweg Playwright Workshop SHI GmbH 23 / 64
  20. Locators in der Praxis 1 page.getByRole('button', { name: 'Search' });

    2 page.getByLabel('Search news articles'); 3 page.getByRole('article') 4 .filter({ hasText: 'Technology' }); Pick Locator Im UI Mode auf das Element zeigen, Playwright schlägt den Locator vor. Playwright Workshop SHI GmbH 24 / 64
  21. Locators präzisieren 1 page.getByRole('button', { name: 'Save', exact: true });

    2 3 // Name für Trace und Report (ab v1.53) 4 page.getByRole('textbox', { name: 'Search news articles' }) 5 .describe('Suchfeld'); Playwright Workshop SHI GmbH 25 / 64
  22. Auto-Waiting vor jeder Aktion Eindeutig Sichtbar genau ein Treffer Stabil

    keine Animation Empfängt Events Aktiviert nicht verdeckt Die Checks hängen von der Aktion ab. fill() prüft zusätzlich, ob das Feld editierbar ist. Playwright Workshop SHI GmbH 26 / 64
  23. Web-first Assertions ✅ wartet, bis die Bedingung erfüllt ist (Standard:

    5 s) 1 // 2 await expect(heading).toBeVisible(); 3 ❌ prüft genau einmal – häufigste Ursache für flaky Tests 4 // 5 expect(await heading.isVisible()).toBe(true); Faustregel: expect bekommt einen Locator, keinen Wert. Playwright Workshop SHI GmbH 27 / 64
  24. Die wichtigsten Assertions 1 await expect(page).toHaveURL('/news/public'); 2 await expect(articles).toHaveCount(20); 3

    await expect(searchField).toHaveValue('Playwright'); 4 await expect(counter).toHaveText(/\d+ articles found/); 5 await expect(alert).toBeHidden(); Kein waitForTimeout Feste Wartezeiten sind langsam und trotzdem flaky. Playwright Workshop SHI GmbH 28 / 64
  25. Weitere Matcher Sichtbarkeit Inhalt toBeVisible , toBeAttached , toBeInViewport toContainText

    , toHaveAttribute , toHaveClass , toHaveCSS Formular Barrierefreiheit toBeChecked , toBeEnabled , toBeEditable , toHaveRole , toHaveAccessibleName , toBeFocused toMatchAriaSnapshot Playwright Workshop SHI GmbH 29 / 64
  26. Übung 2b: Locators aufräumen 20 Min. git switch ex/02b-locators-aufraeumen exercises/02b-locators-aufraeumen.md

    1 · Anlegen 2 · Picken 3 · Umstellen Startcode in e2e/02blocators-aufraeumen.spec.ts In Codegen oder im UI Mode „Pick locator“ auf jedes Element Jedes page.locator('…') durch getByRole , getByLabel kopieren und ausführen anwenden oder getByText ersetzen 4 · Vergleichen Alles zusammen Bonus Welche Locators hat Codegen in deinem Test aus Übung 1b Kein page.locator( mehr, Test in allen Browsern grün Klasse text-sm des Trefferzählers ändern: gewählt? Playwright Workshop Startcode rot, dein Test grün SHI GmbH 30 / 64
  27. Übung 2b: Startcode 1 test('News suchen', async ({ page })

    => { 2 await page.goto('/'); 3 await page.locator('a.bg-accent').click(); 4 await expect(page.locator('h1')).toHaveText('News Feed'); 5 await expect(page.locator('div[role=feed] > article').first()).toBeVisible(); 6 await page.locator('#search-news').fill('Playwright'); 7 await page.locator('#filter-category').selectOption('Technology'); 8 await expect(page.locator('p.font-mono.text-sm')).toContainText('found'); 9 }); Der Test ist grün, hängt aber an CSS-Klassen, IDs und DOM-Struktur. Playwright Workshop SHI GmbH 31 / 64
  28. Übung 2b: Tipps Rollen und Labels Die Artikel haben die

    Rolle article , Suchfeld und Kategorie ein aria-label . Trefferzähler Ein RegExp passt für Ein- und Mehrzahl: getByText(/\d+ articles? found/) . Hängst du fest? Musterlösung: git switch ex/03-interaktionen Playwright Workshop SHI GmbH 32 / 64
  29. Übung 2b: Lösung 1 test('News suchen', async ({ page })

    => { 2 await page.goto('/'); 3 await page.getByRole('link', { name: 'View Public News' }).click(); 4 await expect(page.getByRole('heading', { name: 'News Feed' })).toBeVisible(); 5 await expect(page.getByRole('article').first()).toBeVisible(); 6 await page.getByLabel('Search news articles').fill('Playwright'); 7 await page.getByLabel('Filter news by category').selectOption('Technology'); 8 await expect(page.getByText(/\d+ articles? found/)).toBeVisible(); 9 }); Gleicher Ablauf, aber jeder Locator beschreibt, was der Nutzer sieht. Playwright Workshop SHI GmbH 33 / 64
  30. Trace Viewer Mit trace: 'on-first-retry' in der Config: Aktionen, Netzwerk,

    Konsole und DOM zu jedem Schritt, auch nachträglich. Playwright Workshop SHI GmbH 35 / 64
  31. Trace öffnen 1 # aus dem HTML-Report 2 npx playwright

    show-report 3 4 # Datei oder URL direkt 5 npx playwright show-trace test-results/<lauf>/trace.zip 6 7 # lokal ohne Retries: Trace erzwingen 8 npx playwright test --trace on Ohne Installation: trace.playwright.dev, Datei per Drag & Drop. Die Daten bleiben im Browser. Playwright Workshop SHI GmbH 36 / 64
  32. Trace im Terminal (ab v1.59) 1 npx playwright trace open

    test-results/<lauf>/trace.zip 2 npx playwright trace actions # Aktionen auflisten 3 npx playwright trace action <id> # Details einer Aktion 4 npx playwright trace errors # Fehler mit Stacktrace 5 npx playwright trace requests # Netzwerk 6 npx playwright trace close # aufräumen Für CI-Logs und KI-Agenten: npx playwright trace install-skill legt eine SKILL.md an. Playwright Workshop SHI GmbH 37 / 64
  33. Rückblick & Ausblick Session 1 Jetzt Codegen & erster Test

    Fixtures & Page Objects Locators nach Rolle & Text API-Mocking mit page.route() Web-first Assertions Ausblick: KI & Playwright Trace Viewer Neu dazugekommen? Startbranch der nächsten Übung: git switch ex/10b-pom-fixtures Playwright Workshop SHI GmbH 39 / 64
  34. Fixtures Setup Test Teardown vor use() bekommt den Wert nach

    use() Eine Fixture bereitet vor, übergibt einen Wert und räumt danach auf. Eigene Fixtures ersetzen beforeEach -Wildwuchs. Playwright Workshop SHI GmbH 40 / 64
  35. Eingebaute Fixtures page context browser request Ein Tab, frisch pro

    Isolierter Browser- Eine Instanz pro HTTP-Client für API- Test Context pro Test Worker Aufrufe pro Test Außerdem: browserName , baseURL und playwright . Playwright Workshop SHI GmbH 41 / 64
  36. Page Object Model Test Page Object was geprüft wird wie

    man die Seite bedient App Ändert sich die UI, änderst du eine Klasse statt jeden Test. Playwright Workshop SHI GmbH 42 / 64
  37. Ein Page Object pro Seite HomePage News-Test NewsPage Playwright API

    Login-Test LoginPage Tests beschreiben Fachlogik, Page Objects kapseln die Seitenstruktur. Playwright Workshop SHI GmbH 43 / 64
  38. Page Object in der Praxis 1 export class NewsPage {

    2 constructor(readonly page: Page) {} 3 articles = () => this.page.getByRole('article'); 4 5 async searchFor(term: string) { 6 const search = this.page.getByLabel('Search news articles'); 7 await search.fill(term); 8 await search.press('Enter'); 9 10 } } Playwright Workshop SHI GmbH 44 / 64
  39. Page Object + Fixture 1 export const test = base.extend<{

    newsPage: NewsPage }>({ 2 newsPage: async ({ page }, use) => { 3 await use(new NewsPage(page)); 4 }, 5 }); 6 7 test('findet Artikel', async ({ newsPage }) => { 8 await newsPage.page.goto('/news/public'); 9 await newsPage.searchFor('Playwright'); 10 await expect(newsPage.articles()).not.toHaveCount(0); 11 }); Locators und Aktionen ins Page Object, Assertions in den Test. Playwright Workshop SHI GmbH 45 / 64
  40. Fixtures kombinieren mit mergeTests base pagesTest + authTest mergeTests @playwright/test

    Page Objects · Login per API ein test mit allem 1 import { mergeTests, expect } from '@playwright/test'; 2 import { test as pagesTest } from './fixtures/pages.fixture'; 3 import { test as authTest } from './fixtures/auth.fixture'; 4 5 const test = mergeTests(pagesTest, authTest); 6 7 test('Private News', async ({ authenticatedPage, homePage }) => { 8 await homePage.navigateTo('Private News'); 9 await expect(authenticatedPage).toHaveURL(/news\/private/); 10 }); Playwright Workshop SHI GmbH 46 / 64
  41. Best Practices Trennen Domänensprache Page Object bedient die Seite, der

    Test prüft. loginAsAdmin() statt fillEmailAndPassword() Weiterreichen Konvention navigateToNews() gibt das nächste Page Object Ob expect ins Page Object darf, entscheidet das Team. zurück. Playwright Workshop SHI GmbH 47 / 64
  42. Alternativen zum Page Object Component Object App Actions Kapselt UI-Komponenten

    statt Seiten: Header, Fachliche Aktionen wie app.login() , oft als Fixture Modal, Listeneintrag. Passt gut zu SPAs. mit Login per API. Playwright Workshop SHI GmbH 48 / 64
  43. Übung 10b: Page Objects als Fixtures 20 Min. git switch

    ex/10b-pom-fixtures exercises/10b-pom-fixtures.md 1 · Fixtures anlegen 2 · Tests schreiben Bonus homePage , newsPage , loginPage in Suche, Kategorie „Technology", falscher Login: ohne page , mergeTests mit der Auth- Fixture, eingeloggt zu „Private e2e/fixtures/pages.fixture.ts , ohne new …Page() News" Seite vor use() öffnen Playwright Workshop SHI GmbH 49 / 64
  44. Übung 10b: So sieht die Fixture aus 1 2 export

    const test = base.extend<{ newsPage: NewsPage }>({ newsPage: async ({ page }, use) => { 3 const newsPage = new NewsPage(page); 4 await newsPage.goto(); 5 await use(newsPage); 6 }, 7 }); 8 9 test('filtert', async ({ newsPage }) => { /* … */ }); Der Test startet auf der fertig geladenen Seite. Vorbereitung steht einmal in der Fixture. Playwright Workshop SHI GmbH 50 / 64
  45. Übung 10b: Tipps Trivial wahre Assertion Erst prüfen, dass ein

    Artikel sichtbar ist. Sonst ist toHaveCount(0) auch auf einer leeren Seite grün. Import tauschen Der Test importiert test und expect aus ./fixtures/pages.fixture , nicht aus @playwright/test . Hängst du fest? Musterlösung: git switch ex/11-api-mocking Playwright Workshop SHI GmbH 51 / 64
  46. API-Mocking Browser page.route() Mock-Antwort fängt ab statt Backend Schnell Deterministisch

    Fehlerfälle Kein echtes Backend nötig Immer dieselben Daten 500er, leere Listen, Latenz Playwright Workshop SHI GmbH 53 / 64
  47. page.route() in der Praxis 1 2 3 await page.route('**/api/news/public', (route)

    => route.fulfill({ json: { items: [mockArticle] } }), ); 4 5 await page.goto('/news/public'); Reihenfolge Route immer vor page.goto() registrieren. Playwright Workshop SHI GmbH 54 / 64
  48. Fehlerfälle simulieren 1 // Serverfehler 2 await page.route('**/api/news/public', (route) =>

    3 4 route.fulfill({ status: 500 }), ); 5 6 // Netzwerk weg 7 await page.route('**/api/news/public', (route) => route.abort()); Genau diese Fälle sind mit echtem Backend kaum testbar. Playwright Workshop SHI GmbH 55 / 64
  49. Ersetzen, durchreichen, abbrechen fulfill continue abort Eigene Antwort statt Backend

    Request verändert weiterschicken Request scheitert wie ohne Netz 1 2 await page.route('**/api/news/public', (route) => route.continue({ 3 4 5 headers: { ...route.request().headers(), 'x-test': '1' }, }), ); Playwright Workshop SHI GmbH 56 / 64
  50. Übung 11: API Mocking 30 Min. git switch ex/11-api-mocking exercises/11-api-mocking.md

    1 · Mock-Daten anlegen 2 · Erfolg prüfen 3 · Fehler liefern Zwei Artikel, leere Liste, Such- Genau 2 Artikel mit den Status 500 Feed in e2e/mocks/ gemockten Titeln sichtbar 4 · Leere Liste liefern 5 · Antwort verzögern Bonus „0 articles found", kein Artikel 2 s warten, Ladeanzeige erscheint und verschwindet Suche, Rate-Limit (429), hängende API Playwright Workshop SHI GmbH → Fehlermeldung 57 / 64
  51. Übung 11: Startcode 1 await page.route('**/api/news/public', async (route) => {

    2 // nur Aufgabe 5: Antwort verzögern 3 await new Promise((resolve) => setTimeout(resolve, 2000)); 4 await route.fulfill({ json: mockNewsData.success }); 5 }); 6 7 await page.goto('/news/public'); Mit json setzt Playwright den Content-Type selbst. Playwright Workshop SHI GmbH 58 / 64
  52. Übung 11: Tipps Route vor goto Sonst ist die echte

    Antwort schneller als dein Mock. Alert filtern getByRole('alert').filter({ hasText: … }) , sonst trifft der Locator die Ansage von Next.js. Hängst du fest? Musterlösung: git switch ex/12-waitforresponse Playwright Workshop SHI GmbH 59 / 64
  53. Drei Wege, KI mit Playwright zu nutzen Test Agents MCP

    Server CLI + Skills Planner, Generator, Healer: KI steuert den Browser über Schlanke Kommandos für Tests planen, schreiben, reparieren deine IDE Coding-Agents Die Test Agents sind das offizielle Setup für KI-Tests. MCP und CLI sind die Bausteine darunter. Playwright Workshop SHI GmbH 62 / 64
  54. Geschafft 🎉 Das kannst du jetzt Nächste Schritte Tests mit

    Codegen starten Erste Tests im eigenen Angular-Projekt Stabile Locators & Assertions Auth, Visual Testing, CI vertiefen Fehler im Trace Viewer finden KI: npx playwright init-agents Fixtures & Page Objects Übungen: Repo auf GitHub Netzwerk mocken Doku: playwright.dev Playwright Workshop SHI GmbH 63 / 64
  55. Vielen Dank! Fragen? Kommentare? Anregungen? Daniel Sogl Head of AI

    Engineering & Developer Productivity · SHI GmbH [email protected] linkedin.com/in/sogldaniel linktr.ee/daniel_sogl SHI GmbH Konrad-Adenauer-Allee 15 86150 Augsburg shi-gmbh.com