From fd7cf4a4bc3dc53e8fa6b4ec508ea23431c9d5d2 Mon Sep 17 00:00:00 2001 From: Adam McCrea Date: Sat, 27 Aug 2011 17:54:55 -0400 Subject: [PATCH] Use custom selectors in matchers This continues the centralization of XPath generation and failure messages. --- lib/capybara/node/finders.rb | 15 +++++------ lib/capybara/node/matchers.rb | 47 ++++++++++++++--------------------- lib/capybara/selector.rb | 38 +++++++++++++++++----------- 3 files changed, 49 insertions(+), 51 deletions(-) diff --git a/lib/capybara/node/finders.rb b/lib/capybara/node/finders.rb index 39a441e5..1e344262 100644 --- a/lib/capybara/node/finders.rb +++ b/lib/capybara/node/finders.rb @@ -109,7 +109,7 @@ module Capybara # @return [Array[Capybara::Element]] The found elements # def all(*args) - options = extract_normalized_options(args) + args, options = extract_normalized_options(args) selector = Capybara::Selector.normalize(*args) selector.xpaths. @@ -132,7 +132,7 @@ module Capybara # @return [Capybara::Element] The found element or nil # def first(*args) - options = extract_normalized_options(args) + args, options = extract_normalized_options(args) found_elements = [] selector = Capybara::Selector.normalize(*args) @@ -150,10 +150,11 @@ module Capybara protected def raise_find_error(*args) - options = extract_normalized_options(args) - normalized = Capybara::Selector.normalize(*args) - message = options[:message] || "Unable to find #{normalized.name} #{normalized.locator.inspect}" - message = normalized.failure_message.call(self, normalized) if normalized.failure_message + args, options = extract_normalized_options(args) + normalized = Capybara::Selector.normalize(*args) + message = options[:message] || "Unable to find #{normalized.name} #{normalized.locator.inspect}" + message = normalized.failure_message.call(self, normalized) if normalized.failure_message + raise Capybara::ElementNotFound, message end @@ -178,7 +179,7 @@ module Capybara options[:selected] = [selected].flatten end - options + [args.push(options), options] end def matches_options(node, options) diff --git a/lib/capybara/node/matchers.rb b/lib/capybara/node/matchers.rb index 66ef3acb..158c4767 100644 --- a/lib/capybara/node/matchers.rb +++ b/lib/capybara/node/matchers.rb @@ -157,7 +157,7 @@ module Capybara # @return [Boolean] If the selector exists # def has_css?(path, options={}) - has_xpath?(XPath.css(path), options) + has_selector?(:css, path, options) end ## @@ -169,7 +169,7 @@ module Capybara # @return [Boolean] # def has_no_css?(path, options={}) - has_no_xpath?(XPath.css(path), options) + has_no_selector?(:css, path, options) end ## @@ -181,7 +181,7 @@ module Capybara # @return [Boolean] Whether it exists # def has_content?(content) - has_xpath?(XPath::HTML.content(normalize_whitespace(content))) + has_selector?(:content, normalize_whitespace(content)) end ## @@ -193,7 +193,7 @@ module Capybara # @return [Boolean] Whether it exists # def has_no_content?(content) - has_no_xpath?(XPath::HTML.content(normalize_whitespace(content))) + has_no_selector?(:content, normalize_whitespace(content)) end ## @@ -251,7 +251,7 @@ module Capybara # @return [Boolean] Whether it exists # def has_link?(locator, options={}) - has_xpath?(XPath::HTML.link(locator, options)) + has_selector?(:link, locator, options) end ## @@ -263,7 +263,7 @@ module Capybara # @return [Boolean] Whether it doesn't exist # def has_no_link?(locator, options={}) - has_no_xpath?(XPath::HTML.link(locator, options)) + has_no_selector?(:link, locator, options) end ## @@ -275,7 +275,7 @@ module Capybara # @return [Boolean] Whether it exists # def has_button?(locator) - has_xpath?(XPath::HTML.button(locator)) + has_selector?(:button, locator) end ## @@ -287,7 +287,7 @@ module Capybara # @return [Boolean] Whether it doesn't exist # def has_no_button?(locator) - has_no_xpath?(XPath::HTML.button(locator)) + has_no_selector?(:button, locator) end ## @@ -306,8 +306,7 @@ module Capybara # @return [Boolean] Whether it exists # def has_field?(locator, options={}) - options, with = split_options(options, :with) - has_xpath?(XPath::HTML.field(locator, options), with) + has_selector?(:field, locator, options) end ## @@ -320,8 +319,7 @@ module Capybara # @return [Boolean] Whether it doesn't exist # def has_no_field?(locator, options={}) - options, with = split_options(options, :with) - has_no_xpath?(XPath::HTML.field(locator, options), with) + has_no_selector?(:field, locator, options) end ## @@ -334,7 +332,7 @@ module Capybara # @return [Boolean] Whether it exists # def has_checked_field?(locator) - has_xpath?(XPath::HTML.field(locator), :checked => true) + has_selector?(:field, locator, :checked => true) end ## @@ -347,7 +345,7 @@ module Capybara # @return [Boolean] Whether it doesn't exists # def has_no_checked_field?(locator) - has_no_xpath?(XPath::HTML.field(locator), :checked => true) + has_no_selector?(:field, locator, :checked => true) end ## @@ -360,7 +358,7 @@ module Capybara # @return [Boolean] Whether it exists # def has_unchecked_field?(locator) - has_xpath?(XPath::HTML.field(locator), :unchecked => true) + has_selector?(:field, locator, :unchecked => true) end ## @@ -373,7 +371,7 @@ module Capybara # @return [Boolean] Whether it doesn't exists # def has_no_unchecked_field?(locator) - has_no_xpath?(XPath::HTML.field(locator), :unchecked => true) + has_no_selector?(:field, locator, :unchecked => true) end ## @@ -400,8 +398,7 @@ module Capybara # @return [Boolean] Whether it exists # def has_select?(locator, options={}) - options, selected = split_options(options, :selected) - has_xpath?(XPath::HTML.select(locator, options), selected) + has_selector?(:select, locator, options) end ## @@ -413,8 +410,7 @@ module Capybara # @return [Boolean] Whether it doesn't exist # def has_no_select?(locator, options={}) - options, selected = split_options(options, :selected) - has_no_xpath?(XPath::HTML.select(locator, options), selected) + has_no_selector?(:select, locator, options) end ## @@ -435,7 +431,7 @@ module Capybara # @return [Boolean] Whether it exist # def has_table?(locator, options={}) - has_xpath?(XPath::HTML.table(locator, options)) + has_selector?(:table, locator, options) end ## @@ -447,14 +443,7 @@ module Capybara # @return [Boolean] Whether it doesn't exist # def has_no_table?(locator, options={}) - has_no_xpath?(XPath::HTML.table(locator, options)) - end - - protected - - def split_options(options, key) - options = options.dup - [options, if options.has_key?(key) then {key => options.delete(key)} else {} end] + has_no_selector?(:table, locator, options) end ## diff --git a/lib/capybara/selector.rb b/lib/capybara/selector.rb index ace9ebe4..be9c34de 100644 --- a/lib/capybara/selector.rb +++ b/lib/capybara/selector.rb @@ -35,7 +35,7 @@ module Capybara end normalized.selector ||= all[Capybara.default_selector] - xpath = normalized.selector.call(normalized.locator) + xpath = normalized.selector.call(normalized.locator, normalized.options) if xpath.respond_to?(:to_xpaths) normalized.xpaths = xpath.to_xpaths else @@ -73,8 +73,8 @@ module Capybara @failure_message end - def call(locator) - @xpath.call(locator) + def call(locator, options={}) + @xpath.call(locator, options) end def match?(locator) @@ -84,7 +84,7 @@ module Capybara end Capybara.add_selector(:xpath) do - xpath { |xpath| xpath } + xpath { |xpath, options| xpath } end Capybara.add_selector(:css) do @@ -92,51 +92,51 @@ Capybara.add_selector(:css) do end Capybara.add_selector(:id) do - xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] } + xpath { |id, options| XPath.descendant[XPath.attr(:id) == id.to_s] } match { |value| value.is_a?(Symbol) } end Capybara.add_selector(:field) do - xpath { |locator| XPath::HTML.field(locator) } + xpath { |locator, options| XPath::HTML.field(locator) } end Capybara.add_selector(:link_or_button) do - xpath { |locator| XPath::HTML.link_or_button(locator) } + xpath { |locator, options| XPath::HTML.link_or_button(locator) } failure_message { |node, selector| "no link or button '#{selector.locator}' found" } end Capybara.add_selector(:link) do - xpath { |locator| XPath::HTML.link(locator) } + xpath { |locator, options| XPath::HTML.link(locator, options) } failure_message { |node, selector| "no link with title, id or text '#{selector.locator}' found" } end Capybara.add_selector(:button) do - xpath { |locator| XPath::HTML.button(locator) } + xpath { |locator, options| XPath::HTML.button(locator) } failure_message { |node, selector| "no button with value or id or text '#{selector.locator}' found" } end Capybara.add_selector(:fillable_field) do - xpath { |locator| XPath::HTML.fillable_field(locator) } + xpath { |locator, options| XPath::HTML.fillable_field(locator, options) } failure_message { |node, selector| "no text field, text area or password field with id, name, or label '#{selector.locator}' found" } end Capybara.add_selector(:radio_button) do - xpath { |locator| XPath::HTML.radio_button(locator) } + xpath { |locator, options| XPath::HTML.radio_button(locator, options) } failure_message { |node, selector| "no radio button with id, name, or label '#{selector.locator}' found" } end Capybara.add_selector(:checkbox) do - xpath { |locator| XPath::HTML.checkbox(locator) } + xpath { |locator, options| XPath::HTML.checkbox(locator, options) } failure_message { |node, selector| "no checkbox with id, name, or label '#{selector.locator}' found" } end Capybara.add_selector(:select) do - xpath { |locator| XPath::HTML.select(locator) } + xpath { |locator, options| XPath::HTML.select(locator, options) } failure_message { |node, selector| "no select box with id, name, or label '#{selector.locator}' found" } end Capybara.add_selector(:option) do - xpath { |locator| XPath::HTML.option(locator) } + xpath { |locator, options| XPath::HTML.option(locator) } failure_message do |node, selector| "no option with text '#{selector.locator}'".tap do |message| message << " in the select box" if node.tag_name == 'select' @@ -145,6 +145,14 @@ Capybara.add_selector(:option) do end Capybara.add_selector(:file_field) do - xpath { |locator| XPath::HTML.file_field(locator) } + xpath { |locator, options| XPath::HTML.file_field(locator, options) } failure_message { |node, selector| "no file field with id, name, or label '#{selector.locator}' found" } end + +Capybara.add_selector(:content) do + xpath { |content, options| XPath::HTML.content(content) } +end + +Capybara.add_selector(:table) do + xpath { |locator, options| XPath::HTML.table(locator, options) } +end