Powrót do: Praktyczne wprowadzenie do testów automatycznych z Playwright
Debugowanie i skrypty
Prezentacja
Na powyższym obrazku to część na górze po prawej Podgląd zmiennych.
W VSCode zmienił się obecnie sposób wyświetlania.
Wyświetlane są zmienne/stałe, przez które przejdziemy w debugerze.
Dlatego będąc na pierwszym const podczas debugowania nie widzimy innych stałych w debugerze.
Widzimy wyłącznie this: undefined czyli obiekt automatycznie zadeklarowany wraz z testem.
Zmiana ta nie wpływa na przebieg lekcji i interakcje z debuggerem.
Dodatkowe materiały
Bazujemy na kodzie lekcji L06_dry_i_before
Kod wynikowy tej lekcji znajduje się tu: L07_debug
Pamiętaj, aby po danej porcji pracy:
- 👉 uruchamiać test,
- 👉 commitować poprawnie działający kod 😉
Skrypty w package.json
Skrypty w pliku package.json służą do definiowania i wywoływania różnych poleceń oraz operacji związanych z projektem.
Sekcja scripts pozwala na napisanie własnych, niestandardowych komend i operacji, które są specyficzne dla danego projektu. Dzięki temu, zamiast wpisywać długie polecenia w konsoli, można skonfigurować krótkie aliasy, które ułatwiają wykonywanie często używanych czynności.
Przykładowo możemy sobie napisać skrypty:
- do uruchamiania testów
- do uruchamiania części lub specyficznych testów
- do formatowania naszego kodu
- do uruchamiania aplikacji
- i wiele innych zależnych od projektu 🙂
W pliku package.json w sekcji scripts dodaj następujące skrypty:
- Do uruchamiania pojedynczego polecenia:
"test": "npx playwright test",
- Do uruchamiania pojedynczego polecenia z parametrami:
"test:headed": "npx playwright test --headed",
- Do uruchamiania innego skryptu z parametrami:
"test:pulpit:hd" : "npm run test tests/pulpit.spec.ts -- --headed"
W rezultacie zawartość pliku package.json przyjmie postać:
{
"name": "demo-bank-tests",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "npx playwright test",
"test:pulpit:headed": "npm run test tests/pulpit.spec.ts -- --headed",
"test:headed": "npx playwright test --headed"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@playwright/test": "^1.31.2",
"prettier": "2.8.4"
}
}
W powyższym przykładzie są zdefiniowane trzy skrypty:
- “test”
Ten skrypt odpowiada za uruchamianie testów za pomocą narzędzia Playwright Test. Po wywołaniu komendy npm run test, zostanie uruchomiona komenda
npx playwright test, która uruchomi wszystkie testy zdefiniowane w projekcie. - “test:pulpit:headed”
Ten skrypt odpowiada za uruchomienie testów zawartych w pliku tests/pulpit.spec.ts z trybem headed (czyli z wyświetlaniem przeglądarki). Po wywołaniu w konsoli
npm run test:pulpit:headed, zostanie wykonana komendanpm run test tests/pulpit.spec.ts -- --headed.
Tutaj widzisz bardzo duże uproszczenie komendy, którą musimy wywołać w konsoli w porównaniu do polecenia, które jest uruchamiane “pod spodem” 😉 - “test:headed”
Ten skrypt jest odpowiedzialny za uruchomienie wszystkich testów w trybie headed. Po wywołaniu w konsoli
npm run test:headed, zostanie wywołana komendanpx playwright test --headed, która uruchomi wszystkie testy z otwartą/widoczną przeglądarką 😉
Sekcja scripts w package.json umożliwia tworzenie skrótów dla różnych poleceń związanych z projektem, co ułatwia zarządzanie i wykonywanie często używanych operacji. W tym przypadku, skrypty są związane z testowaniem przy użyciu narzędzia Playwright Test oraz różnymi konfiguracjami uruchamiania testów z przeglądarką 😉
Skrypty uruchamiamy:
- Najeżdżając kursorem na nazwę skryptu i wybierając opcję Run
- Wykonując w konsoli polecenie:
npm run nazwa_skryptu - Aktywując opcję w ustawieniach EDITOR: NPM Scripts i używając nowej zakładki (na samym dole widoku EDITOR)
Uruchomienie w trybie debug
Każdy skrypt możemy uruchomić także w trybie Debug poprzez najechanie kursorem na nazwę skryptu i skorzystanie z opcji Debug Script.
Aby skrypt podczas debugowania został zatrzymany należy dodać breakpoint klikając po lewej stronie numeru danej linii kodu. Następnie można ponownie uruchomić skrypt w trybie debug.
W zakładce po lewej stronie znajdą się informacje na temat debugowanego skryptu.
U góry pojawi się okno kontroli debugera:
- Przycisk play: wykonanie kodu do następnego breakpointa lub do zakończenia skryptu.
- Przycisk skoku: przejście do kolejnej instrukcji.
- Strzałka w dół: wejście do instrukcji.
- Strzałka w górę: wyjście z instrukcji.
- Strzałka w okręgu: uruchomienie ponowne skryptu. Nie działa to zazwyczaj z testami Playwright 😀
- Przycisk wtyczki: rozłączenie debugera lub zakończenie skryptu.
Nowy test i debugowanie
W pliku pulpit.spec.ts tworzymy nowy test będący na początku kopią ostatniego testu. Zmieniamy jego tytuł.
test('correct balance after successful mobile top-up', async ({ page }) => {
});
Dodajemy only i ustawiamy breakpoint na linii z :
await page.locator('#widget_1_topup_receiver').selectOption(topUpReceiver);
Rozpoczynamy debugowanie testu.
Sprawdzamy w otwartej przeglądarce lokator do elementu reprezentującego balans:
#money_value'
A następnie dodajemy kod pobrania balansu (poniżej innych stałych):
const initialBalance = await page.locator('#money_value').innerText();
Uruchamiamy ponownie debug i sprawdzamy wartość zmiennej..
Dodajemy zmienną expectedBalance gdzie obliczamy oczekiwany balans:
const topUpAmount = '50';
const initialBalance = await page.locator('#money_value').innerText();
const expectedBalance = Number(initialBalance) - Number(topUpAmount);
Zwróć uwagę na operację zmiany typu z String na Number aby umożliwić operacje matematyczne.
Stosujemy expectedBalance w asercji:
// Assert
await expect(page.locator('#money_value')).toHaveText(`${expectedBalance}`);
});
Zauważ, że musimy ponownie zmienić typ przekazywanej wartości na String, gdyż taka wartość jest oczekiwana w metodzie weryufikującej.
Usuwamy nieużywane zmienne i uruchamiamy polecenie do formatowania.
Cały nowy test:
test('correct balance after successful mobile top-up', async ({ page }) => {
// Arrange
const topUpReceiver = '500 xxx xxx';
const topUpAmount = '50';
const initialBalance = await page.locator('#money_value').innerText();
const expectedBalance = Number(initialBalance) - Number(topUpAmount);
// Act
await page.locator('#widget_1_topup_receiver').selectOption(topUpReceiver);
await page.locator('#widget_1_topup_amount').fill(topUpAmount);
await page.locator('#uniform-widget_1_topup_agreement span').click();
await page.getByRole('button', { name: 'doładuj telefon' }).click();
await page.getByTestId('close-button').click();
// Assert
await expect(page.locator('#money_value')).toHaveText(`${expectedBalance}`);
});


