module HtmlSelectorsHelpers # Creates a selector (a string) using xpath or css selectors (default) def make_selector(element, attrs={}, method=:css) case method when :xpath # TODO: test xpath with multiple attrs "//#{element}" + attrs.map{ |k,v| "[@#{k.to_s}='#{v.to_s}']" }.join else # :css "#{element}" + attrs.map{ |k,v| "[#{k.to_s}='#{v.to_s}']" }.join end end # Ensures the page has certain element with certain attributes # Same as has_element but for the entire page def page_has_element(element, attrs={}, method=:css) selector = make_selector(element, attrs, method) if page.respond_to? :should case method when :xpath page.should have_xpath(selector) else # :css page.should have_selector(selector) end else case method when :xpath assert page.has_xpath?(selector) else # :css assert page.has_selector?(selector) end end end # Ensures there is a certain element with certain attributes # Used inside "within" blocks # Exemples (both will have the same result): # has_element("input", { :name => 'meeting', :type => 'hidden', :value => 'my-value' }) # has_element("input[name='meeting'][type='hidden'][value='my-value']") def has_element(element, attrs={}, method=:css) selector = make_selector(element, attrs, method) if respond_to? :should case method when :xpath should have_xpath(selector) else # :css should have_selector(selector) end else case method when :xpath assert has_xpath?(selector) else # :css assert has_xpath?(selector) end end end def doesnt_have_element(element, attrs={}, method=:css) selector = make_selector(element, attrs, method) if respond_to? :should case method when :xpath should_not have_xpath(selector) else # :css should_not have_selector(selector) end else case method when :xpath assert !has_xpath?(selector) else # :css assert !has_xpath?(selector) end end end # Creates a css selector to match a form with certain action, method and possibly other attribues def form_selector(action, method='post', attrs={}) attrs[:action] = action attrs[:method] = method make_selector("form", attrs) end # Maps a name to a selector. Used primarily by the # # When /^(.+) within (.+)$/ do |step, scope| # # step definitions in web_steps.rb # def selector_for(locator) case locator when "the page" "html > body" # Add more mappings here. # Here is an example that pulls values out of the Regexp: # # when /^the (notice|error|info) flash$/ # ".flash.#{$1}" # You can also return an array to use a different selector # type, like: # # when /the header/ # [:xpath, "//header"] # This allows you to provide a quoted selector as the scope # for "within" steps as was previously the default for the # web steps: when /^"(.+)"$/ $1 else raise "Can't find mapping from \"#{locator}\" to a selector.\n" + "Now, go and add a mapping in #{__FILE__}" end end end World(HtmlSelectorsHelpers)