🌞 Letnia promocja na kursy online - zyskaj do -40% tylko do końca miesiąca!

Sprawdź promocję
Rafał Podraza
Wróć do bloga

6 lipca 2026

Jak uruchamiać testy Playwright w GitHub Actions?

Pisanie testów automatycznych to jedno, ale prawdziwa wartość zaczyna się wtedy, gdy testy uruchamiają się automatycznie po każdej zmianie w kodzie. W tym wpisie pokażę, jak połączyć Playwright z GitHub Actions i uruchamiać testy end-to-end w pipeline CI/CD.

Jak uruchamiać testy Playwright w GitHub Actions?

Jeżeli piszesz testy automatyczne w Playwright, to bardzo szybko dojdziesz do momentu, w którym samo uruchamianie ich lokalnie przestaje wystarczać.

Na początku wygląda to niewinnie.

Odpalasz testy na swoim komputerze, wszystko przechodzi, jest zielono, więc wydaje się, że temat jest ogarnięty. Problem pojawia się dopiero później, gdy ktoś inny zrobi zmianę w aplikacji, wrzuci pull requesta albo zdeployuje nową wersję i nagle okazuje się, że coś przestało działać.

Dlatego testy automatyczne powinny być uruchamiane nie tylko lokalnie, ale też w procesie CI/CD.

W tym wpisie pokażę Ci, jak uruchamiać testy Playwright w GitHub Actions.

Po co uruchamiać testy Playwright w GitHub Actions?

Najprościej mówiąc: żeby nie sprawdzać wszystkiego ręcznie po każdej zmianie.

GitHub Actions pozwala automatycznie uruchomić testy po pushu do repozytorium albo po utworzeniu pull requesta. Dzięki temu możemy szybciej wykryć, że jakaś zmiana zepsuła logowanie, koszyk, formularz kontaktowy, płatność albo inny ważny proces w aplikacji.

W praktyce wygląda to tak:

  1. Programista robi zmianę w kodzie.
  2. Zmiana trafia na GitHuba.
  3. GitHub Actions uruchamia workflow.
  4. Instalowane są zależności.
  5. Uruchamiają się testy Playwright.
  6. Po zakończeniu widzimy, czy testy przeszły, czy coś się wysypało.

I to jest dokładnie ten moment, w którym automatyzacja zaczyna mieć większy sens.

Bo testy nie są już tylko czymś, co tester uruchamia u siebie raz na jakiś czas. Stają się częścią procesu dostarczania aplikacji.

Przykładowy projekt Playwright

Zakładam, że masz już projekt z Playwrightem.

Jeżeli nie, możesz utworzyć go poleceniem:

npm init playwright@latest

Po instalacji w projekcie powinieneś mieć między innymi:

tests/
playwright.config.ts
package.json

Testy możesz lokalnie uruchomić poleceniem:

npx playwright test

Jeżeli wszystko działa lokalnie, możemy przejść do konfiguracji GitHub Actions.

Gdzie dodać konfigurację GitHub Actions?

W repozytorium utwórz katalog:

.github/workflows

A w nim plik, na przykład:

playwright.yml

Finalna ścieżka powinna wyglądać tak:

.github/workflows/playwright.yml

To właśnie w tym pliku opiszemy, kiedy i jak mają uruchamiać się nasze testy.

Prosty workflow dla Playwright

Na początek możemy przygotować bardzo prostą konfigurację:

name: Playwright Tests

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  test:
    name: Run Playwright tests
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 22

      - name: Install dependencies
        run: npm ci

      - name: Install Playwright browsers
        run: npx playwright install --with-deps

      - name: Run Playwright tests
        run: npx playwright test

      - name: Upload Playwright report
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: playwright-report
          path: playwright-report/
          retention-days: 7

I to jest już działająca podstawa.

Po dodaniu tego pliku do repozytorium GitHub Actions uruchomi testy po pushu do brancha main oraz po utworzeniu pull requesta do main.

Co robią poszczególne kroki?

Przejdźmy przez ten plik spokojnie, bo na początku YAML może wyglądać trochę dziwnie.

name: Playwright Tests

To jest nazwa workflow. Będzie widoczna w zakładce Actions na GitHubie.

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

Tutaj określamy, kiedy workflow ma się uruchamiać.

W tym przypadku testy uruchomią się po pushu do main oraz przy pull requestach kierowanych do main.

runs-on: ubuntu-latest

Ten fragment oznacza, że job zostanie uruchomiony na maszynie z Ubuntu. W większości przypadków do testów Playwright będzie to wystarczające.

uses: actions/checkout@v4

Ten krok pobiera kod repozytorium do środowiska GitHub Actions.

uses: actions/setup-node@v4

Tutaj instalujemy Node.js. W przykładzie używam wersji 22.

run: npm ci

To polecenie instaluje zależności projektu na podstawie pliku package-lock.json.

W CI lepiej używać npm ci zamiast npm install, ponieważ jest bardziej przewidywalne i lepiej pasuje do środowisk automatycznych.

run: npx playwright install --with-deps

