Skip to main content

Playwright-Tests mit GitHub Actions in Ihre Pull-Request-CI integrieren

Artikel von
feature playwright gh actions

14. Oktober 2022

0 Min. Lesezeit

Wenn es Ihnen wie mir geht, wissen Sie einen automatisierten Testschritt als Teil Ihrer Pull-Request-(PR-)CI zu schätzen, denn er gibt Ihnen zusätzliche Sicherheit, bevor Sie Code zusammenführen. Ich zeige Ihnen, wie Sie Playwright-Tests zu Ihren PRs hinzufügen und alles mit einem GitHub-Actions-CI-Workflow verbinden.

Falls Sie noch nicht mit Playwright zu tun hatten: Das Playwright-Testautomatisierungs-Framework wurde erstmals 2017 veröffentlicht, erfreut sich aber in letzter Zeit als weiteres Entwickler-Tool von Microsoft großer Beliebtheit (neben Visual Studio Code und anderen).

Das Playwright-Testautomatisierungs-Framework eignet sich hervorragend, um ganz einfach End-to-End-Tests (E2E) zu schreiben und auch die browserübergreifende Kompatibilität zu prüfen. Ich habe früher sowohl Selenium als auch Cypress verwendet. Wenn Sie ähnliche Erfahrungen gemacht haben, wird Playwright Sie sicher an Letzteres erinnern. Der Einstieg und das Schreiben von Tests sind einfach, und integrierte Maßnahmen sorgen dafür, dass Tests nicht unzuverlässig sind.

In diesem Artikel erfahren Sie:

  • Die Grundlagen zum Schreiben von End-to-End-Tests mit Playwright

  • So führen Sie Playwright-Tests in Ihrer GitHub-Actions-CI aus

  • So führen Sie Playwright-Tests für Ihre bereitgestellten Netlify-Preview-URLs aus

  • So bewahren Sie Playwright-Debug-Traces auf und stellen sie als Build-Artefakte in der GitHub-Actions-CI bereit

Ein Hinweis, bevor wir loslegen: Dieses Playwright-Tutorial konzentriert sich auf JavaScript. Sie können es aber problemlos auf andere Projekte anwenden, etwa auf ein Playwright-Python-Projekt, denn es geht hauptsächlich darum, wie Sie Playwright in die CI integrieren, und nicht darum, fortgeschrittene Playwright-Tests zu schreiben. Wenn Sie mit Java arbeiten, gibt es sogar ein Playwright-Java-SDK.

Playwright zu einem Projekt hinzufügen und testen

Wir fügen Playwright zu einem bestehenden JavaScript-Projekt hinzu. Dafür sind folgende Schritte nötig:

  1. Installieren Sie das Playwright-npm-Paket: npm install @playwright/test --dev

  2. Fügen Sie einen npm-Lifecycle-Hook speziell für die Playwright-End-to-End-Tests hinzu.

Die Änderungen sehen dann in Ihrer Datei package.json wie folgt aus. Der Ausschnitt sollte ungefähr so aussehen, wenn er zusammen mit den übrigen Inhalten und der Konfiguration im Paketmanifest steht:

  “scripts”: {
    "test:e2e": "playwright test"
  },

  "devDependencies": {
    "@playwright/test": "^1.22.2",
   }

Anschließend können wir an folgendem Speicherort eine neue Playwright-Testdatei hinzufügen: ./e2e/home.spec.ts. Dazu erstellen wir im Projektstammverzeichnis ein neues Verzeichnis e2e/, sofern es noch nicht vorhanden ist.

Fügen Sie den folgenden Codeausschnitt als vereinfachtes Playwright-Beispiel für einen End-to-End-Test hinzu. Er richtet einen Playwright-Testfall ein, der die URL http://localhost:3000 aufruft und überprüft, ob der Titel der Website (häufig über das HTML-Element <title> definiert) mit der Zeichenfolge Dogs security blog übereinstimmt. Ein Playwright-Beispiel:

import { test, expect } from '@playwright/test';

test('page should have title of "Dogs security blog"', async ({ page }) => {
  await page.goto('http://localhost:3000/');
  const title = await page.title();
  expect(title).toBe(“Dogs security blog”);
});

