{"id":16538,"date":"2017-03-13T12:15:59","date_gmt":"2017-03-13T10:15:59","guid":{"rendered":"https:\/\/www.webcodegeeks.com\/?p=16538"},"modified":"2017-03-10T12:27:23","modified_gmt":"2017-03-10T10:27:23","slug":"principles-effective-testing-capybara","status":"publish","type":"post","link":"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/","title":{"rendered":"Principles of Effective Testing with Capybara"},"content":{"rendered":"<p>Currently the world of integration testing is overwhelmed with complexity. Industry standards require adding more layers of abstraction with tools like Cucumber, SitePrism, and others, and as a result it becomes more difficult and tedious for a developer to write a simple test. But as any other part of the codebase, testing scenarios should be simple and fun. They should be designed for readability and changeability.<\/p>\n<p>In this article, I\u2019m going to talk about how to make integration testing simple and effective with bare-bones Capybara. We will walk through several rules which, in my experience, lead to clarity and simplicity.<\/p>\n<p>Let\u2019s start with an example:<\/p>\n<pre class=\"brush:php\">scenario \"looking for a hotel\" do\r\n  visit \"\/search\"\r\n  should_see \"Type a destination\"\r\n  fill_in \"Country\", with: \"France\"\r\n  fill_in \"City\", with: \"Paris\"\r\n  set_date \"02\/17\/2099\"\r\n  select \"1\", from: \"Rooms\"\r\n  select \"2\", from: \"Adults\"\r\n  check \"I'm travelling for work\"\r\n  click_on \"Search\"\r\n  should_see \"1 result found\"\r\n  should_see \"Test hotel\"\r\nend<\/pre>\n<p>That is an awesome testing scenario for a few reasons: Any developer with knowledge of the Capybara API can easily read it; it\u2019s obvious what it tests and what it expects, so it\u2019s easy to add more steps and change it; and it doesn\u2019t need changing when markup changes. It only depends on the business requirements.<\/p>\n<p>Now, this scenario has some distinctive features: \u2013 There are no selectors. \u2013 All values are checked globally. \u2013 It tries to maximize usage of Capybara helpers (it sticks to simple means). \u2013 It extends the Capybara API with <code>should_see<\/code>, which is a helper that improves readability. \u2013 It also uses a custom helper <code>set_date<\/code>, which is not scenario-specific but rather widget-specific \u2014 a helper for a date selector widget.<\/p>\n<p>So how do you make all your tests concise and to-the-point like this one? I\u2019ve come up with several rules that can help keep your tests focused on their job, as well as make them easy to write and change.<\/p>\n<h2>Define a Limited Language<\/h2>\n<p>It\u2019s a good thing to take a user\u2019s perspective into account when you\u2019re writing tests. It allows you to focus on the end result and see the product as your user sees it. That\u2019s why you need an extra level of abstraction, a DSL that speaks in a user\u2019s terms.<\/p>\n<p>You could use <a href=\"https:\/\/cucumber.io\/\">Cucumber<\/a>, but even with that, it\u2019s easy to write steps like <code>When I click on \".my-form button\"<\/code>. In this case, you break the abstraction anyway, and now you have to deal with the mental overhead that Cucumber gives you, with nothing in return.<\/p>\n<p>In my experience, it\u2019s best to go with bare-bones Capybara. Note that Capybara already has this layer of abstraction. Think <code>click_on \"Purchase\"<\/code> versus <code>find(...).click<\/code>. The first one searches for an element by text and will refuse to click if it\u2019s not visible or if it\u2019s not a link\/button. It also reads nicely.<\/p>\n<p>Of course that might not be enough, and you probably will need to implement your own custom steps. Just make sure they\u2019re on the same level of abstraction as <code>click_on<\/code>, <code>fill_in<\/code>, and so on. They should not accept selectors, only text. For example, here\u2019s my most useful helper:<\/p>\n<pre class=\"brush:php\">def should_see(text)\r\n  expect(page).to have_content(text)\r\nend\r\n\r\ndef should_not_see(text)\r\n  expect(page).to have_no_content(text)\r\nend<\/pre>\n<h2>Use Universal Steps<\/h2>\n<p>By \u201cuniversal steps,\u201d I mean steps that get used in different tests, as opposed to feature-specific steps that only make sense within a certain scenario. Feature-specific steps should be avoided because they add up to mental overhead that a developer needs to deal with when working with a scenario.<\/p>\n<p>Instead, be explicit. Think about <code>fill_in_order_form<\/code> versus <code>fill_in \"quantity\". with: ''; fill_in password with ''<\/code>. The former hides the complexity, and thus forces a developer to look into an implementation. The latter makes it explicit and easily accessible, so you should always be using it.<\/p>\n<h2>Avoid Using Selectors<\/h2>\n<p>When you use selectors, you switch your mindset from a user\u2019s perspective to a developer\u2019s, from feature to implementation. That\u2019s the wrong way to do it. Users don\u2019t think in selectors. They don\u2019t care about ids and classes. There\u2019s no value in it, nor they are visible to the user.<\/p>\n<p>What selectors do give you is an extra dependency on the code markup, which is an implementation detail. Now your test is going to fail not only because of an actual bug, but also because markup has changed for whatever reason. And it\u2019s not just that tests become fragile; they become harder to read and comprehend, and therefore harder to maintain.<\/p>\n<p>Compare:<\/p>\n<pre class=\"brush:php\">within(\".order-form\") do\r\n  click_on \"input[type=submit]\"\r\nend<\/pre>\n<p>and<\/p>\n<pre class=\"brush:php\">click_on \"Purchase\"<\/pre>\n<p>Note how I just don\u2019t care where exactly on the page the button is located. There\u2019s nothing wrong with looking for elements globally \u2014 remember, that\u2019s how a user does it.<\/p>\n<h2>Use Text Values<\/h2>\n<p>Try to always stick to something that a user can see on the page, like text values. It\u2019s really not as hard as it seems. First of all, Capybara out-of-the-box gives you tools that work this way, methods like \u201cclick_on\u201d (link and button values), \u201cfill_in\u201d (labels and placeholders), and so on. But even if you need something custom, it\u2019s actually quite easy to implement.<\/p>\n<p>By the way, this is why I don\u2019t use tools like <a href=\"https:\/\/github.com\/natritmeyer\/site_prism\">SitePrism<\/a>. SitePrism allows you to map entities to selectors on the page and work with those entities instead of selectors directly. However, it\u2019s not solving a problem, it\u2019s just hiding it by adding another layer of abstraction. To my mind, that\u2019s even worse, because it makes the problem implicit.<\/p>\n<h2>Deal with Ambiguity<\/h2>\n<p>As I said earlier, there\u2019s nothing wrong with searching for an element on a page globally. But what if there are several buttons on the page with the same title?<\/p>\n<p>Consider for a little bit that maybe this ambiguity should be addressed in the business area. How do you expect a user to behave when he sees two Purchase buttons? (A rhetorical question, of course.)<\/p>\n<p>There can be repetitive elements on a page (think rows in a table). One solution for this could be introducing new ids or classes to the page in order to be able to target them. But that\u2019s not a good way to do it. A better solution would be to depend on the order and use numerables in your test. Consider something like this:<\/p>\n<pre class=\"brush:php\">scenario do\r\n  # ...\r\n  within_table_row(3) do\r\n    click_on \"Delete\"\r\n  end\r\n  # ...\r\nend\r\n\r\n# support\/helpers.rb\r\ndef within_table_row(position)\r\n  row = find_all(\"table tr\")[position]\r\n  within(row) do\r\n    yield\r\n  end\r\nend<\/pre>\n<p>Having a proper semantic markup also helps. For example, if you use the <a href=\"http:\/\/htmlreference.io\/\"><code>aside<\/code> HTML tag for the menu block and <code>main<\/code> for the main content<\/a>, you can easily implement helpers like <code>within_sidebar { ... }<\/code> and <code>within_main { ... }<\/code>.<\/p>\n<h2>Stick to Semantic Markup<\/h2>\n<p>The method <code>click_on<\/code> works perfectly for buttons and links, but it won\u2019t click on a span, for example. This is by design. You shouldn\u2019t have spans that behave like links in your code anyway. Use proper markup or ask your HTML developer to do so. If it\u2019s clickable, it should be a button or a link. If it\u2019s a form, it should be a <code>form<\/code> element.<\/p>\n<p>HTML is semantic for a reason, and browsers know better how to deal with different elements in your DOM when they know what they\u2019re dealing with.<\/p>\n<p>Another example of this kind is the method <code>fill_in<\/code>, which can handle both labels and placeholders. If your markup lacks this element, you may be tempted to use <code>find(\"input\").set<\/code>.<\/p>\n<p>But consider for a minute, maybe this is actually a UX problem? If there are no placeholders, nor labels on the page, how is the user to decide what should be put in that field and why? Instead of hacking your way through broken markup, consider changing it by adding a placeholder or a label.<\/p>\n<h2>Conclusion<\/h2>\n<p>In general, never forget that testing should be simple and fun. I often find myself thinking about how can I make the experience even more enjoyable, and I hope you do, too. When you do achieve a certain level of clarity and simplicity in your testing scenarios, it pays off tremendously.<\/p>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td><span class=\"reference\">Reference: <\/span><\/td>\n<td><a href=\"https:\/\/blog.codeship.com\/principles-of-effective-testing-with-capybara\/\">Principles of Effective Testing with Capybara<\/a> from our <a href=\"http:\/\/www.webcodegeeks.com\/join-us\/wcg\/\">WCG partner<\/a> Yanis Triandaphilov at the <a href=\"http:\/\/blog.codeship.com\/\">Codeship Blog<\/a> blog.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Currently the world of integration testing is overwhelmed with complexity. Industry standards require adding more layers of abstraction with tools like Cucumber, SitePrism, and others, and as a result it becomes more difficult and tedious for a developer to write a simple test. But as any other part of the codebase, testing scenarios should be &hellip;<\/p>\n","protected":false},"author":227,"featured_media":4128,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[21],"tags":[380],"class_list":["post-16538","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ruby","tag-capybara"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Principles of Effective Testing with Capybara - Web Code Geeks - 2026<\/title>\n<meta name=\"description\" content=\"Currently the world of integration testing is overwhelmed with complexity. Industry standards require adding more layers of abstraction with tools like\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Principles of Effective Testing with Capybara - Web Code Geeks - 2026\" \/>\n<meta property=\"og:description\" content=\"Currently the world of integration testing is overwhelmed with complexity. Industry standards require adding more layers of abstraction with tools like\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/\" \/>\n<meta property=\"og:site_name\" content=\"Web Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/webcodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2017-03-13T10:15:59+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Yanis Triandaphilov\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Yanis Triandaphilov\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/\"},\"author\":{\"name\":\"Yanis Triandaphilov\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/556c1e47406608dd65cbdbc1217575c1\"},\"headline\":\"Principles of Effective Testing with Capybara\",\"datePublished\":\"2017-03-13T10:15:59+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/\"},\"wordCount\":1271,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg\",\"keywords\":[\"Capybara\"],\"articleSection\":[\"Ruby\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/\",\"name\":\"Principles of Effective Testing with Capybara - Web Code Geeks - 2026\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg\",\"datePublished\":\"2017-03-13T10:15:59+00:00\",\"description\":\"Currently the world of integration testing is overwhelmed with complexity. Industry standards require adding more layers of abstraction with tools like\",\"breadcrumb\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/#primaryimage\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.webcodegeeks.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Ruby\",\"item\":\"https:\/\/www.webcodegeeks.com\/category\/ruby\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Principles of Effective Testing with Capybara\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"name\":\"Web Code Geeks\",\"description\":\"Web Developers Resource Center\",\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.webcodegeeks.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/webcodegeeks\",\"https:\/\/x.com\/webcodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/556c1e47406608dd65cbdbc1217575c1\",\"name\":\"Yanis Triandaphilov\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/7b336d9c2bb6f83299994032828d8717bae760e864c4ddd75f1b02e61ceed860?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/7b336d9c2bb6f83299994032828d8717bae760e864c4ddd75f1b02e61ceed860?s=96&d=mm&r=g\",\"caption\":\"Yanis Triandaphilov\"},\"description\":\"Yanis Triandaphilov lives and works in Prague. He's been into Ruby and JavaScript development for more than six years now. \\\"Being not too smart, I struggle for clarity and simplicity in everything I do.\\\"\",\"url\":\"https:\/\/www.webcodegeeks.com\/author\/yanis-triandaphilov\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Principles of Effective Testing with Capybara - Web Code Geeks - 2026","description":"Currently the world of integration testing is overwhelmed with complexity. Industry standards require adding more layers of abstraction with tools like","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/","og_locale":"en_US","og_type":"article","og_title":"Principles of Effective Testing with Capybara - Web Code Geeks - 2026","og_description":"Currently the world of integration testing is overwhelmed with complexity. Industry standards require adding more layers of abstraction with tools like","og_url":"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/","og_site_name":"Web Code Geeks","article_publisher":"https:\/\/www.facebook.com\/webcodegeeks","article_published_time":"2017-03-13T10:15:59+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg","type":"image\/jpeg"}],"author":"Yanis Triandaphilov","twitter_card":"summary_large_image","twitter_creator":"@webcodegeeks","twitter_site":"@webcodegeeks","twitter_misc":{"Written by":"Yanis Triandaphilov","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/#article","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/"},"author":{"name":"Yanis Triandaphilov","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/556c1e47406608dd65cbdbc1217575c1"},"headline":"Principles of Effective Testing with Capybara","datePublished":"2017-03-13T10:15:59+00:00","mainEntityOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/"},"wordCount":1271,"commentCount":0,"publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg","keywords":["Capybara"],"articleSection":["Ruby"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/","url":"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/","name":"Principles of Effective Testing with Capybara - Web Code Geeks - 2026","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/#primaryimage"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg","datePublished":"2017-03-13T10:15:59+00:00","description":"Currently the world of integration testing is overwhelmed with complexity. Industry standards require adding more layers of abstraction with tools like","breadcrumb":{"@id":"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/#primaryimage","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.webcodegeeks.com\/ruby\/principles-effective-testing-capybara\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.webcodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Ruby","item":"https:\/\/www.webcodegeeks.com\/category\/ruby\/"},{"@type":"ListItem","position":3,"name":"Principles of Effective Testing with Capybara"}]},{"@type":"WebSite","@id":"https:\/\/www.webcodegeeks.com\/#website","url":"https:\/\/www.webcodegeeks.com\/","name":"Web Code Geeks","description":"Web Developers Resource Center","publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.webcodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.webcodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.webcodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/webcodegeeks","https:\/\/x.com\/webcodegeeks"]},{"@type":"Person","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/556c1e47406608dd65cbdbc1217575c1","name":"Yanis Triandaphilov","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/7b336d9c2bb6f83299994032828d8717bae760e864c4ddd75f1b02e61ceed860?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/7b336d9c2bb6f83299994032828d8717bae760e864c4ddd75f1b02e61ceed860?s=96&d=mm&r=g","caption":"Yanis Triandaphilov"},"description":"Yanis Triandaphilov lives and works in Prague. He's been into Ruby and JavaScript development for more than six years now. \"Being not too smart, I struggle for clarity and simplicity in everything I do.\"","url":"https:\/\/www.webcodegeeks.com\/author\/yanis-triandaphilov\/"}]}},"_links":{"self":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/16538","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/users\/227"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/comments?post=16538"}],"version-history":[{"count":0,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/16538\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media\/4128"}],"wp:attachment":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media?parent=16538"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/categories?post=16538"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/tags?post=16538"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}