Czy istnieje trochę wygodniejsza opcja współpracy z timeoutem podczas debugowania? Z perspektywy wydaje mi się dość toporne podejście gdzie by manualnie debugować muszę zmieniać timeout w playwright.config.ts by nie psuł wyników szukania błędu w teście.
Hej Mateusz!
Słuszne spostrzeżenie – i jest kilka sposobów na to.
Pokazałem jak manualnie uruchomić testy samodzielnie odpalając konsolę debug. To samo zachowanie spotka nas gdy uruchomimy skrypt z package.json w trybie debug – również będzie timeout.
Ale – gdy uruchomimy debugowanie ze wtyczki (następna lekcja) to już automatycznie timeout ustawi się na 0 i będziemy mogli bezpiecznie debugować a test zakończy się powodzeniem.
Dlatego przy debugowaniu warto znać wiele sposobów dzięki temu można elastycznie wybierać sposób uruchomienia nie tylko testów ale i skryptów z Playwright.
Pozdrawiam!
Hejka! Mam taki problem, że przy debugowaniu (ustawiłam breakpoint na 16 linii) w Variables -> Block widzę tylko
Nie wyświetlają się inne zmienne.
Hej Patrycja!
Rzeczywiście zachowanie debuggera zmieniło się. Teraz musimy przejść przez daną linię z kodem aby zmienna/stała została zainicjalizowana i wtedy pojawi się w debuggerze.
Dodałem stosowne info w lekcji – w sumie wystarczy debuggować i wtedy zaczną się te zmienne pojawiać.
Wyjątek stanowi this. Który jest inicjalizowany przy całym teście.
Dzięki za zwrócenie na to uwagi.
Pozdrawiam!
Hej !
Mam dziwny problem, bo chcialem sobie odejmować wartosci z zakładki ‘generuj przelew’ z miejsca ‘po przelewie’.
i teraz pojawia sie problem bo o ile zmienną ładnie mi łapie i pokazuje kwote ‘13159,20’ tak wynik odejmowania ‘afterBalance’ w debuggerze jest jako ‘NaN’, przez cos asercja nie jest poprawna.
Nie mam zupełnie pojęcia jak to ugryźć.
Hej,
Jak wygląda Twój cały kod testu? 😉
afterBalance moze mieć wartośc NaN, jeśli wartości działania są niepoprawne.
Np. przy takich działaniach dostaniemy w wyniku NaN:
console.log(12 - Number(undefined))
console.log(12 - Number("a"))
Musiałbyś zobaczyć co dokładnie ląduje w wartościach:
actualBalanceNumber(actualBalance)generateTransfer.cashNumber(generateTransfer.cash)Podesłałem maila z plikiem.
Jeśli miałbyś Krzyśku wolną chwilę, żeby zerknać byłoby super 🙂
Problem rozwiązany 😉
Problemem była konwersja ze string do number:
console.log('actualBalance', actualBalance); console.log('Number(actualBalance)', Number(actualBalance));co daje:
Metoda Number wymaga aby wartość dziesiętna była po kropce, a nie po przecinku 🙂
Jednym (szybkim i prostym) rozwiązaniem jest zamienienie przecinka na kropke, a później w drugą stronę (bo na UI wyświetla się przecinek):
// Replace the comma with a dot for proper number conversion const actualBalanceWithoutComma = actualBalance.replace(',', '.'); // Convert the string to a number and format it to two decimal places const afterBalance = Number(actualBalanceWithoutComma) - Number(generateTransfer.cash); // Format the number to two decimal places const afterBalanceString = afterBalance.toFixed(2); // Replace the dot with a comma for proper display const afterBalanceWithoutDot = afterBalanceString.replace('.', ',');Co można zmniejszyć do:
const currentBalance = Number(actualBalance.replace(',', '.')); const transferAmount = Number(generateTransfer.cash); const afterBalanceWithoutDot = (currentBalance - transferAmount).toFixed(2).replace('.', ',');Albo jeszcze krócej:
const afterBalanceWithoutDot = (Number(actualBalance.replace(',', '.')) - Number(generateTransfer.cash)).toFixed(2).replace('.', ',');Można też przygotować funkcje pomocniczą która będzie dokonywała konwersji 🙂
function convertToNumber(text: string): number { return Number(text.replace(',', '.')); } function formatToCommaDecimal(value: number): string { return value.toFixed(2).replace('.', ','); }Więc w tym teście głównym wyzwaniem jest format prezentacji wartości liczbowych na UI 😉
hej mam problem z debugerem 🙂 tzn. nie odpala się pomimo breakpointów, z tego co widzę na prezentacji nie masz konfiguracji w debugerze a u nie krzyczy i każe wybierać , próbowałem wszystkich opcji 🙂 i ostatecznie scrypt się wykonuje ale nie zatrzymuje się na breakpointach.
Hej Tomek!
Czasem się VSCode zatnie i nie chce dziąłac – pierwsze to restart!
Może to być przyczyna innych wtyczek zainstalowanych w Visual Studio Code lub konfiguracji.
Proponuję zaktualizować VSCode oraz zainstalować Playwright wraz z przeglądarkami w najnowszej wersji (
npm i @playwright/test@latest -Dinpx playwright install)Potem wyłączyć wszystkie wtyczki poza tą do Playwright.
Potem upewnić się, że w zakładce Testing (ta z ikoną kolby laboratoryjnej) w widoku PLAYWRIGHT w PROJECTS masz włączony projekt chromium. Dodatkowo sprawdź czy masz tam też oznaczoną opcję w SETTINGS: Show browser.
Teraz sprawdź czy prawym przyciskiem myszki kliknij na zieloną strzałkę przy teście i wybierz opcję debug.
Daj znać czy zadziałało.
Pozdro
Cześć,
Element, który sprawdzamy czyli amount, ma atrybut id = money_value
Czy jedyny sposób na znalezienie to page.locator(‘#money_value’)?
Nikt nie wadł na metodę getById analogicznej do getByTestId?
Hej Jacek!
Trafne spostrzeżenie. Zdecydowanie jest cała masa sposobów wyszukania elementu.
Stosujemy je tutaj zamienne aby przyzwyczaić kursanta do różnych konwencji.
We frameworku produkcyjnym warto uzgodnić i stosować daną hierarchię lokatorów (np.
getByTestId, inne getBy, css lokator, XPath lokator)
Pozdrawiam
Hej
Nie jest to wielki problem, ale zastanawia mnie dlaczego po uruchomieniu testów pojawia się taki komunikat “Running 5 tests using 2 worker”, na wideo testy uruchamiają się z 1 workerem.
Playwright config mam taki sam jak Przemek 🙂
Pozdrawiam
Hej!
Dobre spostrzeżenie. Liczba workerów zależy od liczby dostępnych logicznych wątków. Playwright domyślnie użyje połowę z nich (u mnie to 2 logical core więc jest jeden worker).
Więcej o tym opisujemy w kolejnej lekcji https://jaktestowac.pl/lesson/pw1s02l08/#Rownolegle_wykonanie_testow_a_zasoby_na_maszynie
Pozdrawiam!
Dzięki za informację, nie wiele brakowało a sam bym wpadł na to rozwiązanie, kończyłem akurat lekcję siódma a rozwiązanie “problemu” było w ósmej 🙂
Często tak się zdarza, że nie jesteśmy w stanie wszystkiego wytłumaczyć w jednej lekcji i tematy omówione są w kolejnych.
Oczywiście śmiało pytaj i postaramy się pomóc 😀
Pozdro!
Taka drobna uwaga – przy pierwszym wybraniu debugowania Visual Code zasugerował użycie polecenia, podaję, bo może się komuś przyda:
Hej, dzięki za informację!
Ta paczka może wspomagać debugowanie ale nie trzeba jej instalować.
Szczególnie, że będzie to globalna paczka (opcja
-g) jeśli ją zainstalujemy w sugerowany sposób. Zalecamy uważać na globalne instalacje dla całego systemu (a nie danego projektu) ze względu na trudność w utrzymaniu i kontroli takich paczek.Pozdrawiam