Wenn Sie Playwright-Automatisierung zum ersten Mal in Ihren Stack integrieren, sollten die obige package.json-Konfiguration und der Codeausschnitt für ./e2e/home.spec.ts ausreichen, um mit einem funktionierenden Playwright-Beispiel loszulegen.

Stellen Sie sicher, dass der Server oder die Webanwendung Anfragen entgegennimmt. Führen Sie dann den Befehl npm run test:e2e aus, um zu überprüfen, ob die Playwright-Tests erfolgreich ausgeführt und abgeschlossen werden können.

Die Testausgabe von Playwright sollte in etwa so aussehen:

npm run test:e2e

> the-snyk-blog@0.1.0 test:e2e
> playwright test

Running 1 test using 1 worker

  ✓  e2e/home.spec.ts:3:1 › page should have title of "Dogs security blog" (4s)

  1 passed (14s)

Juhu! Unser Playwright-Test funktioniert!

Playwright-Automatisierung mit GitHub Actions

Als Nächstes richten wir unsere kontinuierliche Integration (CI) ein. So werden Tests ausgeführt, wenn neue Code-Beiträge für unser Projekt erstellt werden – von uns selbst oder von externen Mitwirkenden. Dadurch können wir sicherstellen, dass Beiträge keine vorhandene Funktionalität beeinträchtigen.

Wenn Sie Ihre Projekte auf GitHub verwalten, ist die Verwendung von GitHub Actions als CI/CD-Workflow ganz einfach, da die Funktion bereits in die Plattform integriert ist. Richten wir sie so ein, dass neue Code-Beiträge über PRs unseren Playwright-Testworkflow auslösen und eine End-to-End-CI-Pipeline durchlaufen.

Zunächst richten wir Playwright mit einer vordefinierten Konfiguration ein, die Playwright anweist, im Hintergrund einen Befehl zum Starten unseres Servers auszuführen. Anschließend können wir die URL in der Konfiguration hinterlegen, statt sie wie zuvor im Playwright-Testcode fest einzutragen.

Fügen Sie den folgenden Inhalt in Ihrem JavaScript-Projektstammverzeichnis (dort, wo sich Ihre Datei package.json befindet) einer neuen Datei namens playwright.config.ts hinzu:

import { PlaywrightTestConfig } from '@playwright/test';

const config: PlaywrightTestConfig = {
  webServer: {
    command: 'npm run start',
    url: 'http://localhost:3000',
  },
};

export default config;

Wenn Ihr lokaler Webserver einen anderen Port verwendet, müssen Sie die obige Einstellung url entsprechend anpassen und sicherstellen, dass Playwright im CI-Umfeld darauf zugreifen kann.

Beachten Sie außerdem: Je nachdem, wie Ihr Projekt erstellt wird, müssen Sie möglicherweise den npm-Lifecycle-Hook start in package.json wie folgt anpassen. Dabei wird vor dem Starten des Servers npm run build ausgeführt:

    "start": "npm run build && next start",

Anschließend können wir einen Playwright-GitHub-Actions-Workflow erstellen.

Fügen Sie den folgenden Inhalt einer neuen Datei unter diesem Pfad hinzu: .github/workflows/e2e-ci.yml:

name: "Tests: E2E"
on: [pull_request]
jobs:
  tests_e2e:
    name: Run end-to-end tests
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
      - name: install dependencies
        run: npm ci
      - name: install playwright browsers
        run: npx playwright install --with-deps
      - name: npm run test:e2e
        run: npm run test:e2e=

Das war’s!

Öffnen Sie in Ihrem GitHub-Repository einen neuen PR und überprüfen Sie, ob der Workflow tests_e2e wie erwartet ausgeführt wird und alle Tests bestehen.