Ten krok instaluje przeglądarki i zależności systemowe potrzebne do działania Playwrighta.

To ważne, bo na świeżej maszynie w GitHub Actions nie możemy zakładać, że wszystko będzie już gotowe.

run: npx playwright test

Tutaj uruchamiane są testy.

if: always()

Ten fragment przy uploadzie raportu oznacza, że raport ma zostać zapisany nawet wtedy, gdy testy zakończą się błędem.

I to jest bardzo ważne.

Bo jeżeli testy się wysypią, to właśnie wtedy najbardziej potrzebujemy raportu, screenshotów albo trace’ów.

Raport HTML z testów

Playwright domyślnie potrafi wygenerować raport HTML. Po wykonaniu testów raport może zostać zapisany jako artefakt w GitHub Actions.

W naszym workflow odpowiada za to ten fragment:

- name: Upload Playwright report
  uses: actions/upload-artifact@v4
  if: always()
  with:
    name: playwright-report
    path: playwright-report/
    retention-days: 7

Po zakończeniu workflow możesz wejść w konkretny run w GitHub Actions i pobrać raport z sekcji artefaktów.

To bardzo pomaga przy analizie błędów.

Zamiast zgadywać, co się stało, możesz sprawdzić, który test nie przeszedł, na którym kroku wystąpił problem i co faktycznie zobaczyła przeglądarka.

Trace Viewer, czyli ratunek przy trudniejszych błędach

Jedną z rzeczy, które bardzo lubię w Playwright, jest Trace Viewer.

Jeżeli test nie przejdzie, trace pozwala prześledzić wykonanie testu krok po kroku. Możemy zobaczyć akcje, asercje, screenshoty, logi, requesty i odpowiedzi.

W praktyce jest to dużo wygodniejsze niż czytanie samego komunikatu błędu w konsoli.

W pliku playwright.config.ts warto mieć ustawione trace, na przykład tak:

import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir: './tests',
  retries: process.env.CI ? 2 : 0,
  reporter: 'html',
  use: {
    trace: 'on-first-retry',
    screenshot: 'only-on-failure',
    video: 'retain-on-failure',
  },
  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },
  ],
});

W tym przykładzie:

  • trace zostanie zapisany przy pierwszym ponowieniu testu,
  • screenshot zostanie zapisany tylko przy błędzie,
  • video zostanie zachowane tylko wtedy, gdy test nie przejdzie,
  • w CI ustawiamy 2 ponowienia testów.

Oczywiście nie zawsze trzeba używać retry. Jeżeli testy są dobrze napisane, powinny być stabilne. Ale w prawdziwych projektach retry czasami pomaga odsiać chwilowe problemy środowiska od faktycznych błędów w aplikacji.

Co jeśli aplikacja musi zostać uruchomiona przed testami?

Bardzo często testy end-to-end wymagają działającej aplikacji.

Lokalnie możesz mieć aplikację pod adresem:

http://localhost:3000

Ale w GitHub Actions trzeba ją najpierw uruchomić.

Można to zrobić na kilka sposobów. Jednym z wygodniejszych jest konfiguracja webServer w Playwright.

Przykład:

import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir: './tests',
  webServer: {
    command: 'npm run dev',
    url: 'http://127.0.0.1:3000',
    reuseExistingServer: !process.env.CI,
    timeout: 120 * 1000,
  },
  use: {
    baseURL: 'http://127.0.0.1:3000',
    trace: 'on-first-retry',
  },
  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },
  ],
});

Dzięki temu Playwright przed testami uruchomi aplikację, poczeka aż będzie dostępna pod wskazanym adresem, a dopiero później odpali testy.

W testach możesz wtedy używać ścieżek względnych:

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

test('homepage should load', async ({ page }) => {
  await page.goto('/');
  await expect(page).toHaveTitle(/Example/);
});

To jest dużo wygodniejsze niż wpisywanie pełnego adresu w każdym teście.

Uruchamianie testów tylko dla pull requestów

Nie zawsze musisz uruchamiać testy po każdym pushu do każdej gałęzi.

Często dobrym rozwiązaniem jest uruchamianie testów na pull requestach do main.

Przykład:

on:
  pull_request:
    branches:
      - main

Dzięki temu testy sprawdzają zmianę zanim trafi ona do głównej gałęzi.

To ma duży sens w projektach zespołowych, bo pull request nie powinien być mergowany, jeżeli testy automatyczne nie przechodzą.

Uruchamianie testów na kilku przeglądarkach

Playwright pozwala testować aplikację na różnych przeglądarkach, na przykład Chromium, Firefox i WebKit.

W pliku playwright.config.ts możesz mieć taką konfigurację:

projects: [
  {
    name: 'chromium',
    use: { ...devices['Desktop Chrome'] },
  },
  {
    name: 'firefox',
    use: { ...devices['Desktop Firefox'] },
  },
  {
    name: 'webkit',
    use: { ...devices['Desktop Safari'] },
  },
],

Czy zawsze warto uruchamiać testy na trzech przeglądarkach?

To zależy.

