{"id":29833,"date":"2024-12-13T05:00:00","date_gmt":"2024-12-13T04:00:00","guid":{"rendered":"https:\/\/sii.pl\/blog\/?p=29833"},"modified":"2025-05-07T13:01:02","modified_gmt":"2025-05-07T11:01:02","slug":"playwright-w-praktyce-5-krokow-do-skutecznego-frameworka-do-automatyzacji-testow-ui-web-czesc-i","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/playwright-w-praktyce-5-krokow-do-skutecznego-frameworka-do-automatyzacji-testow-ui-web-czesc-i\/","title":{"rendered":"Playwright w praktyce: 5 krok\u00f3w do skutecznego frameworka do automatyzacji test\u00f3w UI &amp; Web. Cz\u0119\u015b\u0107 I"},"content":{"rendered":"\n<p>Tym artyku\u0142em chcia\u0142bym rozpocz\u0105\u0107 seri\u0119 wpis\u00f3w, w kt\u00f3rej poka\u017c\u0119, jak krok po kroku zbudowa\u0107 nowoczesny framework do automatyzacji test\u00f3w, korzystaj\u0105c z <strong>Playwrighta<\/strong> oraz <strong>TypeScripta<\/strong>.<\/p>\n\n\n\n<p>Istniej\u0105 r\u00f3\u017cne opinie na temat tego, czy w\u0142a\u015bciwszym okre\u015bleniem jest \u201eframework testowy\u201d, czy \u201ebiblioteka testowa\u201d. Niemniej, przyjmuj\u0119, \u017ce na potrzeby tej serii artyku\u0142\u00f3w u\u017cywamy terminu \u201eframework testowy\u201d.<\/p>\n\n\n\n<p>Jaki\u015b czas temu opublikowa\u0142em wpis, w kt\u00f3rym opisa\u0142em, <a href=\"https:\/\/sii.pl\/blog\/playwright-dlaczego-warto-zainteresowac-sie-narzedziem-od-microsoftu\/\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\">jak rozpocz\u0105\u0107 swoj\u0105 przygod\u0119 z Playwrightem<\/a>. R\u00f3wnie\u017c <a href=\"https:\/\/sii.pl\/blog\/all\/playwright\/\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\">dwa inne artyku\u0142y na temat Playwrighta<\/a> pojawi\u0142y si\u0119 na blogu Sii nieco p\u00f3\u017aniej.<\/p>\n\n\n\n<p>Dzi\u015b p\u00f3jdziemy o krok dalej. Skupimy si\u0119 na tym, jak stworzy\u0107 bardziej zaawansowane rozwi\u0105zanie \u2013 takie, kt\u00f3re b\u0119dziecie mogli zastosowa\u0107 w swojej codziennej pracy.<\/p>\n\n\n\n<p>Na pocz\u0105tek warto zastanowi\u0107 si\u0119 nad wyborem odpowiedniego j\u0119zyka programowania. Przyjrzymy si\u0119 i por\u00f3wnamy r\u00f3\u017cne opcje, aby wybra\u0107 najlepsze narz\u0119dzie do realizacji naszych cel\u00f3w.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Popularno\u015b\u0107 rozwi\u0105zania \u2013 dlaczego TypeScript?<\/li>\n\n\n\n<li>Czym powinien charakteryzowa\u0107 si\u0119 framework testowy?<\/li>\n\n\n\n<li>Wzorce projektowe i dobre praktyki<\/li>\n\n\n\n<li>Raportowanie<\/li>\n\n\n\n<li>CI \/ CD<\/li>\n<\/ol>\n\n\n\n<p>Temat podziel\u0119 na dwie cz\u0119\u015bci \u2013 w pierwszej skupi\u0119 si\u0119 troch\u0119 bardziej na teorii i podkre\u015bleniu, kt\u00f3re obszary s\u0105 wa\u017cne, za\u015b w kolejnej poka\u017c\u0119 kod i om\u00f3wi\u0119 go krok po kroku. Ca\u0142o\u015b\u0107 kodu b\u0119dzie dost\u0119pna wraz z drugim wpisem.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Kod<\/strong><\/h2>\n\n\n\n<p>Nasz framework testowy b\u0119dzie zawiera\u0142 dwa przyk\u0142ady test\u00f3w, kt\u00f3re b\u0119d\u0105 mo\u017cliwe do pobrania z <a href=\"https:\/\/github.com\/sii-poland\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >GitHub Sii Poland<\/a>.<\/p>\n\n\n\n<p>Do stworzenia test\u00f3w skorzystam z Trello.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image1-1.png\"><img decoding=\"async\" width=\"759\" height=\"427\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image1-1.png\" alt=\"Trello \u2013 aplikacja do zarz\u0105dzania projektami\" class=\"wp-image-29834\" style=\"width:377px;height:auto\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image1-1.png 759w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image1-1-300x169.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image1-1-555x312.png 555w\" sizes=\"(max-width: 759px) 100vw, 759px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 1 Trello \u2013 aplikacja do zarz\u0105dzania projektami<\/figcaption><\/figure>\n\n\n\n<p>Trello to aplikacja s\u0142u\u017c\u0105ca do zarz\u0105dzania projektami z wykorzystaniem metodologii Kanban. Jest to zaawansowane narz\u0119dzie zar\u00f3wno pod wzgl\u0119dem interfejsu u\u017cytkownika (UI), jak i mo\u017cliwo\u015bci API. <strong>Z naszej perspektywy stanowi doskona\u0142e \u015brodowisko do \u0107wiczenia umiej\u0119tno\u015bci zwi\u0105zanych z automatyzacj\u0105 proces\u00f3w<\/strong>.<\/p>\n\n\n\n<p>Do cel\u00f3w testowych zach\u0119camy do za\u0142o\u017cenia konta \u2013 bezp\u0142atny plan jest w zupe\u0142no\u015bci wystarczaj\u0105cy.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Dlaczego TypeScript?<\/strong><\/h2>\n\n\n\n<p>TypeScript to popularny j\u0119zyk programowania, od lat wykorzystywany g\u0142\u00f3wnie do tworzenia front-endu w aplikacjach webowych. Istnieje kilka powod\u00f3w, dla kt\u00f3rych TypeScript doskonale sprawdza si\u0119 jako j\u0119zyk dla framework\u00f3w testowych.<\/p>\n\n\n\n<p>Oto najwa\u017cniejsze argumenty:<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"1\">\n<li><strong>Silne typowanie<\/strong> \u2013 umo\u017cliwia wykrywanie b\u0142\u0119d\u00f3w na etapie kompilacji, co zwi\u0119ksza stabilno\u015b\u0107 kodu.<\/li>\n\n\n\n<li><strong>Lepsza wsp\u00f3\u0142praca z Playwright API<\/strong> \u2013 Playwright w po\u0142\u0105czeniu z TypeScriptem oferuje najwi\u0119ksz\u0105 liczb\u0119 usprawnie\u0144 i nowych funkcji w por\u00f3wnaniu do innych implementacji.<\/li>\n\n\n\n<li><strong>Wbudowane wsparcie dla async\/await<\/strong> \u2013 u\u0142atwia tworzenie stabilnych i czytelnych test\u00f3w automatycznych.<\/li>\n\n\n\n<li><strong>Popularno\u015b\u0107 i wsparcie spo\u0142eczno\u015bci<\/strong> \u2013 dzi\u0119ki du\u017cej spo\u0142eczno\u015bci \u0142atwo znale\u017a\u0107 odpowiedzi na pytania, a sam Playwright zosta\u0142 stworzony w TypeScript.<\/li>\n<\/ol>\n\n\n\n<p>Warto doda\u0107, \u017ce mimo zalet TypeScriptu, Playwright mo\u017cna u\u017cywa\u0107 tak\u017ce w innych j\u0119zykach programowania, takich jak C# czy Java. Sam z powodzeniem korzysta\u0142em z tych implementacji w codziennej pracy i r\u00f3wnie\u017c si\u0119 sprawdza\u0142y.<\/p>\n\n\n\n<p>Dla os\u00f3b, kt\u00f3re nie planuj\u0105 korzysta\u0107 z TypeScriptu, <strong>artyku\u0142 nadal mo\u017ce okaza\u0107 si\u0119 warto\u015bciowy<\/strong>, poniewa\u017c koncepcje zwi\u0105zane z tworzeniem testowego frameworka s\u0105 sp\u00f3jne niezale\u017cnie od technologii.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Popularno\u015b\u0107 rozwi\u0105zania \u2013 TypeScript a inne j\u0119zyk programowania<\/strong><\/h2>\n\n\n\n<p>Gdy pisa\u0142em artyku\u0142 <a href=\"https:\/\/sii.pl\/blog\/playwright-dlaczego-warto-zainteresowac-sie-narzedziem-od-microsoftu\/\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\">Playwright \u2013 dlaczego warto zainteresowa\u0107 si\u0119 narz\u0119dziem od Microsoftu?<\/a>, Playwright powoli stawa\u0142 si\u0119 coraz popularniejszym rozwi\u0105zaniem do automatyzacji test\u00f3w. Obecnie przej\u0105\u0142 prowadzenie nad Cypressem i Selenium w ilo\u015bci pobra\u0144 miesi\u0119cznych. R\u00f3wnie\u017c w ofertach pracy mo\u017cna zauwa\u017cy\u0107, \u017ce liczba ofert, w kt\u00f3rych Playwright jest\/bywa wymagany, ro\u015bnie.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image2.png\"><img decoding=\"async\" width=\"1024\" height=\"443\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image2-1024x443.png\" alt=\"Liczba pobra\u0144 Cypress, Playwright i Selenium w ostatnim roku \" class=\"wp-image-29838\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image2-1024x443.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image2-300x130.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image2-768x332.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image2-1536x664.png 1536w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image2-2048x886.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 2 <a href=\"https:\/\/npmtrends.com\/cypress-vs-playwright-vs-selenium-webdriver\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >Liczba pobra\u0144 Cypress, Playwright i Selenium w ostatnim roku<\/a><\/figcaption><\/figure>\n\n\n\n<p>Warto podkre\u015bli\u0107, \u017ce <strong>nie twierdz\u0119, i\u017c Selenium czy Cypress to z\u0142e narz\u0119dzia<\/strong>. Korzysta\u0142em z obu w r\u00f3\u017cnych projektach i uwa\u017cam, \u017ce przy odpowiednim do\u015bwiadczeniu osoby pisz\u0105cej testy mo\u017cna osi\u0105gn\u0105\u0107 bardzo dobre rezultaty w obu przypadkach.<\/p>\n\n\n\n<p>To, co przyci\u0105ga mnie do Playwright i dlaczego tak ch\u0119tnie o nim pisz\u0119 oraz tworz\u0119 prezentacje, to fakt, \u017ce narz\u0119dzie wyr\u00f3\u017cnia si\u0119 dynamicznym rozwojem i oferuje <strong>kilka rozwi\u0105za\u0144, kt\u00f3re uwa\u017cam za bardziej efektywne<\/strong>.<\/p>\n\n\n\n<p>Warto jednak obserwowa\u0107 rozw\u00f3j innych narz\u0119dzi, takich jak Selenium, gdzie od jakiego\u015b czasu prowadzone s\u0105 intensywne prace. Mo\u017ce to sprawi\u0107, \u017ce w przysz\u0142o\u015bci Selenium stanie si\u0119 jeszcze bardziej popularnym i nowoczesnym rozwi\u0105zaniem. Trzeba r\u00f3wnie\u017c zaznaczy\u0107, \u017ce wi\u0119kszo\u015b\u0107 koncept\u00f3w dla test\u00f3w API czy UI jest podobnych, wi\u0119c nawet je\u015bli nie korzystasz z Playwrighta, ten artyku\u0142 mo\u017ce by\u0107 przydatny dla Ciebie.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Czym powinien charakteryzowa\u0107 si\u0119 framework testowy?<\/strong><\/h2>\n\n\n\n<p>Framework testowy powinien pozwala\u0107 tworzy\u0107 rozwi\u0105zania \u0142atwo utrzymywane oraz wspiera\u0107 kilka obszar\u00f3w:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Wzorce projektowe i dobre praktyki <\/strong>\u2013 w naszym rozwi\u0105zaniu musimy uwzgl\u0119dni\u0107 u\u017cycie praktyk, kt\u00f3re pozwol\u0105 nam na \u0142atwe rozwijanie narz\u0119dzia i jego utrzymywanie.<\/li>\n\n\n\n<li><strong>Wsp\u00f3\u0142bie\u017cno\u015b\u0107 <\/strong>\u2013 poza dbaniem o wzrost pokrycia testami, r\u00f3wnie wa\u017cnym aspektem jest zadbanie o to, \u017ceby testy uruchamia\u0142y si\u0119 najszybciej jak to mo\u017cliwe.<\/li>\n\n\n\n<li><strong>Raportowanie wynik\u00f3w test\u00f3w<\/strong> \u2013 wdro\u017cenie efektywnego sposobu raportowania wynik\u00f3w z test\u00f3w. O <a aria-label=\" (opens in a new tab)\" href=\"Trace%20Viewer%20w%20Playwright%20\u2013%20jak%20uzyska\u0107%20szczeg\u00f3\u0142owy%20raport%20z%20test\u00f3w?\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >Raportowaniu w Playwright napisa\u0142em artyku\u0142<\/a>.<\/li>\n\n\n\n<li><strong>CI\/CD<\/strong> \u2013&nbsp; nawet najlepszy framework testowy, je\u015bli nie jest zintegrowany z naszymi narz\u0119dziami CI\/CD, staje si\u0119 istotnym problem ca\u0142ego rozwi\u0105zania.<\/li>\n<\/ul>\n\n\n\n<p>Warto te\u017c zwr\u00f3ci\u0107 uwag\u0119 na piramid\u0119 test\u00f3w, w taki spos\u00f3b, aby nie mie\u0107 ogromnej ilo\u015bci test\u00f3w UI, tylko stara\u0107 si\u0119 przenosi\u0107 te testy do ni\u017cszej warstwy, je\u017celi jest to mo\u017cliwe. Oczywi\u015bcie du\u017co zale\u017cy od architektury aplikacji. W sytuacji, gdy tworzymy testy dla aplikacji sk\u0142adaj\u0105cej si\u0119 z mirkoserwis\u00f3w, prawdopodobnie przede wszystkim lepszym wyj\u015bcie b\u0119dzie skupienie si\u0119 na testach integracyjnych\/kontraktowych.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image3-2.png\"><img decoding=\"async\" width=\"560\" height=\"300\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image3-2.png\" alt=\"Piramida test\u00f3w \" class=\"wp-image-29840\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image3-2.png 560w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image3-2-300x161.png 300w\" sizes=\"(max-width: 560px) 100vw, 560px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 3 <a href=\"https:\/\/martinfowler.com\/bliki\/TestPyramid.html\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >Piramida test\u00f3w<\/a><\/figcaption><\/figure>\n\n\n\n<p>Widzia\u0142em r\u00f3\u017cne implementacje piramidy test\u00f3w \u2013 wa\u017cne jest, aby d\u0105\u017cy\u0107 do umieszczania test\u00f3w funkcjonalnych na ni\u017cszych poziomach piramidy. Dzi\u0119ki temu staj\u0105 si\u0119 one stabilniejsze i szybciej si\u0119 wykonuj\u0105.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Wzorce projektowe i dobre praktyki<\/strong><\/h2>\n\n\n\n<p>Framework testowy powinien wspiera\u0107 wzorce projektowe stosowane w naszym rozwi\u0105zaniu. Oznacza to, \u017ce ma by\u0107 wystarczaj\u0105co elastyczny, aby umo\u017cliwia\u0107 korzystanie z dobrych praktyk. Playwright spe\u0142nia te wymagania, dlatego przedstawi\u0119 kilka praktyk, kt\u00f3re mog\u0105 pom\u00f3c w stworzeniu rozwi\u0105zania \u0142atwego w utrzymaniu oraz sprzyjaj\u0105cego przyjemnemu i efektywnemu tworzeniu kolejnych test\u00f3w.<\/p>\n\n\n\n<p>Zacznijmy od om\u00f3wienia <strong>Fixtures<\/strong>!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Fixtures<\/strong><\/h2>\n\n\n\n<p>Jest to przydatny mechanizm znany w \u015bwiecie TypeScript\/JavaScript, kt\u00f3ry umo\u017cliwia tworzenie cz\u0119\u015bci kodu wielokrotnego u\u017cytku w r\u00f3\u017cnych obszarach test\u00f3w. Mechanizm ten \u015bwietnie sprawdza si\u0119 w przypadku obiekt\u00f3w typu Page Object lub innych element\u00f3w, kt\u00f3re chcemy zainicjalizowa\u0107 w jednym miejscu i wykorzystywa\u0107 w wielu miejscach, na przyk\u0142ad w kodzie test\u00f3w.<\/p>\n\n\n\n<p>Zalety podej\u015bcia:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>mo\u017cliwo\u015b\u0107 wielokrotnego wykorzystania danych,<\/li>\n\n\n\n<li>zwi\u0119kszona czytelno\u015b\u0107,<\/li>\n\n\n\n<li>zwi\u0119kszona czytelno\u015b\u0107.<\/li>\n<\/ul>\n\n\n\n<p>Wady podej\u015bcia:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>narzut spowodowany utrzymywaniem koncepcji,<\/li>\n\n\n\n<li>potencjalne zbyt du\u017ce klasy, kt\u00f3re zawieraj\u0105 zbyt wiele inicjalizacji obiekt\u00f3w.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Jak to dzia\u0142a w praktyce?<\/strong><\/h3>\n\n\n\n<p>W poni\u017cszym kodzie znajdziemy kilka element\u00f3w wymaganych w r\u00f3\u017cnych testach. Przyk\u0142adem jest klasa LoginTrelloPage, kt\u00f3ra reprezentuje Page Object. Jest ona wykorzystywana w wielu testach, w kt\u00f3rych konieczne jest logowanie do aplikacji.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image4.png\"><img decoding=\"async\" width=\"1024\" height=\"752\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image4-1024x752.png\" alt=\"kod\" class=\"wp-image-29843\" style=\"object-fit:cover;width:538px;height:auto\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image4-1024x752.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image4-300x220.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image4-768x564.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image4.png 1318w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>W naszym kodzie typ TrelloFixtures b\u0119dzie zawiera\u0142 dodatkowe definicje element\u00f3w, kt\u00f3re b\u0119d\u0105 wielokrotnie u\u017cywane. Przyk\u0142adem jest obiekt strony TrelloLoginPage przyjmuj\u0105cy jako parametr obiekt page. Obiekt ten jest odpowiedzialny za interakcj\u0119 z dan\u0105 stron\u0105 w Playwright. Dodatkowo, type Settings pozwala na przekazywanie niezb\u0119dnych warto\u015bci konfiguracyjnych. Warto zwr\u00f3ci\u0107 uwag\u0119 na fakt, \u017ce poza inicjalizacj\u0105 obiektu, mo\u017cliwe jest tak\u017ce wykonywanie akcji, takich jak await page.goto, kt\u00f3ra umo\u017cliwia przej\u015bcie do strony powi\u0105zanej z danym obiektem strony.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image5.png\"><img decoding=\"async\" width=\"1024\" height=\"255\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image5-1024x255.png\" alt=\"kod\" class=\"wp-image-29845\" style=\"width:751px;height:auto\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image5-1024x255.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image5-300x75.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image5-768x191.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image5-1536x382.png 1536w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image5.png 1794w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Page Object Pattern<\/strong><\/h2>\n\n\n\n<p>Czym jest Page Object Pattern? Jak zapewne wiecie, jest to popularny wzorzec projektowy rozpropagowany przez Martina Fowlera, znanego programist\u0119 zwi\u0105zanego z firm\u0105 ThoughtWorks. To w\u0142a\u015bnie on stoi tak\u017ce za innym znanym konceptem, jakim jest Piramida Test\u00f3w.<\/p>\n\n\n\n<p>Page Object Pattern polega na tworzeniu klasy powi\u0105zanej z konkretn\u0105 stron\u0105 aplikacji, kt\u00f3ra zawiera zdefiniowane elementy oraz akcje zwi\u0105zane z t\u0105 stron\u0105. Dzi\u0119ki temu uzyskujemy czytelny kod u\u0142atwiaj\u0105cy utrzymanie test\u00f3w.<\/p>\n\n\n\n<p>Oczywi\u015bcie istnieje wiele r\u00f3\u017cnych implementacji tego wzorca, jednak z mojej perspektywy kluczowe jest rozpocz\u0119cie od przekazania \u015bwie\u017cego obiektu, kt\u00f3ry odpowiada za kontrolowanie akcji w danym oknie przegl\u0105darki. W \u015bwiecie Playwright takim obiektem jest <strong>page<\/strong>.<\/p>\n\n\n\n<p>Obiekt page reprezentuje pojedyncz\u0105 stron\u0119 w przegl\u0105darce i umo\u017cliwia interakcj\u0119 z jej elementami. Dla os\u00f3b, kt\u00f3re nie znaj\u0105 Playwrighta, mo\u017ce to by\u0107 mniej intuicyjne, ale w praktyce jest to <strong>niezwykle efektywne rozwi\u0105zanie<\/strong>.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image6.png\"><img decoding=\"async\" width=\"1024\" height=\"751\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image6-1024x751.png\" alt=\"kod\" class=\"wp-image-29847\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image6-1024x751.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image6-300x220.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image6-768x563.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image6-1536x1126.png 1536w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image6-2048x1502.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Id\u0105c dalej w naszym przyk\u0142adzie, jakim jest <strong>TrelloLoginPage,<\/strong> naturaln\u0105 metod\u0105 b\u0119dzie <strong>login<\/strong>, umo\u017cliwiaj\u0105ca zalogowanie si\u0119 do aplikacji. Selectory warto przechowywa\u0107 jako pola klasy, na przyk\u0142ad <strong>loginButtonSelector<\/strong>, co u\u0142atwia ich utrzymanie i ponowne wykorzystanie. Dodatkowo metoda <strong>getAllBoardVisibleStatus()<\/strong> mog\u0142aby zwraca\u0107 status widoczno\u015bci elementu reprezentuj\u0105cego wszystkie \u201eboards\u201d dost\u0119pne po zalogowaniu.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Factory Pattern<\/strong><\/h2>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image7.png\"><img decoding=\"async\" width=\"1024\" height=\"537\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image7-1024x537.png\" alt=\"kod\" class=\"wp-image-29849\" style=\"object-fit:cover\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image7-1024x537.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image7-300x157.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image7-768x403.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image7-1536x806.png 1536w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image7-1920x1008.png 1920w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image7.png 1922w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Z mojej perspektywy, w kontek\u015bcie tworzenia rozwi\u0105za\u0144 dla test\u00f3w automatycznych, ten wzorzec mo\u017ce si\u0119 sprawdzi\u0107. Oczywi\u015bcie istniej\u0105 bardziej zaawansowane zastosowania, jednak zbyt z\u0142o\u017cona abstrakcja mo\u017ce prowadzi\u0107 do dodatkowych problem\u00f3w.<\/p>\n\n\n\n<p>W naszych przyk\u0142adach za\u0142\u00f3\u017cmy, \u017ce tworzymy dwie klasy typu Factory:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>pierwsz\u0105 dla obiekt\u00f3w typu Card, czyli <strong>FactoryCard<\/strong>, kt\u00f3ra b\u0119dzie zawiera\u0107 metod\u0119 do tworzenia okre\u015blonej karty w Trello,<\/li>\n\n\n\n<li>drug\u0105 \u2013 <strong>BoardFactor,<\/strong> odpowiedzialn\u0105 za tworzenie boardu w Trello.<\/li>\n<\/ul>\n\n\n\n<p>Zalety podej\u015bcia:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>reu\u017cywalno\u015b\u0107 kodu i standaryzacja,<\/li>\n\n\n\n<li>mo\u017cliwo\u015b\u0107 tworzenia r\u00f3\u017cnych wariant\u00f3w naszych obiekt\u00f3w,<\/li>\n\n\n\n<li>\u0142atwiejsze utrzymywanie kodu i refaktoryzacja danych testowych,<\/li>\n\n\n\n<li>oddzielenie logiki tworzenia obiekt\u00f3w od test\u00f3w.<\/li>\n<\/ul>\n\n\n\n<p>Wady podej\u015bcia:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>potencjalnie skomplikowany kod,<\/li>\n\n\n\n<li>dodatkowa warstwa abstrakcji \u2013 potencjalnie mo\u017ce wprowadzi\u0107 to trudniejsze zrozumienie kodu.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Parallelism \u2013 uruchamianie test\u00f3w wsp\u00f3\u0142bie\u017cnie<\/strong><\/h2>\n\n\n\n<p>Jednym z kluczowych aspekt\u00f3w, o kt\u00f3rych warto pami\u0119ta\u0107 podczas tworzenia frameworka do test\u00f3w automatycznych, jest wyb\u00f3r narz\u0119dzia umo\u017cliwiaj\u0105cego wsp\u00f3\u0142bie\u017cne uruchamianie test\u00f3w.<\/p>\n\n\n\n<p><strong>Czym w\u0142a\u015bciwie jest wsp\u00f3\u0142bie\u017cne uruchamianie test\u00f3w?<\/strong> To proces, w kt\u00f3rym zamiast korzysta\u0107 z jednego w\u0105tku, testy s\u0105 wykonywane r\u00f3wnolegle w wielu w\u0105tkach, co znacz\u0105co skraca czas ich realizacji. Uwa\u017cam, \u017ce jest to jeden z najistotniejszych element\u00f3w pracy testera automatyzuj\u0105cego. Samo dodawanie kolejnych test\u00f3w niewiele wnosi, je\u015bli ich uruchamianie zajmuje wiele godzin lub nawet dni. Skupienie si\u0119 na tym aspekcie mo\u017ce znacznie przyspieszy\u0107 dostarczanie rozwi\u0105za\u0144.<\/p>\n\n\n\n<p>Przyk\u0142adem mo\u017ce by\u0107 jeden z projekt\u00f3w, w kt\u00f3rym wraz z zespo\u0142em wdro\u017cyli\u015bmy Playwrighta w po\u0142\u0105czeniu z C#. <strong>Przy liczbie oko\u0142o 150 do\u015b\u0107 skomplikowanych test\u00f3w UI &amp; API, ich czas uruchomienia na czterech w\u0105tkach wynosi\u0142 zaledwie 8 minut<\/strong>, czyli stosunkowo kr\u00f3tko. Gdyby\u015bmy zwi\u0119kszyli ilo\u015b\u0107 w\u0105tk\u00f3w, ten czas m\u00f3g\u0142by by\u0107 jeszcze bardziej satysfakcjonuj\u0105cy.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Mo\u017cliwo\u015b\u0107 korzystania z parallelismu w Playwright<\/strong><\/h2>\n\n\n\n<p>Sam temat wykorzystania wsp\u00f3\u0142bie\u017cno\u015bci m\u00f3g\u0142by by\u0107 tematem osobnego artyku\u0142u lub publikacji, jednak postaram si\u0119 na kilku przyk\u0142adach przedstawi\u0107, jakie mo\u017cliwo\u015bci oferuje Playwright w tym zakresie.<\/p>\n\n\n\n<p>Pierwsz\u0105 istotn\u0105 rzecz\u0105 jest szeroki wachlarz opcji dotycz\u0105cych sposobu wykorzystania wsp\u00f3\u0142bie\u017cno\u015bci. Mo\u017cemy na przyk\u0142ad uruchamia\u0107 wszystkie testy wsp\u00f3\u0142bie\u017cne lub niekt\u00f3re z nich. Warto przygotowa\u0107 rozwi\u0105zanie, tak \u017ceby wszystkie testy by\u0142y uruchamiane wsp\u00f3\u0142bie\u017cnie. \u00a0Takie podej\u015bcie jest szczeg\u00f3lnie polecane, poniewa\u017c najlepiej unika\u0107 wyj\u0105tk\u00f3w i dostosowa\u0107 testy w taki spos\u00f3b, aby wszystkie mog\u0142y dzia\u0142a\u0107 wsp\u00f3\u0142bie\u017cnie, co zwi\u0119ksza efektywno\u015b\u0107 i skraca czas wykonania test\u00f3w.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image8.png\"><img decoding=\"async\" width=\"1024\" height=\"601\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image8-1024x601.png\" alt=\"kod\" class=\"wp-image-29851\" style=\"object-fit:cover\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image8-1024x601.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image8-300x176.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image8-768x451.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image8-1536x901.png 1536w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image8-2048x1202.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Gdy ustawimy w pliku <strong>playwright.config.ts<\/strong>opcj\u0119<strong> fullyParallel<\/strong> na \u201etrue\u201d, to automatycznie wszystkie testy b\u0119d\u0105 si\u0119 uruchamia\u0142y wsp\u00f3\u0142bie\u017cnie. To, co jest r\u00f3wnie\u017c ciekawe \u2013 je\u017celi mamy zdefiniowan\u0105 wi\u0119cej ni\u017c jedn\u0105 przegl\u0105dark\u0119, np. korzystamy z chromium i firefoxa, to na obu przegl\u0105darkach owe testy uruchomi\u0105 si\u0119 w spos\u00f3b wsp\u00f3\u0142bie\u017cny.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Parallel w klasie<\/strong><\/h3>\n\n\n\n<p>W Playwright istnieje r\u00f3wnie\u017c mo\u017cliwo\u015b\u0107 zdefiniowania wsp\u00f3\u0142bie\u017cno\u015bci na poziomie klasy testowej \u2013 czy dana klasa ma korzysta\u0107 ze wsp\u00f3\u0142bie\u017cno\u015bci, czy nie. Moim zdaniem lepiej jednak zainwestowa\u0107 czas, aby <strong>zapewni\u0107 poprawne dzia\u0142anie test\u00f3w w \u015brodowisku wsp\u00f3\u0142bie\u017cnym<\/strong>, zamiast tworzy\u0107 obej\u015bcia (tzw. workarounds). Dzi\u0119ki temu unikniemy sytuacji, w kt\u00f3rej cz\u0119\u015b\u0107 test\u00f3w dzia\u0142a wsp\u00f3\u0142bie\u017cnie, a inne nie, co z kolei poprawi sp\u00f3jno\u015b\u0107 i utrzymanie ca\u0142ej bazy testowej.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image9.png\"><img decoding=\"async\" width=\"1024\" height=\"265\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image9-1024x265.png\" alt=\"kod\" class=\"wp-image-29855\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image9-1024x265.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image9-300x78.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image9-768x199.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image9-1536x397.png 1536w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image9-2048x530.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Sharding<\/strong><\/h3>\n\n\n\n<p>Jednym z interesuj\u0105cych mechanizm\u00f3w oferowanych przez Playwright jest tzw. Sharding. Mechanizm ten, zwany r\u00f3wnie\u017c fragmentacj\u0105 lub podzia\u0142em, pozwala na rozdzielenie test\u00f3w automatycznych na mniejsze cz\u0119\u015bci (np. cztery fragmenty) i ich r\u00f3wnoleg\u0142e uruchamianie w osobnych zadaniach (jobach) w systemie CI.<\/p>\n\n\n\n<p>Sharding okazuje si\u0119 szczeg\u00f3lnie przydatny, gdy nie planujemy korzysta\u0107 z bardziej zaawansowanych narz\u0119dzi (takich jak Moon), czy platform do test\u00f3w w chmurze (takich jak np.:, &nbsp;BrowserStack, SauceLabs czy LambdaTest lub inne). Dzi\u0119ki uruchamianiu test\u00f3w w podzielonej formie na wielu jobach mo\u017cemy znacz\u0105co skr\u00f3ci\u0107 ca\u0142kowity czas wykonania test\u00f3w automatycznych, co pozytywnie wp\u0142ywa na efektywno\u015b\u0107 procesu.<\/p>\n\n\n\n<p>Dodatkowym atutem tego rozwi\u0105zania jest mo\u017cliwo\u015b\u0107 integracji wynik\u00f3w test\u00f3w. Standardowo wyniki s\u0105 generowane oddzielnie dla ka\u017cdego zadania (joba), jednak mo\u017cna je scali\u0107 w jeden zbiorczy raport. Taki <strong>raport znacz\u0105co u\u0142atwia analiz\u0119 wynik\u00f3w i monitorowanie efekt\u00f3w przeprowadzonych test\u00f3w, zapewniaj\u0105c sp\u00f3jny obraz jako\u015bci aplikacji<\/strong>.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image10-1.png\"><img decoding=\"async\" width=\"1024\" height=\"208\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image10-1-1024x208.png\" alt=\"kod\" class=\"wp-image-29857\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image10-1-1024x208.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image10-1-300x61.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image10-1-768x156.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image10-1-1536x312.png 1536w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image10-1-2048x416.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image11.png\"><img decoding=\"async\" width=\"1024\" height=\"268\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image11-1024x268.png\" alt=\"kod\" class=\"wp-image-29859\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image11-1024x268.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image11-300x78.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image11-768x201.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image11-1536x402.png 1536w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image11-2048x536.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Asercje \u2013 jak podej\u015b\u0107 do asercji w naszym rozwi\u0105zaniu?<\/strong><\/h2>\n\n\n\n<p>Podej\u015bcie do asercji w testach mo\u017ce by\u0107 r\u00f3\u017cnorodne i jest szeroko opisywane w literaturze oraz publikacjach. Moim zdaniem kluczowe jest, aby klasa Page Object nie zawiera\u0142a asercji, lecz jedynie umo\u017cliwia\u0142a zwracanie stanu danego obiektu. Na przyk\u0142ad: zamiast wykonywa\u0107 asercj\u0119 w klasie, powinna ona zwraca\u0107 stan widoczno\u015bci elementu, pozostawiaj\u0105c sam\u0105 weryfikacj\u0119 do wykonania w kodzie testu.<\/p>\n\n\n\n<p>Istniej\u0105 jednak sytuacje, w kt\u00f3rych trudno jest zwr\u00f3ci\u0107 stan elementu wprost, na przyk\u0142ad, gdy nale\u017cy sprawdzi\u0107 kilka p\u00f3l jednego obiektu (jak w\u0142a\u015bciwo\u015bci produktu dodanego do koszyka w sklepie internetowym). W takich przypadkach mo\u017cna zmapowa\u0107 wszystkie warto\u015bci obiektu na odpowiednie pola i zapisa\u0107 je w dedykowanym obiekcie. Dzi\u0119ki temu klasa Page Object mo\u017ce zwr\u00f3ci\u0107 taki obiekt, a weryfikacja poprawno\u015bci odbywa si\u0119 w kodzie testu poprzez por\u00f3wnanie obiektu pobranego ze strony z wcze\u015bniej zdefiniowanym obiektem referencyjnym.<\/p>\n\n\n\n<p>Alternatywnym rozwi\u0105zaniem jest utworzenie dedykowanej klasy zawieraj\u0105cej metody do bardziej zaawansowanego sprawdzania poprawno\u015bci. Przyk\u0142ad takiego podej\u015bcia znajduje si\u0119 poni\u017cej. Nale\u017cy jednak pami\u0119ta\u0107 o potencjalnych ryzykach zwi\u0105zanych z tym podej\u015bciem \u2013 na przyk\u0142ad, je\u015bli nazwa metody w tej klasie b\u0119dzie b\u0142\u0119dna, mo\u017ce to prowadzi\u0107 do trudnych do wykrycia b\u0142\u0119d\u00f3w. Dlatego istotne jest zachowanie ostro\u017cno\u015bci i odpowiedniej dba\u0142o\u015bci o szczeg\u00f3\u0142y przy implementacji takich rozwi\u0105za\u0144.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>VerifyElementsInCart(cardTitles: string[], columnName: string)<\/strong><\/h3>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image12.png\"><img decoding=\"async\" width=\"1024\" height=\"413\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image12-1024x413.png\" alt=\"kod\" class=\"wp-image-29862\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image12-1024x413.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image12-300x121.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image12-768x310.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image12-1536x619.png 1536w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image12-2048x826.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Tak naprawd\u0119 nie wiemy, co dok\u0142adnie sprawdza ta metoda, a dodatkowo istnieje ryzyko, \u017ce w przysz\u0142o\u015bci kto\u015b zmieni jej implementacj\u0119, przez co przestanie ona weryfikowa\u0107 to, co pierwotnie zak\u0142adali\u015bmy. Oczywi\u015bcie zmiana nazwy metody mo\u017ce u\u0142atwi\u0107 zrozumienie kontekstu tego, co oznacza \u201eVerify\u201d. Z drugiej strony \u2013 dla wielu os\u00f3b jest jasne, \u017ce ta metoda sprawdza po prostu, czy \u201eCards\u201d znajduj\u0105 si\u0119 w okre\u015blonej kolumnie.<\/p>\n\n\n\n<p>Warto jednak by\u0107 precyzyjnym, aby unikn\u0105\u0107 potencjalnych problem\u00f3w. Je\u015bli dok\u0142adnie wiemy, co dana metoda powinna robi\u0107, mo\u017cemy umie\u015bci\u0107 w niej w\u0142a\u015bciwe asercje sprawdzaj\u0105ce zawarto\u015b\u0107 koszyka. Alternatywnie \u2013 mo\u017cna zastosowa\u0107 podej\u015bcie, w kt\u00f3rym metoda zwraca okre\u015blony stan, a asercje dokonywane s\u0105 dopiero w samym te\u015bcie. Dzi\u0119ki temu kod testowy pozostaje czytelny, a logika sprawdzania jasna i scentralizowana.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image13.png\"><img decoding=\"async\" width=\"1024\" height=\"120\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image13-1024x120.png\" alt=\"kod\" class=\"wp-image-29864\" style=\"object-fit:cover\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image13-1024x120.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image13-300x35.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image13-768x90.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image13-1536x180.png 1536w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image13-2048x240.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Bazuj\u0105c na tym podej\u015bciu, mamy odseparowany element sprawdzenia okre\u015blonej rzeczy\/stanu\/elementu z page objectem.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Soft Assertions<\/strong><\/h3>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image14.png\"><img decoding=\"async\" width=\"1024\" height=\"71\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image14-1024x71.png\" alt=\"kod\" class=\"wp-image-29866\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image14-1024x71.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image14-300x21.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image14-768x53.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image14-1536x106.png 1536w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/image14.png 1906w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Jest to r\u00f3wnie\u017c interesuj\u0105cy spos\u00f3b na wprowadzenie asercji do kodu w taki spos\u00f3b, by sprawdzenie by\u0142o wykonywane podczas testu, ale jednocze\u015bnie nie powodowa\u0142o jego natychmiastowego zako\u0144czenia b\u0142\u0119dem.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Podsumowanie<\/strong><\/h2>\n\n\n\n<p>W tej cz\u0119\u015bci artyku\u0142u przedstawi\u0142em kilka kluczowych aspekt\u00f3w tworzenia frameworka do test\u00f3w UI i API w Playwright.<\/p>\n\n\n\n<p>Ze wzgl\u0119du na szeroki zakres tematu skupi\u0142em si\u0119 na om\u00f3wieniu: wybranych wzorc\u00f3w projektowych, znaczenia wsp\u00f3\u0142bie\u017cno\u015bci oraz podej\u015bcia do asercji. Przedstawi\u0142em r\u00f3\u017cne strategie i rozwi\u0105zania, a tak\u017ce wyja\u015bni\u0142em, dlaczego wsp\u00f3\u0142bie\u017cno\u015b\u0107 jest kluczowym czynnikiem umo\u017cliwiaj\u0105cym szybkie uzyskanie informacji zwrotnej z test\u00f3w w obecnych, wymagaj\u0105cych realiach.<\/p>\n\n\n\n<p>W kolejnych cz\u0119\u015bciach rozwin\u0119 temat danych testowych oraz poka\u017c\u0119, jak wygl\u0105da pe\u0142ny test w praktyce.<\/p>\n\n\n\n<p>***<\/p>\n\n\n\n<p>Je\u015bli interesuje Ci\u0119 tematyka Playwrighta, zajrzyj koniecznie r\u00f3wnie\u017c <a href=\"https:\/\/sii.pl\/blog\/all\/playwright\/\" target=\"_blank\" aria-label=\"do innych artyku\u0142\u00f3w naszych ekspert\u00f3w (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\">do innych artyku\u0142\u00f3w naszych ekspert\u00f3w<\/a>. <\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;29833&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;17&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;5&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;11&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;5\\\/5 ( votes: 17)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;Playwright w praktyce: 5 krok\u00f3w do skutecznego frameworka do automatyzacji test\u00f3w UI \\u0026amp; Web. Cz\u0119\u015b\u0107 I&quot;,&quot;width&quot;:&quot;139.5&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} ( {votes}: {count})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 139.5px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 14.4px;\">\n            5\/5 ( votes: 17)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>Tym artyku\u0142em chcia\u0142bym rozpocz\u0105\u0107 seri\u0119 wpis\u00f3w, w kt\u00f3rej poka\u017c\u0119, jak krok po kroku zbudowa\u0107 nowoczesny framework do automatyzacji test\u00f3w, korzystaj\u0105c &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.pl\/blog\/playwright-w-praktyce-5-krokow-do-skutecznego-frameworka-do-automatyzacji-testow-ui-web-czesc-i\/\">Continued<\/a><\/p>\n","protected":false},"author":215,"featured_media":29868,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1317],"tags":[1579,1546,1512,276,146,333],"class_list":["post-29833","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-testowanie","tag-playwright","tag-przeglad-narzedzi","tag-poradnik","tag-framework","tag-testing","tag-typescript"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/Playwright-w-praktyce-5-krokow-do-skutecznego-frameworka-do-automatyzacji-testow-UI-Web-Czesc-I.jpg","category_names":["Testowanie"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/29833"}],"collection":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/users\/215"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/comments?post=29833"}],"version-history":[{"count":2,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/29833\/revisions"}],"predecessor-version":[{"id":29872,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/29833\/revisions\/29872"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media\/29868"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media?parent=29833"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/categories?post=29833"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/tags?post=29833"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}