{"id":1754,"date":"2011-02-09T14:31:53","date_gmt":"2011-02-09T16:31:53","guid":{"rendered":"http:\/\/blog.plataformatec.com.br\/?p=1754"},"modified":"2015-02-25T13:38:26","modified_gmt":"2015-02-25T16:38:26","slug":"improving-your-tests-with-capybara-custom-selectors","status":"publish","type":"post","link":"https:\/\/blog.plataformatec.com.br\/2011\/02\/improving-your-tests-with-capybara-custom-selectors\/","title":{"rendered":"Improving your tests with Capybara custom selectors"},"content":{"rendered":"

Here at PlataformaTec we like to use Capybara for acceptance tests. Recently we have discovered the custom selectors feature in Capybara and we would like to share with you how that feature helped us to improve our tests.<\/p>\n

Sometimes we need to implement features that involves showing some ordered items to the user, like a ranking feature. The HTML for a feature like that could be:<\/p>\n

<ol id=\"overall-ranking\">\n  <% @top_users.each do |user| %>\n    <li><%= user.name %><\/li>\n  <% end %>\n<\/ol>\n<\/code><\/pre>\n

The acceptance tests for this ranking could be written as follows:<\/p>\n

scenario \"The user can see an overall ranking\" do\n  Factory(:user, :name => \"Hugo\",  :score => 5000)\n  Factory(:user, :name => \"Ozaki\", :score => 3000)\n  Factory(:user, :name => \"Jo\u00e3o\",  :score => 4000)\n\n  visit overall_ranking_path\n\n  within(\"#overall-ranking\") do\n    find(:xpath, '.\/\/li[1]').text.should match(\"Hugo\")\n    find(:xpath, '.\/\/li[2]').text.should match(\"Jo\u00e3o\")\n    find(:xpath, '.\/\/li[3]').text.should match(\"Ozaki\")\n  end\nend\n<\/code><\/pre>\n

Generally, I don’t like to see those XPath selectors inside my acceptance tests. And sometimes it can get really ugly! So, in order to improve our tests, we can create a custom selector with Capybara as follows:<\/p>\n

# spec\/spec_helper.rb\n\nRSpec.configure do |config|\n\n  Capybara.add_selector(:li) do\n    xpath { |num| \".\/\/li[#{num}]\" }\n  end\n\nend\n<\/code><\/pre>\n

After that, we can refactor our test as shown below:<\/p>\n

scenario \"The user can see an overall ranking\" do\n  Factory(:user, :name => \"Hugo\",  :score => 5000)\n  Factory(:user, :name => \"Ozaki\", :score => 3000)\n  Factory(:user, :name => \"Jo\u00e3o\",  :score => 4000)\n\n  visit overall_ranking_path\n\n  within(\"#overall-ranking\") do\n    find(:li, 1).text.should match(\"Hugo\")\n    find(:li, 2).text.should match(\"Jo\u00e3o\")\n    find(:li, 3).text.should match(\"Ozaki\")\n  end\nend\n<\/code><\/pre>\n

If you wanna know more about Capybara’s custom selectors, check its README<\/a>.<\/p>\n

And you? Any tips about using Capybara or improving your acceptance\/integration tests?<\/p>\n","protected":false},"excerpt":{"rendered":"

Here at PlataformaTec we like to use Capybara for acceptance tests. Recently we have discovered the custom selectors feature in Capybara and we would like to share with you how that feature helped us to improve our tests. Sometimes we need to implement features that involves showing some ordered items to the user, like a … \u00bb<\/a><\/p>\n","protected":false},"author":5,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[1],"tags":[94,96],"aioseo_notices":[],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/1754"}],"collection":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/comments?post=1754"}],"version-history":[{"count":24,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/1754\/revisions"}],"predecessor-version":[{"id":4434,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/1754\/revisions\/4434"}],"wp:attachment":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/media?parent=1754"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/categories?post=1754"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/tags?post=1754"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}