{"id":17354,"date":"2022-12-09T05:00:00","date_gmt":"2022-12-09T04:00:00","guid":{"rendered":"https:\/\/sii.pl\/blog\/?p=17354"},"modified":"2023-09-27T13:31:05","modified_gmt":"2023-09-27T11:31:05","slug":"playwright-dlaczego-warto-zainteresowac-sie-narzedziem-od-microsoftu","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/playwright-dlaczego-warto-zainteresowac-sie-narzedziem-od-microsoftu\/","title":{"rendered":"Playwright \u2013 dlaczego warto zainteresowa\u0107 si\u0119 narz\u0119dziem od Microsoftu?"},"content":{"rendered":"\n<p>Od jakiego\u015b czasu korzystam z jednego z najlepiej rozwijaj\u0105cych si\u0119 narz\u0119dzi do automatyzacji test\u00f3w UI (ale nie tylko), kt\u00f3rym jest Playwright. W tym artykule chc\u0119 Ci zaprezentowa\u0107, jak zacz\u0105\u0107 i dlaczego warto korzysta\u0107 z tego narz\u0119dzia oraz jak wygl\u0105daj\u0105 testy automatyczne w Playwright w praktyce.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Pocz\u0105tki Playwrighta<\/strong><\/h2>\n\n\n\n<p>Microsoft opublikowa\u0142 Playwrighta w 2020 roku. Jest to narz\u0119dzie open source, stworzone przez Andreya Lushnikova, kt\u00f3ry pracowa\u0142 wcze\u015bniej przy innym popularnym produkcie do automatyzacji, jakim jest, rozwijany przez Google, Puupeteer. Playwright s\u0142u\u017cy do automatyzacji akcji w przegl\u0105darce, ale r\u00f3wnie\u017c umo\u017cliwia automatyzacj\u0119 API.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Mocne strony Playwrighta<\/strong><\/h2>\n\n\n\n<p>Narz\u0119dzie posiada szereg interesuj\u0105cych zalet, kt\u00f3re sprawiaj\u0105, \u017ce warto si\u0119 nim zainteresowa\u0107. Opisz\u0119 je poni\u017cej.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Auto Wait<\/strong><\/h3>\n\n\n\n<p>Je\u017celi pracowali\u015bcie kiedy\u015b nad testami automatycznym UI, to zdajecie sobie spraw\u0119, jak du\u017cym problemem jest obs\u0142uga czekania na r\u00f3\u017cne elementy dynamiczne, kt\u00f3re znajduj\u0105 si\u0119 na stronie. W Selenium WebDriver poleca si\u0119 korzysta\u0107 z tzw. Explicit waitu, kt\u00f3ry powinien rozwi\u0105zywa\u0107 ten problem. Jednak czasami znalezienie odpowiedniego waitu nie jest takie proste. Ma na to wp\u0142yw, jak wiele javascriptu i operacji asynchronicznych jest u\u017cywanych na naszej stronie.<\/p>\n\n\n\n<p>Playwright korzysta z tzw. mechanizmu auto-wait. Co to oznacza? W wielu sytuacjach nie musimy dok\u0142ada\u0107 dodatkowego czekania na elementy, bo Playwright sam domy\u015blnie oczekuje element\u00f3w i akcji. Oczywi\u015bcie, gdy natrafimy na bardziej z\u0142o\u017con\u0105 sytuacj\u0119, w kt\u00f3rej potrzebujemy poczeka\u0107 na jaki\u015b element, to Playwright dostarcza nam metody, z kt\u00f3rych mo\u017cemy skorzysta\u0107.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Korzystanie z r\u00f3\u017cnych j\u0119zyk\u00f3w programowania<\/strong><\/h3>\n\n\n\n<p>Obecnie Playwright wspiera kilka popularnych j\u0119zyk\u00f3w programowania. S\u0105 to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Java,<\/li>\n\n\n\n<li>C#,<\/li>\n\n\n\n<li>JS\/TS,<\/li>\n\n\n\n<li>Python.<\/li>\n<\/ul>\n\n\n\n<p>Dzi\u0119ki temu, rozwi\u0105zanie w wersji dla r\u00f3\u017cnych j\u0119zyk\u00f3w znajduje coraz szersze zastosowanie na rynku.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Dokumentacja<\/strong><\/h3>\n\n\n\n<p>Playwright ma \u015bwietn\u0105 dokumentacj\u0119. Korzystanie z metod jest opisane na praktycznych przyk\u0142adach, kt\u00f3re pomagaj\u0105 skorzysta\u0107 z wielu mo\u017cliwo\u015bci aplikacji. R\u00f3wnie\u017c dokumentacja, kt\u00f3ra pojawia si\u0119, gdy wywo\u0142ujemy jak\u0105\u015b metod\u0119 w IDE, jest cz\u0119sto wystarczaj\u0105ca do tego, aby j\u0105 realnie wykorzysta\u0107.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Popularno\u015b\u0107 narz\u0119dzia<\/strong><\/h3>\n\n\n\n<p>Warto zauwa\u017cy\u0107, \u017ce liczba u\u017cytkownik\u00f3w narz\u0119dzia Playwright ro\u015bnie, co mo\u017cna zobaczy\u0107 na poni\u017cszej grafice.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-1.png\"><img decoding=\"async\" width=\"1024\" height=\"535\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-1-1024x535.png\" alt=\"Ranking u\u017cytkowania r\u00f3\u017cnych framework\u00f3w pod k\u0105tem wielko\u015bci grupy odbiorc\u00f3w \" class=\"wp-image-17355\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-1-1024x535.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-1-300x157.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-1-768x401.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-1.png 1445w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 1 <a href=\"https:\/\/2021.stateofjs.com\/en-US\/libraries\/testing\" rel=\"nofollow\" >Ranking u\u017cytkowania r\u00f3\u017cnych framework\u00f3w pod k\u0105tem wielko\u015bci grupy odbiorc\u00f3w<\/a><\/figcaption><\/figure>\n\n\n\n<p>Playwright, spo\u015br\u00f3d bibliotek u\u017cywanych w testach, poprawi\u0142 wynik wykorzystania w\u015br\u00f3d spo\u0142eczno\u015bci z 3% w 2020 roku do 10% w 2021 roku. Ten ranking odno\u015bni si\u0119 do wersji JS\/TS Playwrighta, jednak moim zdaniem jest to zauwa\u017calny skok popularno\u015bci, kt\u00f3ry b\u0119dzie prawdopodobnie r\u00f3wnie\u017c odnotowany przy innych wersjach j\u0119zykowych narz\u0119dzia.<\/p>\n\n\n\n<p>Poprawi\u0142a si\u0119 r\u00f3wnie\u017c \u015bwiadomo\u015b\u0107 na temat Playwrighta w\u015br\u00f3d spo\u0142eczno\u015bci \u2013 z 19% w 2020 roku do 34% rok p\u00f3\u017aniej.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-2.png\"><img decoding=\"async\" width=\"1024\" height=\"533\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-2-1024x533.png\" alt=\"Ranking dot. \u015bwiadomo\u015bci istnienia narz\u0119dzi\" class=\"wp-image-17357\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-2-1024x533.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-2-300x156.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-2-768x399.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-2.png 1421w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 2 <a href=\"https:\/\/2021.stateofjs.com\/en-US\/libraries\/testing\" rel=\"nofollow\" >Ranking dot. \u015bwiadomo\u015bci istnienia narz\u0119dzi<\/a><\/figcaption><\/figure>\n\n\n\n<p>Przy wyborze narz\u0119dzi warto zwraca\u0107 uwag\u0119 na ich popularno\u015b\u0107 oraz pozytywny odbi\u00f3r przez spo\u0142eczno\u015b\u0107. Playwright posiada oba aspekty.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Cz\u0119stotliwo\u015b\u0107 dostarczania nowych wersji<\/strong><\/h3>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-3.png\"><img decoding=\"async\" width=\"1024\" height=\"721\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-3-1024x721.png\" alt=\"Playwright \u2013 cz\u0119stotliwo\u015b\u0107 dostarczania nowych wersji\" class=\"wp-image-17359\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-3-1024x721.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-3-300x211.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-3-768x541.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-3.png 1273w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 3 Playwright \u2013 cz\u0119stotliwo\u015b\u0107 dostarczania nowych wersji<\/figcaption><\/figure>\n\n\n\n<p>Niew\u0105tpliwie warto wspomnie\u0107 o szybkim rozwoju Playwrighta. Co oko\u0142o dwa tygodnie dodawana jest nowa wersja z usprawnieniami (cz\u0119stotliwo\u015b\u0107 zmian mo\u017cna sprawdzi\u0107 na GitHubie).<\/p>\n\n\n\n<p>Przy wyborze potencjalnego narz\u0119dzia zawsze zwracam uwag\u0119 na rozmiar spo\u0142eczno\u015bci, kt\u00f3ra za nim stoi. W tym wypadku jest to Microsoft i jego pracownicy, ale r\u00f3wnie\u017c coraz wi\u0119cej zaanga\u017cowanych os\u00f3b spoza firmy.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Przegl\u0105darki wspierane przez Playwrighta<\/strong><\/h3>\n\n\n\n<p>Obecnie Playwright wspiera wszystkie najpopularniejsze przegl\u0105darki internetowe, czyli:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Chrome,<\/li>\n\n\n\n<li>Edge,<\/li>\n\n\n\n<li>Firefox,<\/li>\n\n\n\n<li>Opera,<\/li>\n\n\n\n<li>Safari.<\/li>\n<\/ul>\n\n\n\n<p>Rozwi\u0105zania oparte na Electronie r\u00f3wnie\u017c maj\u0105 eksperymentalne wsparcie dla wersji JS\/TS.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Projekty wykorzystuj\u0105ce Playwrighta<\/strong><\/h3>\n\n\n\n<p>Coraz wi\u0119cej projekt\u00f3w chwali si\u0119, \u017ce korzysta z narz\u0119dzia Playwright w swoich testach UI. S\u0105 to popularne inicjatywy open source, ale r\u00f3wnie\u017c rozwi\u0105zania komercyjne. Poni\u017cej kilka przyk\u0142ad\u00f3w:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-4.png\"><img decoding=\"async\" width=\"1024\" height=\"274\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-4-1024x274.png\" alt=\"Przyk\u0142ad projektu wykorzystuj\u0105cego Playwright \" class=\"wp-image-17361\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-4-1024x274.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-4-300x80.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-4-768x205.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-4.png 1301w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 4 <a href=\"https:\/\/github.com\/adobe\/spectrum-web-components\" rel=\"nofollow\" >Przyk\u0142ad projektu wykorzystuj\u0105cego Playwright<\/a><\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-6.png\"><img decoding=\"async\" width=\"1024\" height=\"328\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-6-1024x328.png\" alt=\"Przyk\u0142ad projektu wykorzystuj\u0105cego Playrwight \" class=\"wp-image-17363\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-6-1024x328.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-6-300x96.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-6-768x246.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-6.png 1097w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 5 <a href=\"https:\/\/github.com\/mui\/material-ui\" rel=\"nofollow\" >Przyk\u0142ad projektu wykorzystuj\u0105cego Playrwight<\/a><\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>S\u0142abe strony Playwrighta<\/strong><\/h2>\n\n\n\n<p>W przypadku wszystkich narz\u0119dzi zdarzaj\u0105 si\u0119 momenty, gdy jaka\u015b metoda nie dzia\u0142a poprawnie w okre\u015blonej sytuacji. Jako u\u017cytkownik Playwrighta spotka\u0142em si\u0119 z problemami sporadycznie i zawsze udawa\u0142o mi si\u0119 znale\u017a\u0107 rozwi\u0105zanie. Nie mog\u0119 natomiast wykluczy\u0107, \u017ce mo\u017cemy trafi\u0107 na okoliczno\u015bci, w kt\u00f3rych rozwi\u0105zania nie znajdziemy. Warto w\u00f3wczas porozmawia\u0107 z tw\u00f3rcami narz\u0119dzia \u2013 s\u0105 oni dost\u0119pni i aktywnie bior\u0105 udzia\u0142 w odpisywaniu na zg\u0142oszenia, kt\u00f3re trafiaj\u0105 na GitHuba.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Napiszmy pierwszy test!<\/strong><\/h2>\n\n\n\n<p>Po kr\u00f3tkim, teoretycznym wprowadzeniu mo\u017cemy przej\u015b\u0107 do napisania naszego pierwszego testu automatycznego w tej aplikacji.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Implementacja testu automatycznego<\/strong><\/h3>\n\n\n\n<p>Przygotowany przeze mnie test b\u0119dzie polega\u0142 na zautomatyzowaniu prostego przypadku dla testowo stworzonego sklepu. Scenariusz testu wygl\u0105da tak:<\/p>\n\n\n\n<ol class=\"wp-block-list\" type=\"1\">\n<li>Przejd\u017a na stron\u0119 seleniumsklep.pl<\/li>\n\n\n\n<li>Kliknij w wybrany produkt na podstawie jego nazwy.<\/li>\n\n\n\n<li>Przejd\u017a do koszyka i sprawd\u017a, czy cena na podsumowaniu jest zgodna z cen\u0105, kt\u00f3ra znajduje si\u0119 w szczeg\u00f3\u0142ach produktu.<\/li>\n<\/ol>\n\n\n\n<p>Przechodzimy do Visual Studio i rozpoczynamy prac\u0119 od utworzenia projektu <em>package library<\/em>. Jest to preferowany typ projektu, kt\u00f3ry zastosujemy. Kolejnym krokiem b\u0119dzie dodanie potrzebnych paczek za pomoc\u0105 NuGet packages. W naszym przypadku:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Playwright,<\/li>\n\n\n\n<li>Playwright Nunit.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-7.png\"><img decoding=\"async\" width=\"672\" height=\"461\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-7.png\" alt=\"Dodawanie potrzebnych paczek\" class=\"wp-image-17366\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-7.png 672w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-7-300x206.png 300w\" sizes=\"(max-width: 672px) 100vw, 672px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 6 Dodawanie potrzebnych paczek<\/figcaption><\/figure>\n\n\n\n<p>Playwright Nunit zawiera przydatne klasy, kt\u00f3re pomagaj\u0105 wsp\u00f3\u0142pracowa\u0107 narz\u0119dziom np. w kontek\u015bcie uruchamiania test\u00f3w w spos\u00f3b wsp\u00f3\u0142bie\u017cny.<\/p>\n\n\n\n<p>Kolejnym krokiem jest stworzenie potrzebnych katalog\u00f3w tak, aby od samego pocz\u0105tku porz\u0105dkowa\u0107 nasze rozwi\u0105zanie.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-8.png\"><img decoding=\"async\" width=\"318\" height=\"152\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-8.png\" alt=\"Tworzenie katalog\u00f3w\" class=\"wp-image-17368\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-8.png 318w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-8-300x143.png 300w\" sizes=\"(max-width: 318px) 100vw, 318px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 7 Tworzenie katalog\u00f3w<\/figcaption><\/figure>\n\n\n\n<p>Najpierw tworzymy katalog \u201ePages\u201d, w kt\u00f3rym umie\u015bcimy wszystkie page objecty potrzebne nam do testu automatycznego. Kolejnym niezb\u0119dnym katalogiem jest \u201eTests\u201d.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-9.png\"><img decoding=\"async\" width=\"1024\" height=\"614\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-9-1024x614.png\" alt=\"fragment kodu\" class=\"wp-image-17370\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-9-1024x614.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-9-300x180.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-9-768x461.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-9.png 1229w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>W klasie BaseSetup mamy dwie metody, kt\u00f3rych u\u017cyjemy we wszystkich testach dziedzicz\u0105cych z tej klasy. Metoda \u201eSetup()\u201d na pocz\u0105tku inicjalizuje obiekt Playwrighta. Robimy to w linii 17. Przed ni\u0105 deklarujemy trzy pola, kt\u00f3re b\u0119d\u0105 nam potrzebne w dalszej pracy.<\/p>\n\n\n\n<p>S\u0105 to pola:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Playwright,<\/li>\n\n\n\n<li>Browser,<\/li>\n\n\n\n<li>Context.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-10.png\"><img decoding=\"async\" width=\"315\" height=\"65\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-10.png\" alt=\"fragment kodu\" class=\"wp-image-17373\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-10.png 315w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-10-300x62.png 300w\" sizes=\"(max-width: 315px) 100vw, 315px\" \/><\/a><\/figure>\n\n\n\n<p>W metodzie Setup() inicjalizujemy pole Browser, kt\u00f3re definiujemy, aby ustawi\u0107 jakiej przegl\u0105darki b\u0119dziemy u\u017cywa\u0107 w testach. Je\u017celi nie podamy parametru Headless, nie zobaczymy przebiegu test\u00f3w, poniewa\u017c uruchomi\u0105 si\u0119 bez trybu graficznego. Jest to przydatna opcja, dzi\u0119ki kt\u00f3rej unikamy wyskakuj\u0105cych okiem z testami.&nbsp;<\/p>\n\n\n\n<p>Kolejn\u0105 rzecz\u0105, kt\u00f3r\u0105 mo\u017cemy ustawi\u0107 w tym miejscu jest Channel. Playwright pozwala nam zdecydowa\u0107, jak\u0105 wersj\u0119 Chrome u\u017cy\u0107 w naszym te\u015bcie automatycznym. W bardzo prosty spos\u00f3b mo\u017cemy zdefiniowa\u0107, \u017ce chcemy skorzysta\u0107 np. z Chrome czy z Edge\u2019a w wersji beta. Mo\u017ce by\u0107 to bardzo przydatne do sprawdzenia dzia\u0142ania naszej aplikacji z nadchodz\u0105cymi wersjami przegl\u0105darek.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-11.png\"><img decoding=\"async\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-11.png\" alt=\"fragment kodu\" class=\"wp-image-17375\" width=\"639\" height=\"98\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-11.png 639w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-11-300x46.png 300w\" sizes=\"(max-width: 639px) 100vw, 639px\" \/><\/a><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-12.png\"><img decoding=\"async\" width=\"709\" height=\"97\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-12.png\" alt=\"fragment kodu\" class=\"wp-image-17377\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-12.png 709w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-12-300x41.png 300w\" sizes=\"(max-width: 709px) 100vw, 709px\" \/><\/a><\/figure>\n\n\n\n<p>Nast\u0119pnie przechodzimy do zdefiniowania Contextu. Czym jest Context? Inicjalizujemy pole Context, kt\u00f3re pozwala obs\u0142ugiwa\u0107 sesj\u0119 danej przegl\u0105darki. Wyr\u00f3\u017cnikiem Playwrighta jest to, \u017ce potrafi obs\u0142ugiwa\u0107 wi\u0119cej ni\u017c jedn\u0105 sesj\u0119 przegl\u0105darki na raz. Dodatkowo ka\u017cde z okien ma \u201eFocus\u201d, wi\u0119c nie musimy si\u0119 prze\u0142\u0105cza\u0107 pomi\u0119dzy nimi, je\u017celi chcemy wykona\u0107 jak\u0105\u015b akcj\u0119.<\/p>\n\n\n\n<p>R\u00f3wnie\u017c w obiekcie Browser mogliby\u015bmy od razu skorzysta\u0107 z metody NewContextAsync(), jednak tw\u00f3rcy Playwrighta polecaj\u0105, \u017ceby tworzy\u0107 kontekst za ka\u017cdym razem. Ka\u017cdy \u201eContext\u201d przechowuje oddzielny cache i ciasteczka.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-13.png\"><img decoding=\"async\" width=\"753\" height=\"204\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-13.png\" alt=\"fragment kodu\" class=\"wp-image-17379\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-13.png 753w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-13-300x81.png 300w\" sizes=\"(max-width: 753px) 100vw, 753px\" \/><\/a><\/figure>\n\n\n\n<p>Kolejnym krokiem jest zdefiniowanie tzw. Tracingu. Ta metoda pozwala na zbieranie log\u00f3w podczas dzia\u0142ania testu automatycznego. \u015aledzi\u0107 mo\u017cemy:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Screenshots \u2013 tworzenie zrzutu ekranu po ka\u017cdej akcji,<\/li>\n\n\n\n<li>Snapshots \u2013 zbieranie zawarto\u015bci DOM-u po ka\u017cdej akcji oraz zbieranie informacji z \u201enetworku\u201d, czyli wszystkie \u017c\u0105dania i informacje z konsoli,<\/li>\n\n\n\n<li>Sources \u2013 zbieranie informacje na temat tego, kt\u00f3ra linia kodu by\u0142a uruchomiona w danym momencie.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Kod \u017ar\u00f3d\u0142owy testu automatycznego<\/strong><\/h2>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-14.png\"><img decoding=\"async\" width=\"836\" height=\"466\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-14.png\" alt=\"fragment kodu\" class=\"wp-image-17381\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-14.png 836w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-14-300x167.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-14-768x428.png 768w\" sizes=\"(max-width: 836px) 100vw, 836px\" \/><\/a><\/figure>\n\n\n\n<p>Przechodz\u0105c do kodu \u017ar\u00f3d\u0142owego testu automatycznego, zaczynamy od zdefiniowania nazwy metody. W tym przypadku jest to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>EnterToShop_AddProductToBasket_CheckProductPriceInSummary()<\/code><\/pre>\n\n\n\n<p>Jako parametr definiujemy \u201eoption\u201d, dzi\u0119ki kt\u00f3remu w spos\u00f3b dynamiczny mo\u017cemy przekaza\u0107 nazw\u0119 artyku\u0142u, wybieranego przez test. Odpowiada na niego atrybut \u201eTestCase\u201d. Ka\u017cda kolejna linia w postaci atrybutu TestCase z argumentem, definiuje nam kolejny przypadek testowy.<\/p>\n\n\n\n<p>Zaczynamy od zdefiniowania obiektu page. Odpowiada on za kontrol\u0119 pojedynczej zak\u0142adki w przegl\u0105darce (oczywi\u015bcie skojarzonej z naszym kontekstem).<\/p>\n\n\n\n<p>HomePage<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-15.png\"><img decoding=\"async\" width=\"965\" height=\"543\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-15.png\" alt=\"fragment kodu\" class=\"wp-image-17384\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-15.png 965w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-15-300x169.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-15-768x432.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-15-555x312.png 555w\" sizes=\"(max-width: 965px) 100vw, 965px\" \/><\/a><\/figure>\n\n\n\n<p>Definiujemy page object dla strony HomePage. Sama strona posiada list\u0119 interesuj\u0105cych nas produkt\u00f3w.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-16.png\"><img decoding=\"async\" width=\"1024\" height=\"524\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-16-1024x524.png\" alt=\"Strona z interesuj\u0105cymi nas produktami\" class=\"wp-image-17387\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-16-1024x524.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-16-300x154.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-16-768x393.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-16-1536x786.png 1536w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-16.png 1571w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 6 Strona z interesuj\u0105cymi nas produktami<\/figcaption><\/figure>\n\n\n\n<p>Nast\u0119pnie tworzymy konstruktora dla tej klasy. Konstruktor b\u0119dzie przyjmowa\u0142 parametr jako obiekt page, kt\u00f3ry zawiera metody pozwalaj\u0105ce kontrolowa\u0107 akcje zwi\u0105zane z t\u0105 stron\u0105. Kolejnym krokiem jest zdefiniowanie pola ProductTitles z selektorem odpowiadaj\u0105cym nazwie ka\u017cdego z produkt\u00f3w.<\/p>\n\n\n\n<p>Potrzebujemy r\u00f3wnie\u017c metody SelectDefineProduct, kt\u00f3ra odpowiada za klikni\u0119cie w dany produkt na podstawie jego nazwy. &nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-17.png\"><img decoding=\"async\" width=\"910\" height=\"298\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-17.png\" alt=\"fragment kodu\" class=\"wp-image-17390\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-17.png 910w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-17-300x98.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-17-768x251.png 768w\" sizes=\"(max-width: 910px) 100vw, 910px\" \/><\/a><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"984\" height=\"137\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-18.png\" alt=\"fragment kodu\" class=\"wp-image-17392\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-18.png 984w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-18-300x42.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-18-768x107.png 768w\" sizes=\"(max-width: 984px) 100vw, 984px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Metoda QuerySelectorAllAsync \u2013 pozwala nam na pobranie wszystkich element\u00f3w na podstawie zadanego selectora.<\/li>\n\n\n\n<li>Metoday InnerText \u2013 umo\u017cliwia pobranie tekstu z danego elementu.<\/li>\n\n\n\n<li>Metoda ClickAsync \u2013 klika w element, kt\u00f3ry chcemy wybra\u0107.<\/li>\n<\/ul>\n\n\n\n<p>Ciekaw\u0105 w\u0142a\u015bciwo\u015bci\u0105 Playwrighta jest to, \u017ce wi\u0119kszo\u015b\u0107 wykorzystywanych metod, posiada dodatkowe sposoby u\u017cycia, kt\u00f3re poszerzaj\u0105 jego mo\u017cliwo\u015bci.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-19.png\"><img decoding=\"async\" width=\"1024\" height=\"183\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-19-1024x183.png\" alt=\"fragment kodu\" class=\"wp-image-17394\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-19-1024x183.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-19-300x54.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-19-768x137.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-19.png 1219w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Jedn\u0105 z nich jest metoda ClickAsync. Pozwala nam zdefiniowa\u0107, ile razy chcemy klikn\u0105\u0107 lub okre\u015bli\u0107 czekanie po klikni\u0119ciu.<\/p>\n\n\n\n<p>Metod, kt\u00f3rych mo\u017cemy u\u017cy\u0107 na danym obiekcie jest wiele. Oto kilka z nich:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-20.png\"><img decoding=\"async\" width=\"566\" height=\"302\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-20.png\" alt=\"Wybrane metody - lista\" class=\"wp-image-17396\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-20.png 566w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-20-300x160.png 300w\" sizes=\"(max-width: 566px) 100vw, 566px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 7 Dost\u0119pny wyb\u00f3r metod<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Waity<\/strong><\/h3>\n\n\n\n<p>Tak jak wspomina\u0142em dla wi\u0119kszo\u015bci operacji nie mamy potrzeby dodawania dodatkowych wait\u00f3w. Jednak, mo\u017cemy skorzysta\u0107 z tych metod, gdy nasza strona jest bardziej skomplikowana i zale\u017cy nam na dodaniu czekania na element.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-21.png\"><img decoding=\"async\" width=\"617\" height=\"306\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-21.png\" alt=\"Metody czekania na element\" class=\"wp-image-17398\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-21.png 617w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-21-300x149.png 300w\" sizes=\"(max-width: 617px) 100vw, 617px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 8 Metody czekania na element<\/figcaption><\/figure>\n\n\n\n<p>Mo\u017cemy poczeka\u0107, a\u017c pop-up&nbsp;lub okre\u015blone \u017c\u0105danie si\u0119 pojawi\u0105. Ta metoda jest przydatna, gdy przechodzimy pomi\u0119dzy stronami i potrzebujemy poczeka\u0107 d\u0142u\u017cej na za\u0142adowanie strony.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-22.png\"><img decoding=\"async\" width=\"1024\" height=\"508\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-22-1024x508.png\" alt=\"fragment kodu\" class=\"wp-image-17401\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-22-1024x508.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-22-300x149.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-22-768x381.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-22.png 1065w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-23.png\"><img decoding=\"async\" width=\"1024\" height=\"288\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-23-1024x288.png\" alt=\"fragment kodu\" class=\"wp-image-17403\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-23-1024x288.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-23-300x84.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-23-768x216.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-23.png 1097w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Wracaj\u0105c do test\u00f3w: nast\u0119pny krokiem w linii 18 jest skorzystanie z metody GoToAsync(), kt\u00f3ra przejdzie do okre\u015blonej strony internetowej. Adres do strony zapisujemy w osobnej klasie TestSettings.EnvUrl. Takie warto\u015bci jak adres do \u015brodowiska najlepiej przechowywa\u0107 w osobnych klasach\/plikach. Metoda GoToAsync ma r\u00f3wnie\u017c mo\u017cliwo\u015b\u0107 dodania dodatkowego czekania na za\u0142adowanie strony. Adres strony zapisujemy we w\u0142a\u015bciwo\u015bciach w klasie TestSettings.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-24.png\"><img decoding=\"async\" width=\"761\" height=\"190\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-24.png\" alt=\"fragment kodu\" class=\"wp-image-17405\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-24.png 761w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-24-300x75.png 300w\" sizes=\"(max-width: 761px) 100vw, 761px\" \/><\/a><\/figure>\n\n\n\n<p>Po tym kroku, w te\u015bcie przechodzimy do wywo\u0142ania metody SelectDefineProduct(option). To ona kliknie w okre\u015blony produkt. Kolejnym dzia\u0142aniem jest dodanie klasy DetailsProductPage, w kt\u00f3rej zaczynam od stworzenia p\u00f3l potrzebnych do metod u\u017cywanych na dalszych etapach tego testu.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-25.png\"><img decoding=\"async\" width=\"624\" height=\"319\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-25.png\" alt=\"Pole AddToBasketBtn odpowiada przyciskowi na stronie.\" class=\"wp-image-17407\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-25.png 624w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-25-300x153.png 300w\" sizes=\"(max-width: 624px) 100vw, 624px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 9 Pole AddToBasketBtn odpowiada przyciskowi na stronie<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-26.png\"><img decoding=\"async\" width=\"864\" height=\"266\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-26.png\" alt=\"Pole ProceedToCheckoutBtn odpowiada przyciskowi na stronie\" class=\"wp-image-17409\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-26.png 864w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-26-300x92.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-26-768x236.png 768w\" sizes=\"(max-width: 864px) 100vw, 864px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 10 Pole ProceedToCheckoutBtn odpowiada przyciskowi na stronie<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-27.png\"><img decoding=\"async\" width=\"247\" height=\"59\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-27.png\" alt=\"Pole CurrentPrice odpowiada obecnej cenie produktu, kt\u00f3ra znajduje si\u0119 na stronie szczeg\u00f3\u0142\u00f3w produktu\" class=\"wp-image-17411\"\/><\/a><figcaption class=\"wp-element-caption\">Ryc. 11 Pole CurrentPrice odpowiada obecnej cenie produktu, kt\u00f3ra znajduje si\u0119 na stronie szczeg\u00f3\u0142\u00f3w produktu<\/figcaption><\/figure>\n\n\n\n<p>Nast\u0119pnie, dodajemy konstruktor, kt\u00f3ry przez argument b\u0119dzie przyjmowa\u0142 obiekt page, pozwalaj\u0105cy na wykonywanie akcji zwi\u0105zanych ze stron\u0105.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-28.png\"><img decoding=\"async\" width=\"963\" height=\"543\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-28.png\" alt=\"fragment kodu\" class=\"wp-image-17414\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-28.png 963w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-28-300x169.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-28-768x433.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-28-555x312.png 555w\" sizes=\"(max-width: 963px) 100vw, 963px\" \/><\/a><\/figure>\n\n\n\n<p>Definiujemy pole AddToBasektBtn. Aby doda\u0107 element w Playwright, korzystamy z metody _page.Locator(\u201enazwa_selectora\u201d), kt\u00f3ra na podstawie podanego selectora pozwala uzyska\u0107 dost\u0119p do elementu za pomoc\u0105 Playwrighta. Kolejnym elementem, kt\u00f3ry definiujemy w tej klasie, jest odpowiednik przycisku \u201eProceed to Checkout\u201d.<\/p>\n\n\n\n<p>By test zadzia\u0142a\u0142, kolejne wymagane pole to \u201eCurrentPrice\u201d. Pozwala ono na pobranie aktualnej ceny za nasz przedmiot.<\/p>\n\n\n\n<p>Po zdefiniowaniu wszystkich p\u00f3l niezb\u0119dnych dla testu przechodzimy do zdefiniowania dw\u00f3ch prostych metod:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>metoda AddProductToCart() zawiera klikni\u0119cie przycisku dodania do koszyka,<\/li>\n\n\n\n<li>metoda ProceedToCheckout() jest analogiczn\u0105 metod\u0105 do klikni\u0119cia dla przycisku \u201eProceed to checkout\u201d.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-29.png\"><img decoding=\"async\" width=\"682\" height=\"151\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-29.png\" alt=\"fragment kodu\" class=\"wp-image-17416\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-29.png 682w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-29-300x66.png 300w\" sizes=\"(max-width: 682px) 100vw, 682px\" \/><\/a><\/figure>\n\n\n\n<p>Definiuj\u0119 metod\u0119 GetCurrentProductPrice, kt\u00f3ra odpowiada za pobranie obecnej warto\u015bci ceny ze szczeg\u00f3\u0142\u00f3w tego produktu. Potrzebujemy jeszcze doda\u0107 metod\u0119 ParseEuroToDouble. Jest to metoda, kt\u00f3ra stosuje proste tzw. parsowanie, kt\u00f3re w tym przypadku usuwa symbol \u20ac z tekstu. W tym wypadku musimy to zrobi\u0107, poniewa\u017c element jest zdefiniowany w ten spos\u00f3b w HTML-u strony.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-30.png\"><img decoding=\"async\" width=\"521\" height=\"78\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-30.png\" alt=\"fragment kodu\" class=\"wp-image-17418\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-30.png 521w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-30-300x45.png 300w\" sizes=\"(max-width: 521px) 100vw, 521px\" \/><\/a><\/figure>\n\n\n\n<p>Oczywi\u015bcie jest to jedna z dr\u00f3g, ale mo\u017cna podej\u015b\u0107 do tego na wiele sposob\u00f3w. Innym pomys\u0142em jest skorzystanie z wyra\u017cenia regularnego, kt\u00f3re pozwoli\u0142oby na pobranie liczbowej warto\u015bci z&nbsp;tekstu. Metoda ParseEuroToDouble wygl\u0105da tak:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-31.png\"><img decoding=\"async\" width=\"1024\" height=\"201\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-31-1024x201.png\" alt=\"fragment kodu\" class=\"wp-image-17420\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-31-1024x201.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-31-300x59.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-31-768x151.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-31.png 1065w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Wracamy do kodu \u017ar\u00f3d\u0142owego testu. Wywo\u0142ujemy metody, kt\u00f3re pozwol\u0105 doda\u0107 produkt do koszyka.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-32.png\"><img decoding=\"async\" width=\"454\" height=\"46\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-32.png\" alt=\"fragment kodu\" class=\"wp-image-17422\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-32.png 454w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-32-300x30.png 300w\" sizes=\"(max-width: 454px) 100vw, 454px\" \/><\/a><\/figure>\n\n\n\n<p>W kolejnej linii inicjalizujemy obiekt SummaryCartPage. Jest to obiekt reprezentuj\u0105cy klas\u0119 SummaryCartPage.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-33.png\"><img decoding=\"async\" width=\"647\" height=\"274\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-33.png\" alt=\"fragment kodu\" class=\"wp-image-17424\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-33.png 647w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-33-300x127.png 300w\" sizes=\"(max-width: 647px) 100vw, 647px\" \/><\/a><\/figure>\n\n\n\n<p>W tej klasie opr\u00f3cz zdefiniowania konstruktora, dodajemy pole odpowiadaj\u0105ce elementowi kwoty w podsumowaniu koszyka.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-34.png\"><img decoding=\"async\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-34.png\" alt=\"element kwoty\" class=\"wp-image-17426\" width=\"421\" height=\"123\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-34.png 421w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-34-300x88.png 300w\" sizes=\"(max-width: 421px) 100vw, 421px\" \/><\/a><\/figure>\n\n\n\n<p>R\u00f3wnie\u017c w tym miejscu korzystamy z metody ParseEuroToDouble, bo w tej sytuacji jest por\u00f3wnywalna. Po dodaniu tej metody, wracamy do kodu testu i por\u00f3wnujemy warto\u015b\u0107 zmiennej currentTotalPrice z productPrice. To por\u00f3wnanie korzysta z biblioteki FluentAssertions, kt\u00f3r\u0105 dodajemy poprzez NuGeta. Jest to biblioteka do asercji, kt\u00f3ra pozwala na bardziej czytelny zapis ni\u017c standardowe metody z klasy Assert. Dalej, przechodzimy do uruchomienia testu. Mo\u017cemy tego dokona\u0107 za pomoc\u0105 dotnet test z poziomu VS oraz z poziomu VS i R#.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-35.png\"><img decoding=\"async\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-35.png\" alt=\"test\" class=\"wp-image-17428\" width=\"640\" height=\"275\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-35.png 640w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-35-300x129.png 300w\" sizes=\"(max-width: 640px) 100vw, 640px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 12 Uruchamianie testu<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-36-1.png\"><img decoding=\"async\" width=\"870\" height=\"295\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-36-1.png\" alt=\"fragment kodu\" class=\"wp-image-17440\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-36-1.png 870w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-36-1-300x102.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Ryc.-36-1-768x260.png 768w\" sizes=\"(max-width: 870px) 100vw, 870px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Podsumowanie<\/strong><\/h2>\n\n\n\n<p>W artykule pokaza\u0142em Playwrighta w praktyce i przedstawi\u0142em kilka cech, kt\u00f3re mog\u0105 Ci\u0119 zainteresowa\u0107 i przekona\u0107 do spr\u00f3bowania pracy z tym narz\u0119dziem.<\/p>\n\n\n\n<p>W nast\u0119pnej cz\u0119\u015bci chcia\u0142bym zaprezentowa\u0107 jak skorzysta\u0107 z Trace Viewer, przydatnej funkcji, kt\u00f3ra pozwala nam przegl\u0105da\u0107 zebrane logi z test\u00f3w. Przedstawi\u0119 tak\u017ce inne ciekawe w\u0142a\u015bciwo\u015bci tego narz\u0119dzia.<\/p>\n\n\n\n<p><a aria-label=\"Kod znajdziecie w przygotowanym repozytorium (opens in a new tab)\" href=\"https:\/\/github.com\/sii-poland\/PlaywrightCSharp\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >Kod znajdziecie w przygotowanym repozytorium<\/a>.<\/p>\n\n\n\n<p>***<br>Je\u015bli chcesz wiedzie\u0107, dlaczego rozw\u00f3j i nauka nowych j\u0119zyk\u00f3w oprogramowania przydaj\u0105 si\u0119 na stanowisku Test Architecta oraz co Micha\u0142 ceni w pracy, obejrzyj koniecznie jego nagranie:<\/p>\n\n\n\n<figure class=\"wp-block-embed aligncenter is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe title=\"Automatyzacja test\u00f3w oczami Test Architecta #PowerPeopleAtWork\" width=\"500\" height=\"281\" src=\"https:\/\/www.youtube.com\/embed\/2l5uI2sLgqQ?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><\/figure>\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;17354&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;4.9&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;4.9\\\/5 ( votes: 17)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;Playwright \u2013 dlaczego warto zainteresowa\u0107 si\u0119 narz\u0119dziem od Microsoftu?&quot;,&quot;width&quot;:&quot;136.6&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: 136.6px;\">\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            4.9\/5 ( votes: 17)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>Od jakiego\u015b czasu korzystam z jednego z najlepiej rozwijaj\u0105cych si\u0119 narz\u0119dzi do automatyzacji test\u00f3w UI (ale nie tylko), kt\u00f3rym jest &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.pl\/blog\/playwright-dlaczego-warto-zainteresowac-sie-narzedziem-od-microsoftu\/\">Continued<\/a><\/p>\n","protected":false},"author":215,"featured_media":19844,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":9,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1317],"tags":[1579,1554,1546],"class_list":["post-17354","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-testowanie","tag-playwright","tag-zalety-i-wady","tag-przeglad-narzedzi"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/12\/Playwright-\u2013-dlaczego-warto-zainteresowac-sie-narzedziem-od-Microsoftu-1.jpg","category_names":["Testowanie"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/17354"}],"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=17354"}],"version-history":[{"count":2,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/17354\/revisions"}],"predecessor-version":[{"id":24470,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/17354\/revisions\/24470"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media\/19844"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media?parent=17354"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/categories?post=17354"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/tags?post=17354"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}