Jeżeli projekt jest mały, czasami wystarczy Chromium. Jeżeli aplikacja jest używana przez wielu klientów i musi działać poprawnie na różnych przeglądarkach, warto rozważyć szerszą konfigurację.

Ja zwykle zaczynam od najważniejszych scenariuszy na Chromium, a dopiero później dokładam kolejne przeglądarki tam, gdzie faktycznie ma to sens.

Najczęstsze problemy w GitHub Actions

Przy pierwszej konfiguracji Playwrighta w GitHub Actions najczęściej pojawiają się podobne problemy.

1. Brak zainstalowanych przeglądarek

Jeżeli zobaczysz błąd związany z brakiem przeglądarki, sprawdź, czy w workflow masz krok:

- name: Install Playwright browsers
  run: npx playwright install --with-deps

Bez tego Playwright może nie mieć środowiska potrzebnego do uruchomienia testów.

2. Aplikacja nie wystartowała przed testami

Jeżeli testy próbują wejść na localhost, ale aplikacja nie działa, testy oczywiście się wysypią.

Wtedy warto użyć webServer w konfiguracji Playwright albo dodać osobny krok w workflow, który uruchomi aplikację przed testami.

3. Test działa lokalnie, ale nie działa w CI

To klasyk.

Najczęstsze przyczyny to:

  • zależność od danych lokalnych,
  • zbyt sztywne timeouty,
  • słabe selektory,
  • brak oczekiwania na element,
  • różnice w środowisku,
  • testy zależne od kolejności uruchamiania.

W takich przypadkach bardzo pomaga trace, screenshot i raport HTML.

4. Za długie wykonywanie testów

Jeżeli testów robi się dużo, workflow może trwać zbyt długo.

Na początku to nie problem, ale z czasem warto pomyśleć o:

  • podziale testów,
  • uruchamianiu tylko najważniejszych testów na każdym pull requeście,
  • osobnym workflow dla pełnej regresji,
  • sharding testów,
  • uruchamianiu pełnego zestawu testów na przykład raz dziennie albo przed większym releasem.

Czy testy Playwright powinny blokować merge?

Moim zdaniem: tak, ale z głową.

Jeżeli masz kilka stabilnych testów sprawdzających najważniejsze procesy w aplikacji, to jak najbardziej powinny one blokować merge.

Przykładowo:

  • logowanie,
  • rejestracja,
  • koszyk,
  • płatność,
  • wysłanie formularza,
  • podstawowy proces zakupowy,
  • najważniejsza ścieżka użytkownika.

Nie zaczynałbym od blokowania merge’a setką testów, które są niestabilne i co chwilę losowo się wysypują.

Najpierw lepiej mieć mały, ale stabilny zestaw testów. Dopiero później można go rozbudowywać.

Dobra praktyka: osobny workflow dla smoke testów

W wielu projektach dobrze sprawdza się podział testów.

Na przykład:

  • smoke testy uruchamiane na każdym pull requeście,
  • pełna regresja uruchamiana ręcznie albo według harmonogramu,
  • testy cross-browser uruchamiane przed releasem.

Dzięki temu nie blokujemy pracy zespołu zbyt długim pipeline’em, ale nadal mamy automatyczną kontrolę jakości.

Przykładowo smoke testy mogą sprawdzać tylko najważniejsze funkcje aplikacji:

npx playwright test --grep @smoke

A w testach możemy oznaczać scenariusze w nazwie:

test('@smoke user can open homepage', async ({ page }) => {
  await page.goto('/');
  await expect(page).toBeVisible();
});

To prosty sposób na rozdzielenie szybkich testów od większej regresji.

Podsumowanie

Uruchamianie testów Playwright w GitHub Actions to jeden z tych kroków, które naprawdę podnoszą wartość automatyzacji.

Dopóki testy są uruchamiane tylko lokalnie, łatwo o nich zapomnieć. Dopiero kiedy trafiają do pipeline’u, zaczynają realnie wspierać zespół.

Dobrze skonfigurowany workflow pozwala:

  • uruchamiać testy po pushu lub pull requeście,
  • szybciej wykrywać błędy,
  • zapisywać raporty HTML,
  • analizować trace’y i screenshoty,
  • blokować merge, jeśli najważniejsze scenariusze nie przechodzą.

Na start nie trzeba robić idealnej konfiguracji.

Wystarczy prosty workflow, kilka stabilnych testów i raport zapisywany jako artefakt. Później można stopniowo dokładać kolejne elementy: retry, trace, smoke testy, sharding, testy na wielu przeglądarkach czy pełną regresję.

Najważniejsze jest jedno: testy automatyczne powinny działać tam, gdzie faktycznie podejmujemy decyzję o jakości kodu.

A w wielu projektach tym miejscem jest właśnie GitHub Actions.

Udostępnij wpis

Odbierz 15% rabatu

Zapisz się do newslettera i otrzymaj kod rabatowy 15% na dowolny kurs w naszym sklepie.

Zapisując się, akceptujesz politykę prywatności.

Najpopularniejsze kursy

Jeśli ten temat jest Ci bliski, te kursy będą dobrym kolejnym krokiem.