Follow table links in cucumber

On a page you’ll quite often have a table like the following

Book Author  
Harry Potter and half blood prince J.K. Rowling Delete
The Cuckoo’s Egg: Tracking a Spy Through the Maze of Computer Espionage Cliff Stoll Delete

In your cucumber steps you want to say

Given I am on the books page
When I follow the "Delete" link for "Harry Potter and half blood prince"
Then ...

Out of the box webrat doesn’t have a step that will allow you to do this. Let’s create one that will do the job

When /^I follow the "([^\"]*)" link for "([^\"]*)"$/ do |link, cell_value|
  within "//*[.//text()='#{cell_value}' and .//a[text()='#{link}']]" do |scope|
   scope.click_link link
 end
end

This works great, it even works outside tables, the step will work so long as the text and link have a common parent in the dom. Just one problem, for this step to work webrat needs to understand xpath selectors. Here’s a little monkey patch that will get it working in webrat 0.6.0.

#lib/webrat_extensions.rb
module Webrat
  class Scope
    protected
      def scoped_dom
        begin
          @scope.dom.css(@selector).first
        rescue Nokogiri::CSS::SyntaxError, Nokogiri::XML::XPath::SyntaxError => e
          begin
            @scope.dom.xpath(@selector).first
          rescue Nokogiri::XML::XPath::SyntaxError
            raise e
          end
        end
      end
  end
end

Once you’ve added the patch our new webrat step will work. As a bonus you also get to use xpath selectors anywhere you use css selectors.


 
 
 

2 Responses to “Follow table links in cucumber”

  1. Tim Medcalf
    27. April 2010 at 07:06

    Brilliant. Thanks. Just what i was looking for. Don’t know if it makes any real difference but i ended up putting the file in /features/support. I guess that keeps it away from my main app code, but shouldn’t make much difference i guess.

  2. Jon Kinney
    10. May 2010 at 13:36

    I can’t seem to get this to work. I’m not sure why, I’ve triple checked and my table has the same format as yours but even when using something like ‘xpath checker’ or whatever the firefox extension is called I can’t get the selector to work right. My document is HTML5, does that matter? I’ve included just my table’s HTML in the snippet below. I also have the xpath selector as specified in my app shown in that file.

    http://pastie.textmate.org/private/9od335pmsj4hi9nbe9lbow

    Any help is greatly appreciated! Thank you so much,
    -Jon

Leave a Reply