Beachten Sie: Vielleicht haben Sie in Playwright-Tutorials oder -Artikeln schon Verweise auf das Playwright-GitHub-Actions-Repository (https://github.com/microsoft/playwright-github-action) oder direkt auf die Action microsoft/playwright-github-action@v1 gesehen. Diese sind jedoch nicht mehr erforderlich. Die offizielle GitHub Action ist veraltet. Stattdessen wird die playwright-CLI installiert und verwendet, wie wir es oben mit npm getan haben.

Playwright-Tests für bereitgestellte Netlify-Preview-URLs ausführen

Wenn Sie Netlify verwenden, um Ihr Frontend-Projekt zu erstellen und den clientseitigen Build auf einer aktiven Website bereitzustellen, profitieren Sie außerdem von Netlify Previews, die in Ihre PRs integriert sind. Jedes Mal, wenn ein neuer Pull Request erstellt oder geändert wird, stellt Netlify das Projekt unter einer URL bereit. So können Sie den Zustand und die Qualität des Frontend-Builds für diesen PR ansehen und testen.

Eine native GitHub-Integration mit dem Netlify-Bot sieht etwa so aus:

Dunkle Netlify-Bot-Benachrichtigung: Eine Deploy-Vorschau ist bereit. Mit Links zum neuesten Commit, Deploy-Log, zur Vorschau und zum mobilen QR-Code.

Um unseren Playwright-Test für eine Netlify-Preview-URL auszuführen, müssen wir Folgendes tun:

  1. Aktualisieren Sie die Basis-URL in der Playwright-Konfiguration so, dass sie dynamisch festgelegt werden kann oder für lokal ausgeführte Playwright-Tests (in unserer Entwicklungsumgebung oder in der CI) auf den Standardwert localhost:3000 zurückfällt.

  2. Ermitteln Sie die PR-Nummer. Anhand dieser Nummer identifiziert Netlify den Frontend-Build und erstellt dafür eine eindeutige URL.

  3. Warten Sie, bis die Netlify-Preview-URL verfügbar ist.

  4. Führen Sie unseren Playwright-End-to-End-Test für die Netlify-Preview-URL aus.

Aktualisieren wir zunächst die Playwright-Konfigurationsdatei:

import { PlaywrightTestConfig } from '@playwright/test';

const config: PlaywrightTestConfig = {
    use: {
        baseURL: process.env.PLAYWRIGHT_TEST_BASE_URL || 'http://localhost:3000'
    },
    webServer: {
        command: "npm run start"
    }
};

export default config;

Mit dieser Konfiguration können wir die Umgebungsvariable PLAYWRIGHT_TEST_BASE_URL dynamisch in unserer Umgebung oder in der CI festlegen.

Als Nächstes müssen wir auch den Playwright-Testfall aktualisieren: Statt die URL fest einzutragen, verwenden wir die baseURL aus der obigen Konfigurationsdatei. Aktualisieren Sie Ihre Testdatei ./e2e/home.spec.ts wie folgt:

import { test, expect } from '@playwright/test';

test('page should have title of "Dogs security blog"', async ({page, baseURL}) => {
  await page.goto(baseURL);
  const title = await page.title();
  expect(title).toBe(“Dogs security blog”);
});

Aktualisieren Sie zum Schluss die Datei .github/workflows/e2e-ci.yml um zwei neue Schritte: Einer verwendet eine GitHub Action, um zu warten, bis die bereitgestellte URL verfügbar ist, der andere führt die Tests dafür aus. Als Referenz finden Sie hier den gesamten Workflow-Dateiinhalt:

name: "Tests: E2E"

on: [pull_request]

env:
  GITHUB_PR_NUMBER: ${{github.event.pull_request.number}}

jobs:
  tests_e2e:
    name: Run end-to-end tests
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
      - name: install dependencies
        run: npm ci
      - name: install playwright browsers
        run: npx playwright install --with-deps
      - name: npm run test:e2e
        run: npm run test:e2e

  tests_e2e_netlify_prepare:
    name: Wait for deployment on Netlify
    runs-on: ubuntu-latest
    steps:
      - name: Waiting for Netlify Preview
        uses: josephduffy/wait-for-netlify-action@v1
        id: wait-for-netflify-preview
        with:
          site_name: "pull-request"
          max_timeout: 180

  tests_e2e_netlify:
    needs: tests_e2e_netlify_prepare
    name: Run end-to-end tests on Netlify PR preview
    runs-on: ubuntu-latest
    timeout-minutes: 5
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
      - name: install dependencies
        run: npm ci
      - name: install playwright browsers
        run: npx playwright install --with-deps
      - name: npm run test:e2e
        run: npm run test:e2e
        env:
          PLAYWRIGHT_TEST_BASE_URL: "https://deploy-preview-${{env.GITHUB_PR_NUMBER}}--pull-request.netlify.app/"
          DEBUG: pw:api

Beachten Sie, dass Sie für den zweiten Schritt mit der Kennung tests_e2e_netlify_prepare ein Timeout Ihrer Wahl festlegen können. In diesem Beispiel habe ich drei Minuten eingestellt.

Der dritte Schritt mit der Kennung tests_e2e_netlify ähnelt dem lokal ausgeführten Playwright-Test (den wir als ersten Schritt dieses Workflows beibehalten haben). Er enthält jedoch eine zusätzliche Konfiguration mit der Umgebungsvariable PLAYWRIGHT_TEST_BASE_URL, die wir dynamisch festlegen und für die erwartete bereitgestellte Netlify-Preview-URL formatieren.

Außerdem habe ich die Playwright-Debug-Funktionen ausdrücklich aktiviert, um ausführlichere Ausgaben zu erhalten. Dazu habe ich dem letzten Workflowschritt die neue Umgebungsvariable DEBUG: pw:api hinzugefügt.

Öffnen Sie einen neuen PR und überprüfen Sie, ob Ihr End-to-End-Testworkflow erfolgreich abgeschlossen wird:

GitHub-Actions-Workflow mit zwei erfolgreichen Playwright-End-to-End-Tests in Netlify-Pull-Request-Vorschauen.

Herzlichen Glückwunsch! Sie haben eine robuste Playwright-End-to-End-Testautomatisierung erstellt und nahtlos in die kontinuierliche Integration Ihres Projekts mit GitHub Actions eingebunden.

Playwright-Debugging in der CI einrichten

Playwright macht das Debugging von Tests mit mehreren integrierten Funktionen besonders einfach. Dazu gehört zunächst der Playwright Inspector: eine grafische Benutzeroberfläche, mit der Sie HTML-Elemente untersuchen und Ihre Playwright-Testfälle Schritt für Schritt debuggen können. Eine weitere integrierte Funktion ist der Playwright Trace Viewer, mit dem Sie einen aufgezeichneten Test erneut abspielen können.

Der Playwright Trace Viewer ist besonders nützlich, wenn Tests unzuverlässig sind, also nicht deterministisch ablaufen und sich nur schwer reproduzieren lassen. Bei solchen Problemen mit Ihren End-to-End-Tests können Sie eine Playwright-Debug-Funktion aktivieren, die alle Interaktionen protokolliert und in einer Datei speichert. Anschließend können Sie diese Datei im Playwright Trace Viewer laden und untersuchen, warum der Playwright-Test fehlgeschlagen ist.

Machen wir dort weiter, wo wir aufgehört haben, und richten den CI-Workflow so ein, dass Playwright Traces aufzeichnet. So können wir später auf diese Dateien zugreifen.

Mit der offiziellen GitHub Action actions/upload-artifact können wir Dateien oder Verzeichnisinhalte aus Builds aufbewahren und als Artefakte speichern. Beachten Sie jedoch: Verwenden Sie diese Methode nicht, um Protokolldateien oder andere Daten zu speichern, die vertrauliche Informationen enthalten könnten, da diese öffentlich für alle zugänglich sind.

Wir fügen dem vorhandenen lokalen End-to-End-Testjob mit der Job-ID tests_e2e den folgenden Schritt hinzu:

      - name: Upload test results
        if: always()
        uses: actions/upload-artifact@v2
        with:
          name: playwright-report
          path: test-results

Sie können diesen Schritt auch zu anderen Schritten für Playwright-Debugging in anderen CI-Workflows hinzufügen, etwa beim Testen der Netlify-Preview-URL.

Aktualisieren Sie anschließend Ihre Datei .gitignore, damit diese Trace-Dateien nicht in das Repository übernommen werden. Fügen Sie dazu Folgendes in die Datei ein:

test-results/

Aktualisieren Sie zum Schluss die Playwright-Konfigurationsdatei playwright.config.ts, um das Tracing zu aktivieren. Mit der Ergänzung sollte sie wie folgt aussehen:

import { PlaywrightTestConfig } from '@playwright/test';

const config: PlaywrightTestConfig = {
  webServer: {
    command: 'npm run start'
  },
  use: {
    trace: 'on',
  },
};

export default config;

Das war’s. Vielleicht fragen Sie sich aber, wo Sie das Debug-Artefakt finden.

Auf CI-Artefakte greifen Sie im Tab Summary einer GitHub-Actions-Ausführung zu. Im folgenden Screenshot sehen Sie das Artefakt unten im Job, der in meiner CI erfolgreich abgeschlossen wurde:

GitHub-Actions-Workflow mit erfolgreichen End-to-End-Tests und einem Playwright-Report-Artefakt.

An dieser Stelle möchte ich darauf hinweisen, dass wir bei jedem Build eine Playwright-Debug-Trace-Datei erstellen – unabhängig davon, ob der Build erfolgreich abgeschlossen wurde. Die CI-Konfiguration weist dies an, weil wir im obigen Schritt des Jobs tests_e2e die Direktive if: always() verwendet haben.

Um die Trace-Datei anzusehen, können Sie das Artefakt jetzt herunterladen, in einen lokalen Ordner entpacken und die Playwright-Debug-Informationen darin als Archivdatei finden. Mit der Playwright-eigenen CLI können Sie sie ganz einfach wie folgt ausführen:

npx playwright show-trace <my-directory>/my-trace.zip

Playwright im Vergleich zu Cypress

Wenn Sie Cypress bereits verwendet haben, wird Ihnen das Playwright-Automatisierungstool vertraut vorkommen – sowohl im Hinblick auf die CLI als auch auf die grafische Benutzeroberfläche zum Untersuchen und Debuggen von Playwright-Tests sowie die allgemeinen Sprachmechanismen.

Wie funktioniert Playwright?

Anders als Cypress, ein weiteres Testautomatisierungstool, das sich als Bibliothek in das DOM der Webseite einbindet und den Browser auf diese Weise steuert, nutzt Playwright native Browser-APIs zur Automatisierung. Beispielsweise verwendet es Chrome CDP als Remote-Debugging-Protokoll, um mit einem Chrome-Browser zu kommunizieren. Außerdem unterstützt Playwright alle wichtigen Browser wie Chrome, Firefox, Edge und WebKit und bietet ähnliche Funktionen wie Cypress, etwa Test-Resilienz: Elemente und Aktionen werden automatisch abgewartet, um fehleranfällige Tests zu vermeiden.

Was ist Playwright-Automatisierung?

Playwright ist ein Open-Source-Projekt von Microsoft, das ein Framework für End-to-End-Tests mit Unterstützung für mehrere Browser bereitstellt. Es nutzt die APIs nativer Browser-Automatisierungsframeworks, um Browser zu steuern und mit ihnen zu interagieren, und bietet sprachübergreifende SDKs für die Playwright-API. Zu den besonderen Vorteilen zählen neben dem Open-Source-Ansatz und der kostenlosen Nutzung die Resilienz (zur Vermeidung fehleranfälliger Tests), die vollständige Browser-Automatisierung, Tracing und Debugging.

Playwright-Testautomatisierung: mehr erfahren

Wenn Ihnen dieser Artikel gefallen hat und Sie Ihr Wissen zu Playwright vertiefen möchten, empfehle ich Ihnen folgende Ressourcen:

  • Die Dokumentation zu Playwright unter https://playwright.dev ist hervorragend. Sie enthält spezielle Abschnitte wie Playwright debug und bietet Playwright-Beispiele, mit denen Entwicklerinnen und Entwickler schnell mit diesem Testframework loslegen können.

  • Für Neuigkeiten, Tutorials und weitere Inhalte für Playwright-Entwicklerinnen und -Entwickler empfehle ich Ihnen sehr, Debbie O'Brien auf Twitter zu folgen. Sie ist Programmmanagerin für Playwright bei Microsoft und spricht regelmäßig auf Veranstaltungen darüber.

Weitere Ressourcen

Gepostet in: