Trzy agenty Playwright: Planner, Generator i Healer w aplikacji sklepowej w czasie rzeczywistym
Framework Playwright, w którym jeden agent planuje testy, drugi tworzy specyfikacje na podstawie sesji przeglądarki w czasie rzeczywistym, a trzeci naprawia błędy, umożliwiając przeprowadzenie 22 testów równolegle w około 16 sekund.
Większość ludzi widziała już tę demonstrację: podaje się prompt modelowi, otrzymuje się skrypt Playwright, uruchamia się go raz, a po krótkim czasie okazuje się, że nie działa. Zespół QA pracujący w sposób profesjonalny stosuje inny cykl składający się z eksploracji, planowania, automatyzacji i konserwacji, a celem tutaj było przyznanie agentowi odpowiedzialności za każdy z tych etapów. Rezultatem jest framework Playwright, który można ponownie wykorzystać, wspierany przez trzy specjalistyczne agenty:
- Planner bada aplikację w czasie rzeczywistym i tworzy plan testów.
- Generator przekształca pojedynczy zaplanowany scenariusz w gotową specyfikację testową.
- Healer uruchamia zestaw testów, ustala przyczynę ich niepowodzeń i naprawia podstawowe problemy.
Celem demonstracji była mała aplikacja koszyka zakupowego, w której użytkownik przechodził od logowania przez listę produktów do koszyka, procesu płatności i strony podziękowań. Ostatecznie stworzono 22 zautomatyzowane scenariusze obejmujące normalne ścieżki działania, przypadki negatywne oraz specjalne sytuacje walidacyjne. Scenariusze te działają równolegle, wykorzystując obiekty strony, które sami utrzymują agenci. Raport HTML Playwright pokazał 22 przetestowane z powodzeniem scenariusze, 0 nieudanych oraz 0 niestabilnych, a cała seria testów zakończyła się w ciągu 16,2 sekundy.
Przygotowania przed uruchomieniem jakiegokolwiek agenta
Najpierw muszą istnieć trzy elementy. Większość przewodników je pomija, a one decydują o tym, czy wygenerowany wynik w ogóle może być użyty.
Serwer testowy MCP Playwright. Agenci nie powinni zgadywać struktury DOM, dlatego korzystają z rzeczywistego przeglądarki. Jeden plik konfiguracyjny łączy je ze sobą:
{
"servers": {
"playwright-test": {
"type": "stdio",
"command": "npx",
"args": ["playwright", "run-test-mcp-server"]
}
}
}
To daje każdemu agentowi takie narzędzia jak browser_navigate, browser_snapshot i browser_click, a także test_run i test_debug przeznaczone dla Healera.
Umowa ramowa. Jeden plik framework.md określa strukturę folderów i zasady: selektory znajdują się w pages/, ścieżki użytkownika w flows/, a adresy oraz dane logowania w pliku .env. Każdy agent czyta go przed wykonaniem jakichkolwiek działań, dzięki czemu wyniki przypominają jedną bazę kodu, a nie trzy różne style osobiste.
Test początkowy. Jeden mały opis otwiera prawdziwą stronę główną i sprawdza coś stabilnego. Każdy wygenerowany test rozpoczyna się od tego znanej, poprawnej stanu.
Jakość agenta zależy wyłącznie od „szyn”, po których działa, a te trzy stanowią właśnie takie szyny.
The Planner: decydowanie o tym, co zasługuje na test
Planner w ogóle nie pisze żadnego kodu. Otwiera aplikację, porusza się jak ciekawy tester i mapuje to, co istnieje: formularze, mechanizmy autoryzacji, koszyk zakupów, kroki finalizacji zamówienia, komunikaty walidacyjne oraz stany puste.
Jego rutyna:
- Zawołać funkcję
planner_setup_pageraz. - Eksplorować aplikację za pomocą narzędzi przeglądarki, czytając zrzuty DOM zamiast ekranów.
- Wyznaczyć główne ścieżki działania oraz sposoby, w jakie mogą one zawieść.
- Zapisać plan w formacie markdown do pliku
specs/-plan.md.
Każdy scenariusz w planie ma tytuł, numerowane kroki, oczekiwany wynik, założenia dotyczące stanu początkowego (świeży sesja, chyba że zaznaczono inaczej) oraz ścieżkę pliku, w której zostanie umieszczony.
Plan procesu zakupowego składa się z 22 scenariuszy w sekcjach dotyczących logowania, koszyka zakupowego, procesu płatności oraz jednej pełnej ścieżki od początku do końca. Taka struktura okazuje się przydatna później, ponieważ generator przekształca nazwę każdej sekcji w blok test.describe, dzięki czemu plan i kod są od początku dobrze skorelowane.
Dlaczego oddzielny etap? Ocena zakresu testowania to problem wymagający przemyśleń. Gdy jedno polecenie musi jednocześnie obejmować planowanie i pisanie kodu, jakość planowania pogarsza się. Wynik zawierający tylko plan można przejrzeć i edytować, zanim powstanie choćby jedna linia kodu testowego.
Generator: urzeczywistnianie jednego scenariusza
Generator obsługuje dokładnie jeden scenariusz naraz, nigdy nie cały plan. Dla każdego z nich:
- Uruchamia funkcję
generator_setup_page, aby osiągnąć stan wyjściowy. - Wykonuje każdy krok bezpośrednio w przeglądarce, traktując tekst opisujący krok jako intencję.
generator_read_log, który przechowuje informacje o lokalizatorach i czeka na te, które rzeczywiście zadziałały.generator_write_test, aby utworzyć pojedynczy plik specyfikacji.W trzecim kroku pochodzi wartość. Nic nie jest przechowywane z danych treningowych. To, co trafia do pliku, to zapis sesji, która właśnie została przeprowadzona z użyciem rzeczywistej interfejsu.
Wynik automatycznie przestrzega zasad frameworka:
// spec: specs/checkout-e2e-plan.md
// seed: tests/web/seed.spec.js
import { test, expect } from '../../../fixtures';
import { users } from '../../../testdata';test.describe.configure({ mode: 'parallel' });test.describe('E2E checkout journey', () => {
test('positive: login → add product → checkout → thank you → home', async ({ flow }) => {
await flow.completeHappyPathPurchase();
});
});
W wyniku brakuje wyraźnie selektorów CSS, dosłownego hasła oraz ciągów URL. Selektory są przenoszone do obiektów strony, a procesy wieloetapowe stają się metodami w klasie flow:
async completeHappyPathPurchase(user = users.standard, info = checkout.valid) {
await this.goToCheckoutInformation(user);
await this.fillValidInformation(info);
await this.continueToOverview();
await this.app.checkoutOverview.expectProductVisible(products.first.name);
await this.finishOrder();
await this.backHomeToProducts();
}
Każdy test otrzymuje również własny kontekst przeglądarki, graf obiektów strony oraz instancję toku poprzez pliki konfiguracyjne. Dzięki braku wspólnego, zmienne stanu zestaw testów jest bezpieczny do wykonywania równolegle od samego początku, a nie jako dodatek później. To właśnie odróżnia skrypt od frameworka.
The Healer: naprawianie właściwej warstwy
Tworzenie testów to korzyść jednorazowa. Konserwacja stanowi natomiast stały koszt, i to właśnie tutaj pojawia się trzeci element. Jego pętla wygląda następująco:
test_runuruchamia zestaw testów i zbiera informacje o błędach.test_debugzatrzymuje się przy każdym błędzie.- Bada aktualny zrzut ekranu, konsolę, ruch sieciowy oraz błędną afirmację.
- Diagnozuje przyczynę: zmieniony lokator, różnice w czasie wykonywania, zmienione warunki działania lub rzeczywisty błąd produktu.
pages/, gdy zmienia się interfejs użytkownika, oraz api/endpoints/, gdy zmienia się kontrakt.Dwa mechanizmy zabezpieczające zapewniają jego wiarygodność. Nigdy nie osłabia założeń tylko po to, by test przeszedł pomyślnie. Jeśli produkt jest błędny, a test prawidłowy, oznacza test funkcją test.fixme() oraz komentarzem opisującym rzeczywiste zachowanie, dzięki czemu niepowodzenie pozostaje widoczne i nie zostaje ukryte. Unika również niebezpiecznych interfejsów, takich jak networkidle, jako rozwiązania tymczasowego na problemy z synchronizacją.
Zaletą jest koncentracja zmian. Wystarczy przemienić nazwę przycisku, a edytowana jest tylko jedna metoda obiektu strony, po czym wszystkie testy ją wykorzystujące znów działają poprawnie. Ponieważ 22 testy korzystają z 325 linii kodu obiektów stron rozproszonych w 10 klasach, przeprojektowanie nie powoduje załamania całego zestawu testów. W sumie każdy element odpowiada za określoną część repozytorium, a wspólna warstwa obiektów stron jest tym, co utrzymuje całą strukturę w ruchu.
Rozpoczęcie i zakończenie działania
Polecenia konfiguracji:
1. Copy .env.example → .env, set BASE_URL (+ credentials)
2. npm install && npx playwright install
A agent uruchamia się w następującej kolejności:
3. Run the Planner
→ specs/checkout-e2e-plan.md (22 scenarios, reviewed by me)4. Run the Generator, scenario by scenario
→ tests/web/login/login.spec.js
→ tests/web/cart/cart.spec.js
→ tests/web/checkout/checkout.spec.js
→ tests/web/e2e/checkout-journey.spec.js5. npm test (4 workers, fully parallel)6. Any red? Run the Healer → re-run → green
Przejście na inny produkt nie wpływa na agenty. Ustaw BASE_URL na nowy produkt, przygotuj ponownie obiekty strony oraz dane testowe, a następnie wyślij te same trzy polecenia. Ponieważ agenci czytają pliki framework.md i .env, a nie sztywno zdefiniowaną nazwę produktu, cały proces jest przenoszalny i nie wymaga indywidualnej konfiguracji.
O ile szybciej to naprawdę jest?
Takie twierdzenia jak „Sztuczna inteligencja sprawiła, że jest to dziesięć razy szybsze” nie powinny być przyjmowane bez szczegółowego wyjaśnienia. Ręczne pisanie testów end-to-end rzadko polega wyłącznie na wpisywaniu tekstu. Oznacza to otwieranie narzędzi DevTools, poszukiwanie odpowiedniego selektora, znajdowanie przycisku w nietypowym otoczeniu, ponowne uruchamianie testów, aby sprawdzić, czy warunek nie zostanie spełniony zbyt wcześnie, oraz rozpoczynanie procesu od nowa. Większość wysiłku polega na tym cyklu poszukiwań, a Generator pokrywa ten koszt poprzez realizację kroków w czasie rzeczywistym i raportowanie tego, co zadziałało.
Korzyści są widoczne na kilku etapach:
- Decydowanie o zakresie testowania. Ręczne podejście jest ad hoc i często pomija przypadki negatywne. Planner z góry wylicza scenariusze pomyślne, negatywne oraz graniczne.
- Znajdowanie lokatorów. Ręczne szukanie w narzędziach DevTools dla każdego elementu ustępuje miejsca lokatorom uzyskanym z już przeprowadzonej sesji.
- Pierwszy udany test. Cykl pisania, uruchamiania, naprawy i powtórzenia zamienia się w generowanie testów na podstawie zweryfikowanego transkryptu.
- Utrzymywanie kompletności zestawu testów. Szukanie w każdej specyfikacji uszkodzonych selektorów ustępuje miejsca jednej naprawie obiektu strony, która naprawia wszystkie powiązane testy.
Największe oszczędności pochodzą od drugiego do dwudziestego testu. Pierwszy wiąże się z rzeczywistymi kosztami konfiguracji obiektów strony, fixitów oraz danych początkowych. Od tego momentu nowy scenariusz to głównie kombinacja istniejących elementów, a koszt na test szybko spada.
Szybkość wykonywania pochodzi zupełnie z innej przyczyny. Paralelizm nie jest cechą sztucznej inteligencji – to zasada projektowa, której muszą przestrzegać agenci. Każdy test otrzymuje nowy kontekst z ustawień, a żaden nie modyfikuje stanu wspólnego modułu, dzięki czemu konfiguracja jest wykonywana w pełni równolegle: cztery procesory lokalnie, dwa w środowisku CI z dwoma próbami ponownego uruchomienia, przy czym ślady i nagrania wideo są tworzone tylko wtedy, gdy test się nie powiedzie. Każdy zestaw testów, który wykorzystuje tę samą sesję logowania, nie może być uruchamiany w ten sposób bez ryzyka. Ten jednak może, ponieważ zasada „jeden scenariusz to jeden niezależny test” była obowiązkowa dla Generatora we wszystkich plikach.
Cztery lekcje wartego przejęcia
- Utrzymuj role w wąskim zakresie. Jeden długi prompt, który zarządza planowaniem, pisaniem kodu i debugowaniem, daje niejasne wyniki. Trzy skoncentrowane role, z których każda ma własne narzędzia, pozostawiają coś do przejrzenia na każdym etapie.
framework.md poprawiło jakość bardziej niż jakakolwiek modyfikacja instrukcji.Dla kogo to jest przeznaczone
Inżynierowie QA, którzy spędzają więcej czasu na naprawianiu narzędzi lokalizacyjnych niż na projektowaniu mechanizmów testowania, odnotują korzyści. Podobnie będzie z zespołami stosującymi Playwright, które chcą wykorzystać sztuczną inteligencję w ramach uporządkowanej struktury, a nie zastąpić nią ludzi, oraz z tymi, którzy porównują agenty Copilot lub Cursor z serwerem testowym MCP Playwright.
Nic z tego nie zastępuje procesu testowania QA. Decyzje dotyczące tego, co jest ważne, co stanowi prawdziwy błąd oraz jakiego zakresu testowania brakuje, pozostają w rękach człowieka. Agenty przejmują zadania związane z eksploracją, tworzeniem szablonów oraz powtarzalną naprawą błędów, co umożliwia realizację cyklu: planowanie, generowanie, uruchamianie, naprawa i ponowne uruchamianie.