{"id":28386,"date":"2024-07-18T05:00:00","date_gmt":"2024-07-18T03:00:00","guid":{"rendered":"https:\/\/sii.pl\/blog\/cypress-testy-komponentow\/"},"modified":"2024-07-19T08:31:22","modified_gmt":"2024-07-19T06:31:22","slug":"cypress-component-testing","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/en\/cypress-component-testing\/","title":{"rendered":"Cypress \u2013 component testing"},"content":{"rendered":"\n<p>Component testing is a relatively new concept introduced in Cypress on June 1, 2022, in version 10.0.0. We had previously encountered the implementation of component tests, but at a different level than it is today.<\/p>\n\n\n\n<p>In this article, I will describe component tests, present an example from the past, and discuss the current implementation using Cypress. Additionally, I will discuss the pros and cons of these solutions.<\/p>\n\n\n\n<p>If you are interested in Cypress, I warmly invite you to read my previous article about waits in Cypress: <a href=\"https:\/\/sii.pl\/blog\/testy-automatyczne-cypress-czeka-az-wprowadzenie-do-waitow\/\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\">Testy automatyczne Cypress czeka a\u017c \u2013 wprowadzenie do wait\u00f3w<\/a>, as well as an article by my colleague Micha\u0142, introducing this testing tool: <a href=\"https:\/\/sii.pl\/blog\/cypress-dlaczego-warto-zainteresowac-sie-tym-frameworkiem\/\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\">Cypress \u2013 dlaczego warto zainteresowa\u0107 si\u0119 tym frameworkiem<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>What are component tests?<\/strong><\/h2>\n\n\n\n<p>Component tests in front-end testing involve checking individual components or units of a web application in isolation. The main goal is to ensure that each component works as expected at an early stage of development.<\/p>\n\n\n\n<p>Components are usually smaller, independent user interface parts, such as:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>buttons,<\/li>\n\n\n\n<li>forms,<\/li>\n\n\n\n<li>or custom UI elements.<\/li>\n<\/ul>\n\n\n\n<p>For example, a popular \u201cdate-picker\u201d fits perfectly into this definition and is an excellent subject for testing on your own keyboard.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Benefits of component tests<\/strong><\/h3>\n\n\n\n<p>These tests bring several benefits, including:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Isolation testing \u2013 <\/strong>this means we don&#8217;t need actual working software, service, website, or server to conduct the test. It saves time and increases test stability.<\/li>\n\n\n\n<li><strong>Small and fast tests \u2013 <\/strong>we conduct component tests almost like unit tests. This lets us detect irregularities quickly, resulting in quick and relatively inexpensive fixes.<\/li>\n\n\n\n<li><strong>Easy and readable code <\/strong>\u2013 using this practice, we introduce ease of code maintenance and increase its clarity. The application is divided into smaller parts, which are then tested by these component tests.<\/li>\n\n\n\n<li><strong>Automation and integration \u2013 <\/strong>these tests can be easily automated and integrated into continuous integration tools. We can also run them locally on a Docker container, particularly useful when starting the journey with automated tests.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>But why do we need component tests?<\/strong><\/h2>\n\n\n\n<p>To answer this question, we need to understand the necessity and essence of automated tests. An automated test is part of the process of checking test scenarios using automation tools or scripts. However, it&#8217;s important to remember the testing basics, as they are crucial when creating test cases. In my opinion, a good automated test should consist of three elements:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Test data,<\/li>\n\n\n\n<li>Steps,<\/li>\n\n\n\n<li>One assertion.<\/li>\n<\/ol>\n\n\n\n<p>I touch on a rather <strong>controversial topic<\/strong> by emphasizing the last point as a critical criterion. In my view, a test that checks many things is unreliable, difficult to maintain, and complicated to verify.<\/p>\n\n\n\n<p><strong>Let&#8217;s consider a situation<\/strong> where we want to write a test that submits a user registration form. We fill in all the fields and click the &#8220;submit&#8221; button using cy.contains(&#8220;submit&#8221;). However, a question arises \u2013 what happens if our button has different text, for instance, due to issues displaying special characters? We get a negative result in a test that creates a user even though the string (commonly known as a &#8220;string&#8221;) we are searching for is different.<\/p>\n\n\n\n<p>What can we do in this situation? We should write <strong>a better test<\/strong>! We can use the cy.get() method and provide our unique identifier (cy-data locator) here. This method eliminates the need to search for elements by a specific string and instead refers to the locator. However, we sometimes use the cy.contains() method because it is more convenient and effective than cy.get().<\/p>\n\n\n\n<p>But what if we had a component test that generates this element with the expected string, simultaneously checking its text, behavior, and CSS styles? Our continuous integration tool would only allow further tests to run if we fixed what produced a negative result. Thanks to early error detection, we can quickly and cheaply fix it. Additionally, this prevents false negatives in other tests where the component is at fault, not the logic of the code itself.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong><strong>Component testing vs. the Testing Pyramid<\/strong><\/strong><\/h2>\n\n\n\n<p>The Testing Pyramid is a &#8220;design pattern&#8221; that outlines the hierarchy and quantity of tests. According to generally accepted standards, it is divided into three levels, stacked one on top of the other, in order of creation\/maintenance cost or execution time.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image1-3.png\"><img decoding=\"async\" width=\"373\" height=\"288\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image1-3.png\" alt=\"The Testing Pyramid depicts the three main levels of tests\" class=\"wp-image-28264\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image1-3.png 373w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image1-3-300x232.png 300w\" sizes=\"(max-width: 373px) 100vw, 373px\" \/><\/a><figcaption class=\"wp-element-caption\">Fig. 1 The Testing Pyramid depicts the three main levels of tests<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Unit test<\/strong>s<\/h3>\n\n\n\n<p>Developers usually write these and aim to verify a method\/function\/module at a unit level. They should have the highest, realistic code coverage. Unit tests are represented as the foundation of the testing pyramid because:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>They are independent of external services.<\/li>\n\n\n\n<li>They are extremely quick to write and execute.<\/li>\n\n\n\n<li>They are inexpensive to maintain and create.<\/li>\n<\/ul>\n\n\n\n<p>They can also serve as a form of project documentation.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Integration tests<\/strong><\/h3>\n\n\n\n<p>At the next level are integration tests, which include system, functional, and integration tests. These tests verify whether individual modules communicate with each other using both test and real data. These tests are primarily written and executed by testers, but this also depends on team agreements and project approach. Depending on complexity, they may rely on external services but are certainly cheaper and faster than end-to-end tests (E2E).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>End-to-end tests<\/strong><\/h3>\n\n\n\n<p>These tests verify business paths from user creation to purchasing items in an online store. However, they have the following disadvantages:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>They are unstable.<\/li>\n\n\n\n<li>They are costly to create and maintain.<\/li>\n\n\n\n<li>They cover a minimal portion of code.<\/li>\n\n\n\n<li>Their execution time is much longer compared to unit or integration tests.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Where do component tests fit into the testing pyramid?<\/strong><\/h3>\n\n\n\n<p>Based on what we&#8217;ve read about both component tests and the Testing Pyramid, they sit between the unit and integration layers. This is precisely where I place them.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image2-1.png\"><img decoding=\"async\" width=\"365\" height=\"294\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image2-1.png\" alt=\"Testing Pyramid with placement of component tests\" class=\"wp-image-28266\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image2-1.png 365w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image2-1-300x242.png 300w\" sizes=\"(max-width: 365px) 100vw, 365px\" \/><\/a><figcaption class=\"wp-element-caption\">Fig. 2 Testing Pyramid with placement of component tests<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Who should write\/create component tests?<\/strong><\/h2>\n\n\n\n<p>Here, we encounter a situation similar to that of unit tests. Internet sources claim that developers are responsible for component tests. However, I know from experience that most developers focus more on code implementation than writing tests. This is also a debatable topic related to the definition of done, project approach, and team dynamics.<\/p>\n\n\n\n<p>In my opinion, writing component tests is an ideal task for a tester who wants to start their journey with automated testing. These tests are easy to write and maintain, and their results are clear, reliable, and transparent.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Component tests in practice<\/strong><\/h2>\n\n\n\n<p>Here, I will discuss two approaches: the old and the new way of creating component tests using JavaScript with Cypress.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Old-fashion way<\/strong><\/h3>\n\n\n\n<p>This approach is encountered in Cypress and other testing frameworks where we cannot currently display components. Knowing these limitations, let&#8217;s proceed with implementation.<\/p>\n\n\n\n<p>We want our test to verify if our website&#8217;s &#8220;Click me&#8221; button meets our expectations. We need to check the button on our locally running software version at <a href=\"http:\/\/localhost:4200\/\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >http:\/\/localhost:4200\/<\/a>.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image3-2.png\"><img decoding=\"async\" width=\"717\" height=\"396\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image3-2.png\" alt=\"Verification of the operation of the \u201cClick me\u201d button\" class=\"wp-image-28268\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image3-2.png 717w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image3-2-300x166.png 300w\" sizes=\"(max-width: 717px) 100vw, 717px\" \/><\/a><figcaption class=\"wp-element-caption\">Fig. 3 Verification of the operation of the \u201cClick me\u201d button<\/figcaption><\/figure>\n\n\n\n<p>We create test cases and check if it works.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Check if the button has the label &#8220;Click me.&#8221;<\/li>\n\n\n\n<li>Verify if the button has a red background color.<\/li>\n\n\n\n<li>Ensure the button correctly displays the text &#8220;1!2#45.&#8221;<\/li>\n\n\n\n<li>Confirm if the button displays the color changed to blue correctly.<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image4-1.png\"><img decoding=\"async\" width=\"721\" height=\"592\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image4-1.png\" alt=\"code\" class=\"wp-image-28270\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image4-1.png 721w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image4-1-300x246.png 300w\" sizes=\"(max-width: 721px) 100vw, 721px\" \/><\/a><\/figure>\n\n\n\n<p>The presented code looks neat and readable. Using the Page-Object design pattern and pulling recurring elements into variables can make it even clearer. Its drawback is undoubtedly the execution time, which, with four tests, is only 809 ms or as much as 809 ms.<\/p>\n\n\n\n<p>Here, we need to note that we access the button immediately after loading &#8220;localhost.&#8221; It does not require any additional interaction, allowing us to achieve an acceptable time for four test cases. However, it becomes more complicated to extract individual elements, for example, from the third page of the user edit form to reach the reset button, which only appears after editing any field.<\/p>\n\n\n\n<p>Suddenly, your test looks like this:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image5-3.png\"><img decoding=\"async\" width=\"352\" height=\"173\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image5-3.png\" alt=\"code\" class=\"wp-image-28272\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image5-3.png 352w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image5-3-300x147.png 300w\" sizes=\"(max-width: 352px) 100vw, 352px\" \/><\/a><\/figure>\n\n\n\n<p>Acquiring this element can take a lot of time, leading to a significant increase in code and dependence on other services. What if we were to test the button on the &#8220;production&#8221; server? It took me 12 seconds to execute these four tests.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>What can we do to make our test better and faster?<\/strong><\/h2>\n\n\n\n<ol class=\"wp-block-list\" start=\"1\">\n<li>If we have Storybook or similar tools, let&#8217;s write tests there. We may encounter inconveniences with iframes, but the scale of these inconveniences is drastically smaller compared to the time it takes to run these tests, and they are very close to component tests themselves.<\/li>\n\n\n\n<li>Combine all assertions into one test using so-called &#8220;Soft assertions&#8221; (an assertion that does not immediately fail the test upon occurrence) to save time when visiting the page or element. This idea can be beneficial, especially with the right reporter, which can really pay off. (This is a potential anti-pattern because a test should ideally consist of a single assertion, but&#8230; that&#8217;s a topic for another post). I managed to achieve a time of 358 ms.<\/li>\n\n\n\n<li>Do not refresh the page and perform assertions in separate tests (anti-pattern because tests depend on each other) \u2013 time: 278 ms.<\/li>\n\n\n\n<li>Use the cy.mount() method to utilize Cypress&#8217;s component testing!<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image6-2.png\"><img decoding=\"async\" width=\"688\" height=\"535\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image6-2.png\" alt=\"code\" class=\"wp-image-28274\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image6-2.png 688w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image6-2-300x233.png 300w\" sizes=\"(max-width: 688px) 100vw, 688px\" \/><\/a><\/figure>\n\n\n\n<p>With this method, we can generate the component individually by importing it and passing it to the mount() method. It saves time on writing and execution, keeps the code clear, and ensures reliable tests. The time I achieved was 162 ms! This is the best result so far.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image7-3.png\"><img decoding=\"async\" width=\"1024\" height=\"244\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image7-3-1024x244.png\" alt=\"Component testing\" class=\"wp-image-28276\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image7-3-1024x244.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image7-3-300x72.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image7-3-768x183.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/06\/image7-3.png 1429w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Fig. 4 Component testing<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>If not Cypress, then what?<\/strong><\/h2>\n\n\n\n<p>Component testing is not limited to Cypress alone. There are several alternative tools, such as<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Jest,<\/li>\n\n\n\n<li>Enzyme,<\/li>\n\n\n\n<li>Vue Test Utils,<\/li>\n<\/ul>\n\n\n\n<p>which can also be effectively used for this practice.<\/p>\n\n\n\n<p>These diverse options allow developers to tailor tools to specific project needs, which becomes particularly important in situations where Cypress, for various reasons, does not meet expectations.<\/p>\n\n\n\n<p>***<\/p>\n\n\n\n<p>Learn more about Cypress in <a aria-label=\"other articles by our experts (opens in a new tab)\" href=\"https:\/\/sii.pl\/blog\/all\/cypress\/\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"ek-link\">other articles by our experts<\/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;28386&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;10&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: 10)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;Cypress \u2013 component testing&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: 10)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>Component testing is a relatively new concept introduced in Cypress on June 1, 2022, in version 10.0.0. We had previously &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.pl\/blog\/en\/cypress-component-testing\/\">Continued<\/a><\/p>\n","protected":false},"author":460,"featured_media":28351,"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":[1321],"tags":[2231,1619,1590],"class_list":["post-28386","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-testing","tag-component-testing","tag-cypress-en","tag-tools"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/07\/Cypress_testy-komponentow.jpg","category_names":["Testing"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts\/28386"}],"collection":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/users\/460"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/comments?post=28386"}],"version-history":[{"count":1,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts\/28386\/revisions"}],"predecessor-version":[{"id":28388,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts\/28386\/revisions\/28388"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/media\/28351"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/media?parent=28386"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/categories?post=28386"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/tags?post=28386"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}