W świecie QA pojawiła się nowa gwiazda. Jest to Playwright – potężny, open-source’owy framework od Microsoft, który szturmem zdobywa uznanie w dziedzinie automatyzacji testów end-to-end. Dlaczego zyskuje taką popularność? Playwright oferuje unikalne połączenie szybkości, niezawodności (dzięki inteligentnym mechanizmom jak auto-waiting ) i wszechstronności, wspierając testy na wielu przeglądarkach za pomocą jednego API. Więcej o tym narzędziu pisaliśmy między innymi tutaj.
W tym artykule zebrałem konkretne narzędzia i dobre praktyki, które realnie ułatwiają mi pracę z Playwrightem i pomagają pisać stabilniejsze, szybsze i bardziej czytelne testy.
1. Debugowanie testów
Podczas programowania i podczas pisania testów automatycznych jednym z najważniejszych etapów jest szybkie lokalizowanie i rozwiązywanie problemów. Playwright ma na tym polu solidne wsparcie w postaci Playwright Inspector – interaktywnego debuggera, który pozwala podejrzeć, co faktycznie dzieje się w przeglądarce w trakcie testu.
Inspector uruchamia się w osobnym oknie i umożliwia krokowe przechodzenie przez test. Do tego pomaga sprawdzać stan elementów, kopiować selektory i przede wszystkim – obserwować zachowanie strony w czasie rzeczywistym. Wygląda on tak:

Playwright oferuje kilka sposobów debugowania testów – w tym także integrację z wtyczką do VS Code, która pozwala uruchamiać testy bezpośrednio z edytora. W praktyce projektowej najczęściej korzystam jednak z opisywanego wyżej Inspectora – jest szybki, stabilny i pozwala dokładnie zobaczyć, co dzieje się na stronie w danym momencie.
Aby uruchomić test z debugowaniem, wystarczy do polecenia uruchomienia testu dodać flagę --debug:
npx playwright test --debugWięcej informacji na temat tego narzędzia znajduje się w oficjalnej dokumentacji.
2. Projekty i ich konfiguracja
Playwright pozwala definiować projects – czyli różne konfiguracje testów w ramach jednej konfiguracji globalnej. Dzięki nim można uruchamiać te same testy w różnych przeglądarkach, bez potrzeby duplikowania kodu ani ręcznego przełączania konfiguracji.
export default defineConfig({
projects: [
{
name: 'Chrome',
use: { browserName: 'chromium' },
},
{
name: 'Firefox',
use: { browserName: 'firefox' },
},
],
});Jednak ich rola nie ogranicza się tylko i wyłącznie do wskazywania przeglądarek w teście. Projects pozwalają tworzyć osobne konfiguracje testowe – nie tylko dla różnych przeglądarek, ale również dla różnych języków, środowisk, urządzeń czy zestawów testów. Dzięki nim można łatwo uruchomić te same scenariusze np. w trybie desktopowym i mobilnym. To także świetny sposób na grupowanie testów – np. rozdzielenie testów API od UI lub smoke testów od regresyjnych.
Co ważne, każdy projekt może mieć również własne ustawienia, takie jak retries, testMatch (czyli dopuszczone pliki testowe), timeouty czy nawet inne środowiskowe zmienne. Dzięki temu możemy na przykład zwiększyć liczbę ponowień testów tylko dla Firefoksa, jeśli wiemy, że w tej przeglądarce występuje większa niestabilność. Przykład takiej konfiguracji znajduje się poniżej:
projects: [
{
name: 'API tests',
testMatch: /.*\.api\.spec\.ts/,
retries: 0,
},
{
name: 'UI tests',
testMatch: /.*\.ui\.spec\.ts/,
retries: 2,
use: { browserName: 'chromium' },
},
],
Poszczególne konfiguracje można uruchamiać selektywnie za pomocą flagi --project, np.
npx playwright test --project="API tests"
npx playwright test --project="UI tests".Podsumowując – projekty to prosty sposób na na zwiększenie elastyczności testów i lepsze odwzorowanie rzeczywistych scenariuszy użytkownika w różnych środowiskach.
3. Ignorowanie testów
W codziennej pracy zdarza się, że trzeba tymczasowo wyłączyć test – na przykład gdy nie działa w konkretnej przeglądarce albo jest w trakcie poprawki. Tradycyjnie radzono sobie z tym, komentując kod testu lub wstawiając prowizoryczne instrukcje warunkowe. Takie rozwiązania są jednak nieczytelne, trudne do utrzymania i łatwo prowadzą do błędów.
Playwright umożliwia ominięcie testu w łatwy sposób. Możemy oznaczyć test adnotacją skip():
test.skip('This test is temporarily disabled', async () => {
// ...
});Warto wspomnieć także o podobnej, równie ciekawej funkcjonalności. Jeśli test jest niestabilny lub wymaga uwagi, zamiast go całkowicie wyłączać, możesz użyć fixme()
test.fixme('Requires a fix after the last refactor');To nie pomija testu, ale oznacza go w raporcie jako wymagający naprawy. Dzięki temu nie wylatuje z test suite, ale dostajesz czytelny sygnał, że coś jest nie tak.
4. Zapisywanie stanu sesji
Wiele testów E2E zaczyna się od zalogowania użytkownika. Powtarzanie procesu logowania w każdym teście jest nieefektywne – spowalnia wykonanie całego zestawu testów i może prowadzić do niestabilności (np. z powodu limitów żądań do API logowania). Playwright oferuje mechanizm zapisywania i ponownego wykorzystywania stanu uwierzytelnienia, co znacząco optymalizuje ten proces.
Playwright pozwala zapisać stan uwierzytelnienia do pliku. Zapisany plik storageState (zazwyczaj w formacie JSON) może być następnie użyty do inicjalizacji nowych kontekstów przeglądarki, które od razu będą miały stan zalogowanego użytkownika.
Jak to zrobić? Po pomyślnym zalogowaniu użytkownika w teście, stan kontekstu można zapisać za pomocą metody context.storageState():
await context.storageState({ path: 'playwright/.auth/user.json' });5. Soft Assertions
Domyślnie w Playwright test zatrzymuje się przy pierwszym nieudanym expect. Jednak może zdarzyć się sytuacja, w której zechcesz sprawdzić kilka warunkow naraz i zobaczyć pełną listę błędów, a nie tylko pierwszy z nich.
Tu właśnie przydaje się expect.soft(). Zamiast przerywać test, expect.soft() zapisuje wszystkie niepowodzenia i zgłasza je razem po zakończeniu testu. Przykład:
import { test, expect } from '@playwright/test';
test('Checking a few elements on the page', async ({ page }) => {
await page.goto('https://example.com');
expect.soft(await page.locator('h1')).toHaveText('Dashboard');
expect.soft(await page.locator('#login')).toBeVisible();
expect.soft(await page.locator('.profile-picture')).toHaveAttribute('src', /avatar/);
});
Jeśli wszystkie trzy asercje zawiodą, Playwright poda je w jednym raporcie, bez zatrzymywania testu po pierwszym błędzie.
Kiedy warto używać expect.soft? Np. w smoke testach lub wszystkich innych przypadkach, kiedy świadomie chcesz zebrać jak najwięcej błędów podczas jednego uruchomienia testów.