Powrót do: Praktyczne wprowadzenie do testów automatycznych z Playwright
Rozbudowa testów i lokatory
- brakiem wczytania wiadomości potwierdzającej przelew
- brakiem wypełnienia pola z kwotą i tytułem przelewu
Wynikały one z próby wykonania akcji na jeszcze nie do końca załadowanej stronie.
Powodem tego mogą być:
- problemy z hostingiem
- problemy z połączeniem internetowym
- nie optymalne rozwiązania zastosowane na testowanej stronie
- zbyt dużą szybkością akcji, jakie wykonuje Playwright
Rozwiązaniem jest dodanie inteligentnego czekania w postaci:
await page.waitForLoadState("domcontentloaded")
Konstrukcja waitForLoadState
czeka, aż pojawi się w przeglądarce zdarzenie domcontentloaded, które oznacza, że zawartość strony została w pełni załadowana.
Na nagraniu jej nie używamy, jednak jeśli Twoje testy kończyłyby się niepowodzeniem, to rzuć okiem pod nagranie do sekcji Stabilizacja Testów. Tam umieściliśmy dodatkowe instrukcje, polecenia i kod 😉
Prezentacja
Dodatkowe materiały
Link do testowanej stronyUzupełnienie wiedzy o HTML i lokatorach
Jeśli nie miałeś styczności z kodem stron internetowych HTML to skorzystaj z lekcji Kod strony HTML oraz Elementy strony w przeglądarce.
Drobne poprawki kodu
Poprawiamy literówkę w pliku login.spec.ts. Zamiast:
unsuccessful login with to short username
powinno być:
unsuccessful login with too short username
Synchronizujemy się z zawartością pliku README.md z repozytorium poprzedniej Lekcji 02:
https://github.com/jaktestowac/playwright_automatyzacja_wprowadzenie/tree/main/S01_wprowadzenie/L02_testy_logowania
Wielokrotne użycie only
Zastosowanie ograniczenia wykonywania testów, w postaci test.only()
w kilku testach spowoduje wykonanie wszystkich testów oznaczonych funkcją only
.
Dokładnie sprawdzaj wyniki w konsoli przy uruchamianiu testów, czy przypadkiem nie pozostawiłeś gdzieś testu z funkcją only
.
Kasujemy nadmiarowe akcje
Pozbywamy się akcji w testach, które nie wpływają na wykonanie testów.
W naszych testach takie dwa kroki:
await page.getByTestId('login-input').click(); await page.getByTestId('login-input').fill('testerLO');
Mogą być zredukowane do:
await page.getByTestId('login-input').fill('testerLO');
Metoda fill()
realizuje zarówno focus na elemencie jak i wypełnienie go danymi.
Czyścimy z testu wszystkie nadmiarowe kroki, dzięki czemu tak teraz wyglądają nasze testy:
test('successful login with correct credentials', async ({ page }) => { await page.goto('https://demo-bank.vercel.app/'); await page.getByTestId('login-input').fill('testerLO'); await page.getByTestId('password-input').fill('10987654'); await page.getByTestId('login-button').click(); await expect(page.getByTestId('user-name')).toHaveText('Jan Demobankowy'); }); test('unsuccessful login with too short username', async ({ page }) => { await page.goto('https://demo-bank.vercel.app/'); await page.getByTestId('login-input').fill('tester'); await page.getByTestId('password-input').click(); await expect(page.getByTestId('error-login-id')).toHaveText('identyfikator ma min. 8 znaków'); }); test('unsuccessful login with too short password', async ({ page }) => { await page.goto('https://demo-bank.vercel.app/'); await page.getByTestId('login-input').fill('testerLO'); await page.getByTestId('password-input').fill('1234'); await page.getByTestId('password-input').blur(); await expect(page.getByTestId('error-login-password')).toHaveText('hasło ma min. 8 znaków'); });
Testy pulpitu
Tworzymy nowy plik z testami pulpit.spec.ts.
Dodajemy podstawowe struktury do pliku:
import { test, expect } from '@playwright/test'; test.describe('Pulpit tests', () => { });
Nagrywamy nowy scenariusz według kroków:
- Zalogowanie się
- Skorzystanie z opcji Szybki przelew
- do Chuck Demobankowy
- kwota 150
- tytułem Przelw środków
- Akceptacja okna potwierdzenia
- Weryfikacja wiadomości o przelewie
Wklejamy nagrany test do przygotowanego pliku, oraz usuwamy nadmiarowe akcje (czyli np. nadmiarowe kliknięcia w element).
Lokatory
Lokator: jest to sposób w jaki znajdujemy dany element ze strony internetowej.
Selektor: jest to adres danego elementu
Lokator getByTestId()
Zastosowanie:
await page.getByTestId('login-input').fill('testerLO');
Lokator getByTestId()
Zastosowanie:
await page.getByTestId('login-input').fill('testerLO');
Lokator getByTestId()
działa w oparciu o wartość atrybutu zlokalizowanego w kodzie strony data-testid
. Przykład elementu z data-testid
do wpisywania loginu:
Taki test id musi zostać dodany przez twórców aplikacji do kodu danej strony. Najczęściej ten atrybut jest usuwany przed wprowadzeniem aplikacji na produkcję.
Usunięcie tego atrybutu to jedynie kosmetyczny zabieg w większości przypadków. Jedynie w przypadku bardzo rozbudowanych stron taki atrybut może mieć cząstkowy wpływ na ich wydajność.
Ostatecznie dodawanie i usuwanie takiego atrybutu to konwencja techniczna zależna od realiów danego projektu.
Więcej o usuwaniu takiego atrybutu z punkty widzenia deweloperskiego poczytasz tutaj:
https://dpericich.medium.com/removing-data-test-attributes-from-react-production-dom-5ea4ea018acc
Dodanie takiego atrybutu do kodu strony zazwyczaj jest poprzedzone zespołowym uzgodnieniem konwencji: jak będzie się on nazywał, jak będą wyglądać jego wartości.
W Playwright domyślnie rozpoznawany jest format nazwy data-testId
ale można go dowolnie nazwać w kodzie aplikacji i ustawić w playwright.config.ts (klucz testIdAttribute
):
// Set custom test id attribute from @playwright/test config: import { defineConfig } from '@playwright/test'; export default defineConfig({ use: { testIdAttribute: 'data-pw' }, });
Więcej o tym czym jest test id poczytasz we wpisach (język angielski):
Oficjalna dokumentacja: https://playwright.dev/docs/locators#locate-by-test-id
Dlaczego warto używać test id: https://medium.com/@automationTest/why-your-development-team-should-use-data-testid-attributes-a83f1ca27ebb
Implementacja automatycznego test id w React: https://www.educative.io/answers/what-is-the-data-testid-attribute-in-testing
Lokator getByRole()
Zastosowanie:
await page.getByRole('button', { name: 'wykonaj' }).click();
getByRole()
działa w oparciu o typy elementów i ich cechy.
Przykład elementu związanego z przyciskiem wykonaj:
Selektorem dla tego elementu działającym w oparciu o typ element button
i wartość jego tekstu będzie:
getByRole('button', { name: 'wykonaj' })
Lokator locator()
Zastosowanie:
await page.locator('#widget_1_transfer_receiver').selectOption('2');
locator()
wykorzystuje między innymi adresy zapisane w formacie CSS.
Przykład elementu z css
związanego z wybieraniem odbiorcy przelewu:
Selektorem dla tego elementu działającym w oparciu o wartość atrybutu id
będzie:
#widget_1_transfer_receiver
Asercja
Posiadając nagrany kod:
await page.getByRole('link', { name: 'Przelew wykonany! Chuck Demobankowy - 150,00PLN - pizza' }).click();
Można zidentyfikować element:
Przelew wykonany! Chuck Demobankowy - 34,00PLN - pizza
Używając atrybutu id elementu z tekstem, który został nagrany można zbudować taką asercję:
await expect(page.locator('#show_messages')).toHaveText('Przelew wykonany! Chuck Demobankowy - 150,00PLN - pizza');
Aby upewnić się, że nasz test działa poprawnie, a dokładnie jego asercja warto ją uszkodzić celowo, aby wywołać niepowodzenie testu.
Nazwa testu
quick payment with correct data
Stabilizacja testów
- brakiem wczytania wiadomości potwierdzającej przelew
- brakiem wypełnienia pola z kwotą i tytułem przelewu
Wynikały one z próby wykonania akcji na jeszcze nie do końca załadowanej stronie.
Powodem tego mogą być:
- problemy z hostingiem
- problemy z połączeniem internetowym
- nie optymalne rozwiązania zastosowane na testowanej stronie
- zbyt dużą szybkością akcji, jakie wykonuje Playwright
Rozwiązaniem jest dodanie inteligentnego czekania w postaci:
await page.waitForLoadState("domcontentloaded")
Konstrukcja waitForLoadState
czeka, aż pojawi się w przeglądarce zdarzenie domcontentloaded, które oznacza, że zawartość strony została w pełni załadowana.
Jak skorzystać z tej konstrukcji?
W naszym teście pulpitu problem ten może występować, po operacji logowania. Wtedy ładowana jest nowa strona pulpitu.
Dlatego po kliknięciu w przycisk login musimy dodać await page.waitForLoadState("domcontentloaded")
:
import { test, expect } from '@playwright/test'; test.describe('Pulpit tests', () => { test('quick payment with correct data', async ({ page }) => { await page.goto('https://demo-bank.vercel.app/'); await page.getByTestId('login-input').fill('testerLO'); await page.getByTestId('password-input').fill('password'); await page.getByTestId('login-button').click(); // wait for page to fully load: await page.waitForLoadState("domcontentloaded") await page.locator('#widget_1_transfer_receiver').selectOption('2'); await page.locator('#widget_1_transfer_amount').fill('150'); await page.locator('#widget_1_transfer_title').fill('pizza'); await page.getByRole('button', { name: 'wykonaj' }).click(); await page.getByTestId('close-button').click(); await expect(page.locator('#show_messages')).toHaveText( 'Przelew wykonany! Chuck Demobankowy - 150,00PLN - pizza' ); }); });
Tego typu konstrukcja może zapewnić nas, że strona w następnym kroku (przy wyborze danych z elementy select) jest w pełni załadowana.
Cały kod
Aktualny kod z lekcji znajdziesz w dedykowanym repozytorium: https://github.com/jaktestowac/playwright_automatyzacja_wprowadzenie.
Panowie muszę Wam dać niestety minusa za tą lekcję. Jako tester automatyzujący (Selenium Java) stwierdzam, że tutaj jest błąd:
await page.getByRole(‘button’, { name: ‘wykonaj’ }).click();
Fajnie, że jest taka możliwość, fajnie ze to było pokazane ale nie rozumiem czemu ten element nie został zlokalizowany po ID gdyż ten element takie posiada. Co do ID. To nie ma znaczenia czy to Cypress, PW czy Selenium:
ID elementów są zazwyczaj unikalne i niezmienne w ramach jednej aplikacji. To oznacza, że testy automatyczne są mniej podatne na zmiany w strukturze DOM, co zwiększa ich stabilność.
Selektory oparte na ID są zwykle szybkie do przetworzenia przez przeglądarki, ponieważ ID są indeksowane w DOM. Dzięki temu testy mogą działać szybciej.
Jednoznaczność: ID są unikalne w ramach jednej strony, co eliminuje niejednoznaczność przy wybieraniu elementów. Dzięki temu testy są bardziej precyzyjne i łatwiejsze do debugowania.
Także jeśli mamy do wyboru ID to wybierajmy to ID.
Hej,
Dzięki za komentarz i podkreślenie wartości ID w testach!
Zgadzam się, że powinniśmy lokalizować elementy po ID (albo data-testid). Zazwyczaj ID są unikalne, przez co łatwiej (i szybciej) możemy zlokalizować dany element.
Na początku bazujemy na kodzie, jaki wygenerował Playwright (czyli na
await page.getByRole(‘button’, { name: ‘wykonaj’ }).click();
) i jest to przykład jak jeszcze można podchodzić do lokalizacji elementów 🙂 Tak jak słusznie wspominasz – nie jest on optymalny bo m.in bazuje na tekście, jaki jest zawarty w elemencie i który może się zmieniać.Ciężko mi powiedzieć, dlaczego w tym przypadku, gdy element posiada ID, tamta wersja codegen wygenerowała akurat taki kod do lokalizacji elementu. Codegen jest z każdą wersją poprawiany, dlatego też może w kolejnych wydaniach będzie inaczej (lepiej) generował kod.
W 27:40 robimy refaktoryzację tego kawałka kodu – i zamieniamy
getByRole
na znajdowania elementu po ID, czyli naawait page.locator('#execute_btn')
🙂Również tak jak Przemek wspominał, pracujemy nad dodatkowym materiałem, w którym poruszymy różne praktyki znajdowania elementów (wraz z ich wadami i zaletami).
Tak, zgadza się Przemek robi refaktor w 27:40 i tutaj dla mnie powinno być powiedziane, że istnieje taka możliwość jak getByRole() ale zostawione już dalej jako ID, a filmie mimo iż zostało zmienione na ID to Przemek wrócił do getByRole() i to był moja uwaga. Tak jak mówię – fajnie, że taka funkcja istnieje bo nie zawsze możemy po ID wyszukać, ale jak mamy ID to zdecydowanie szukajmy po ID i takie podejście propagujmy od początku 😉
Co do CodeGen to ja tutaj nie mam do Was uwag, bo to jest mechanizm PW na który nie mamy wpływu.
BTW liczę, że w nowej wersji kursu w nowym kwartale? To będzie już poprawione, bo mam zamiar zakupić kurs 🙂
Zgodzę się, że dobre praktyki mogły być tu bardziej uwypuklone 🙂
Więcej o tym temacie, wadach i zaletach pokryjemy w materiale dedykowanym lokatorom i selektorom 🙂 Wstępnie planujemy podłączyć go do tego kursu, jednak tu jeszcze jesteśmy na etapie planowania struktury.
Jeśli wszystko nam się zepnie, to materiał ten pojawi sie jeszcze w tym kwartale. Natomiast kolejne otwarcie pełnego Programu o Automatyzacji z Playwright planujemy jeszcze w tym roku 🙂
Ja bym polemizowała z tym szukaniem po id. To znaczy również uważam, że jest najszybsze i najskuteczniejsze jeśli takowe posiadamy, ale… nie jest zgodne z zaleceniami z dokumentacji PlayWrighta. Według dokumentacji Playwrightowej powinniśmy najpierw lokalizować po czymś co użytkownik realnie widzi na stronie, a jeśli to nie wystawczy to dopiero wspomagać się innymi możliwościami.
https://playwright.dev/docs/locators
https://playwright.dev/docs/other-locators
Czy mi się to podoba? Raczej nie.. Ale może muszę podejść do tematu z bardziej otwartą głową.
Hej,
Słuszna uwaga 😉 Faktycznie w dokumentacji twórcy zalecają takie podejście (z getBy) jednak przy jego stosowaniu warto rozważyć jego wady i zalety 🙂
– getBy bywa mało precyzyjny i trzeba dodawać dodatkowe informacje o szukanych elementach
– uwzględnianie tekstu, który jest wyświetlony w elemencie, podczas szukania elementu może wpływać na niestabilność testów
– getBy moze miec zastosowanie jesli z jakiegoś powodu nie mamy id ani testid
Dużo zależy jakie testy piszemy w Playwright. Jeśli są to rozbudowane testy e2e różnych funkcjonalności dla skomplikowanej aplikacji, to raczej nie chcielibyśmy aby test się wysypywał na przycisku, któremu został zmieniony tekst. W takim przypadku naprawa testu może być kosztowna (od analizy błędu, rerun, az po MR i sprawdzenie na CI/CD).
Przy mniejszych aplikacjach – możemy zaryzykować, jednak musimy mieć na uwadze koszty z naprawą testów lub późniejsza zmianą na ID/data-testid 🙂
W jednym z dużych projektów, za pomocą Playwrighta testowaliśmy rozbudowane scenariusze e2e. Tam zastosowaliśmy podejście z data-testid (bo takie atrybuty dodawaliśmy również na front-endzie) – dzieki temu mieliśmy mniej pracy przy kosmetycznych aktualizacjach aplikacji (zmiana tekstu, języka etc).
Style i to co widzi użytkownik sprawdzaliśmy na niższych poziomach – w testach jednostkowych/modułowych front-endu 🙂
Reasumując – nie ma jednoznacznie dobrego podejścia, które sprawdzi się wszędzie 😉 Warto protestować oba z nich i zobaczyć jakie się z nimi wiążą zyski i koszta 🙂
Hej,
Mam drobny problem z asercją w trakcie testu – próbowałem twardej i miękkiej – await w tej asercji nie jest potrzebny ale próbowałem i z awaitem i mam problem ponieważ mimo iż w consoli za pomocą lokatora i odpowiednich indexów tabeli oraz wartości obiektu innerText lub innerHTML nie mogę wyjąć odpowiedniej opcji do porównania
Mój test:
Wydzielony kawałek posiada asercję zostwiłem na miękkiej jednak błąd przy teście w raporcie html’a jest przy zanestowanym indexie w odpowiedzzi – czy macie jakiś pomysł jak to obejść
Czy macie również z tym kłopot??
Z góry dziękuję za odpowiedź.
Pozdrawiam,
Jakub K
Hej,
Dobre pytanie!
W dużym uproszczeniu –
$$
i mechanizm Playwright do znajdowania elementów działa odrobinę inaczej.Poniżej rozpisałem 4 sposoby na wykonanie tej asercji. 3 dobre (zaleznie od kontekstu) i sposób 4 – nie do końca zalecany. Pomija on mechanizm auto-wait, który jest wbudowany w Playwright gdy asercję bazujemy na obiekcie lokatora.
Jeśli mamy kilka elementów i musimy sprawdzić jeden z nich, to musimy wykorzystać konstrukcję
element.nth(3)
, a jeśli chcemy z niego wybrać tekst – toawait options.nth(3).innerText()
(zawait
, bo to jest metoda asynchroniczna!)Rzuć okiem na poniższy kod – z różnymi opcjami, opisami i asercjami – na konsoli też możesz prześledzić jakie wyniki otrzymasz na poszczególnych etapach tego przykładu 🙂
Hej,
Pięknie dziękuję za Tipy:
Rezultaty:
Jak pierwszy raz puściłem z solucją nr 1 – strony nie miałem otwartej za żadnym razem – to otrzymałem błąd: ale z czasem na kolejnej asercji z prekroczeniej czasu:
ale jak puściłem solucję 2 i potem znów 1nkę to wsio zaczęło przechodzić bez problemu włącznie z pozostałymi solucjami – dziękuję bardzo za różne sposoby rozwiązania problemu super info i wyczerpujące.
Pozdrawiam i spokojności życzę,
Jakub K
Hej,
Ciesze się, że wszystko śmiga 🙂
Błąd związany z weryfikacją wiadomosci:
to znany błąd – czasem występuje w tej aplikacji. Na razie postanowiliśmy go zostawić bo nie występuje zbyt czesto, a kroki do jego reprodukcji nie są jasne.
Zatem jeśli test wysypał Ci się tylko na weryfikacji wiadomości, to znaczy, że poprzednie kroki działają poprawnie 🙂
Hej,
Okidoki to wszystko jasne zatem,
Dzięuję za analizę i odpowiedź
Poadrawiam i spokojności życze,
Jakub K
Hej, wspominacie krótko o dobrej praktyce usuwania test-dataid z aplikacji produkcyjnej. Macie może jakiś ciekawy materiał na ten temat, który możecie podlinkować?
Hej Arek!
Rozszerzyłem opis tutaj https://jaktestowac.pl/lesson/pw1s01l03/#Lokator_getByTestId() i podlinkowałem jeden artykuł:
https://dpericich.medium.com/removing-data-test-attributes-from-react-production-dom-5ea4ea018acc
Warto zauważyć, że sprzątanie po test id jest zależne od technologi użytej w projekcie i często używane są specjalne paczki, które czyszczą kod budowany na produkcję:
https://www.npmjs.com/package/babel-plugin-jsx-remove-data-test-id
Czyszczenie więc to bardziej zagadnienie deweloperskie, uzależnione od technologii i związane ze skryptami Ciągłej Integracji.
Hej,
Ja miałem taki problem, że test przechodził albo w wersji headed albo z opcją trace włączoną.
Po spędzonej godzinie i degugingu m.in. logów z API PW, okazało się, że w trybie headless event ‘domcontentloaded’ jest później (różnica kilkadziesiąt milisekund) niż w wersji headed, trace, etc. i powoduje to, że w momencie zamknięcia tego okna z potwierdzeniem zrobienia przelewu, wiadomość nie była wczytywana.
Pomogło dodanie `page.waitForLoadState(“domcontentloaded”)` zaraz po kliknięciu knefla logowania, a przed krokiem wyboru odbiorcy przelewu.
Hej,
Dzięki wielkie za zgłoszenie! Przeanalizowałem potencjalne powody, jednak nie udało mi się odkryć głównego. Główną trudnością była niewielka powtarzalność tego błędu. Mogła wystąpić kombinacja poniższych powodów:
problemy z hostingiem
problemy z połączeniem internetowym
nie optymalne rozwiązania zastosowane na testowanej stronie
zbyt dużą szybkością akcji, jakie wykonuje Playwright
Zaktualizowałem lekcje i dodałem dodatkowy kod z konstrukcją
page.waitForLoadState(“domcontentloaded”)
, który powinien zaopiekować ten problem 🙂Być może jest to kwestia TypeScript, którego właściwie nie znam, ale dlaczego po page.waitForLoadState(“domcontentloaded”) (linijka 12) nie ma średnika?
Słuszne spostrzeżenie!
Zarówno w JavaScript, jak i TypeScript, średniki są opcjonalne – mozna, ale nie trzeba ich stosować 😉
Oba podejścia mają swoje wady i zalety (oraz zwolenników).
W zależności od projektu mozna wypracować reguły, że np. zawsze je stosujemy, albo nigdy ich nie stosujemy. Najważniejsze jest ujednolicone podejście 🙂
I w tym przypadku – z racji, żę wszystkie linie maja średnik, a linia z
await page.waitForLoadState("domcontentloaded")
nie ma średnika – to jest drobny błąd do poprawy 😉Mam ten sam problem:
This page isn’t working
If the problem continues, contact the site owner.
HTTP ERROR 405
Dodatkowo w adresie url doklejany jest pytajnik, który widać w trybie –headed:
https://demo-bank.vercel.app/pulpit.html?
Zwiększenie timeoutów w configu u mnie nie pomaga
Pomogło ostatecznie dodanie w configu
Ale uważam, że to kiepskie rozwiązanie. Może ktoś ma jakieś inne sugestie? Dodawanie wszelkich dodatkowych waitów uważam za złą praktykę 🙁
Hej,
To prawda, że waity na sztywno to zła praktyka. W PW jest kilka sposobów na inteligentne czekanie (np. na zadany stan strony
await page.waitForLoadState('domcontentloaded');
albo na odpowiedz z API).Jednak HTTP ERROR 405 nie powinien mieć miejsca🤔
Również przed chwilą puszczałem testy i wszystko działało🤔
Podeślij mi proszę cały spakowany projekt na mail kontaktowy (znajdziesz go po prawej stronie w sekcji Znajdź nas lub na stronie /kontakt).
Dodaj też proszę dokładne logi jak wygląda błąd i co jest w konsoli.
Rzucę na niego okiem i spróbuje odnaleźć przyczynę tej 405 🙂
Czy jest możliwe ze Playwright próbje działać zbyt szybko? Próbowałem uruchamiać u siebie kod dokładnie taki jak na githubie i za każdym razem test failuje. Kiedy uruchamiam to w trybie headed to wygląda to tak, jakby wybór z dropdownu był za wolny i pozostałe dwa pola z kwotą i tutułem przelewu pozostają nie wypełnione.
Kiedy dodałem sztywny timeout po wyborze dropdownu
test przechodzi bez problemów
Hej,
Jaki dokładnie błąd dostajesz?
Rozumiem, że kod masz dokładnie taki sam jak w lekcji? 🤔
Daj znać to zbadam temat dokładniej 😉
Dostaję błąd dokłądnie taki jak dostał Przemek w 33 min nagrania.
Error: Timed out 5000ms waiting for expect(received).toHaveText(expected)
Expected string: “Przelew wykonany! Chuck Demobankowy – 120,00PLN – pizza”
Received string: “Brak wiadomości”
Call log:
– expect.toHaveText with timeout 5000ms
– waiting for locator(‘#show_messages’)
– locator resolved to Brak wiadomości
– unexpected value “Brak wiadomości”
– locator resolved to Brak wiadomości
– unexpected value “Brak wiadomości”
– locator resolved to Brak wiadomości
– unexpected value “Brak wiadomości”
– locator resolved to Brak wiadomości
– unexpected value “Brak wiadomości”
– locator resolved to Brak wiadomości
– unexpected value “Brak wiadomości”
– locator resolved to Brak wiadomości
– unexpected value “Brak wiadomości”
– locator resolved to Brak wiadomości
– unexpected value “Brak wiadomości”
– locator resolved to Brak wiadomości
– unexpected value “Brak wiadomości”
– locator resolved to Brak wiadomości
– unexpected value “Brak wiadomości”
Tylko, że u mnie ten błąd bez dodatkowego timeoutu występuje cały czas.
Próbowałem uruchomić test w trybie UI i tutaj nawet bez dodatkowego timeoutu błąd się nie pojawia i test przechodzi za każdym razem. Natomiast w trybie headed i headless bez timeoutu błąd jest za każdym razem.
Hm podejrzane 🤔
Puszczałem przed chwilą testy z najnowszymi paczkami (Playwright 1.38.1) na 2 różnych konfiguracjach (Win10 i Win11) i w różnych lokalizacjach – we wszystkich przypadkach problem nie występował 🤔 Dodatkowo puszczałem testy w pętli, ale również problem nie wystąpił:
Zamiast sztywnego czekania, możesz spróbować jeszcze dodać:
Jest to inteligentne czekanie, aż dokument się załaduje 🙂
Jeśli to nie pomoże – podeślij mi proszę cały spakowany projekt na maila (znajdziesz go po prawej stronie w sekcji Znajdź nas lub na stronie /kontakt) – to rzuce na niego okiem i spróbuje przeanalizować przyczynę tego błędu.
Hej,
można znaleźć w playwright.config.ts w sekcji expect – rzuć okiem do naszego repo: https://github.com/jaktestowac/playwright_automatyzacja_wprowadzenie/blob/main/S01_wprowadzenie/L02_testy_logowania/playwright.config.ts
Później podczas testów ten timeout jest brany pod uwagę przy asercjach expect jako czas czekania na elementy 🙂
Za kazdym razem wystepuje ten problem u mnie
Hej,
Wygląda na to, że dany napis z jakiegoś powodu jest ucięty na testowanej stronie.
Jak wygląda Twój kod testów?
Czy masz poprawnie skonstruowaną asercję lub wyszukiwanie elementu?
Daj mi proszę znać, jak to u Ciebie wygląda, a znajdziemy rozwiązanie 🙂
Błąd wskazuje, że dane, które są używane w teście (selektory i wartości) się nie zgadzają z oczekiwanymi wynikami.
Sam test wygląda poprawnie i gdy puściłem go u siebie, to zakończył się powodzeniem. Aczkolwiek nie był to kod, z którego wysłałeś poprzedni błąd, który dotyczył przelewu o tytule
pizza
– bez aktualnie używanego przez Ciebie kodu, ciężko będzie wskazać powód tego błędu 🙂Również jak wygląda cała informacja w konsoli?
Powyżej wiadomości, którą wysłałeś w pierwszej wiadomości, powinny być też takie wpisy:
Error: expect(received).toHaveText(expected)
Expected string: “Błędny oczekiwany napis”
Received string: “Przelew wykonany! Chuck Demobankowy – 100,25PLN – Test pizza”
Jak wygląda testowana strona w trakcie testu? Tutaj możesz użyć polecenia
npx playwright test --headed
Zrobilem maly refaktor swojego kodu i test teraz przechodzi pozytywnie, czy moge cos w nim usprawnic?
Doskonale, że już wszystko działa 😉 Czy udało Ci sie zlokalizować i okreslić wcześniejszy problem?
Jesli chodzi o dalsze usprawnienia – to pokażemy je w kolejnych lekcjach, które udostępnimy w najbliższych dniach – tam pokażemy zmniejszenie duplikacji kodu, wydzielenie wartości do zmiennych (które tu wykonałeś) oraz praktykę AAA czyli Arrange Act Assert. W dalszych lekcjach pokażemy jak zastosować wzorzec POM w tym projekcie 🙂
Spotykam kolejny problem, gdy chce wyswietlic kontent z selektora #show_messages, dostaje error z strony
jezeli odkomentuje kod I usune te dwie linie
to test przechodzi pozytywnie co tu moze byc nie take czy blad po waszej stronie?
Sprawdziłem po naszej stronie – Twój test działa poprawnie (musiałem tylko zakomentować logToApp):
Jaki wynik otrzymujesz, gdy wykonasz go manualnie?
Jak wygląda wynik gdy uruchamiasz testy z opcją –headed?
Hej tak jak powyżej przesłałem jak użyje testy z headed ,
otrzymuje kod z przeglądarki
This page isn’t workingIf the problem continues, contact the site owner.
HTTP ERROR 405
Jeśli możesz spakuj pliki z kodem (bez folderu node_modules) i podeślij do nas na maila kontakt (małpa) jaktestowac.pl Widząc cały kod i ustawienia będziemy mogli pomóc. Pozdro
Miałam te same błędy. Musiałam zwiększyć czas w playwright.config.ts . Dokładnie w tym miejscu:
* Maximum time expect() should wait for the condition to be met.
* For example in `await expect(locator).toHaveText();`
*/
timeout: 6000
Wcześniej miałam na 5000 i testy nie przechodziły, być może internet nie był wystarczająco szybki.
Może się tak zdarzyć, gdy aplikacja działa odrobinę wolniej w danym momencie.
Dodaliśmy stosowne informacje w pierwszych lekcjach 🙂
gdzie w playwright.config.ts można znaleźć? trzeba wejść gdzieś do powiązanych plików?
* Maximum time expect() should wait for the condition to be met.
* For example in `await expect(locator).toHaveText();`
*/
timeout: 500