mirror of
https://github.com/teamcapybara/capybara.git
synced 2022-11-09 12:08:07 -05:00
Make Query a first class citizen
This commit is contained in:
parent
33692b258c
commit
4083ed1afa
4 changed files with 58 additions and 59 deletions
|
@ -302,6 +302,7 @@ module Capybara
|
|||
autoload :Server, 'capybara/server'
|
||||
autoload :Session, 'capybara/session'
|
||||
autoload :Selector, 'capybara/selector'
|
||||
autoload :Query, 'capybara/query'
|
||||
autoload :VERSION, 'capybara/version'
|
||||
|
||||
module Node
|
||||
|
|
|
@ -109,10 +109,10 @@ module Capybara
|
|||
# @return [Array[Capybara::Element]] The found elements
|
||||
#
|
||||
def all(*args)
|
||||
selector = Capybara::Selector.normalize(*args)
|
||||
selector.xpaths.
|
||||
map { |path| find_in_base(selector, path) }.flatten.
|
||||
select { |node| selector.matches_filters?(node) }
|
||||
query = Capybara::Query.new(*args)
|
||||
query.xpaths.
|
||||
map { |path| find_in_base(query, path) }.flatten.
|
||||
select { |node| query.matches_filters?(node) }
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -138,13 +138,13 @@ module Capybara
|
|||
protected
|
||||
|
||||
def raise_find_error(*args)
|
||||
normalized = Capybara::Selector.normalize(*args)
|
||||
raise Capybara::ElementNotFound, normalized.failure_message(self)
|
||||
query = Capybara::Query.new(*args)
|
||||
raise Capybara::ElementNotFound, query.failure_message(self)
|
||||
end
|
||||
|
||||
def find_in_base(selector, xpath)
|
||||
def find_in_base(query, xpath)
|
||||
base.find(xpath).map do |node|
|
||||
Capybara::Node::Element.new(session, node, self, selector)
|
||||
Capybara::Node::Element.new(session, node, self, query)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
49
lib/capybara/query.rb
Normal file
49
lib/capybara/query.rb
Normal file
|
@ -0,0 +1,49 @@
|
|||
module Capybara
|
||||
class Query
|
||||
attr_accessor :selector, :locator, :options, :xpaths
|
||||
|
||||
def initialize(*args)
|
||||
@options = if args.last.is_a?(Hash) then args.pop.dup else {} end
|
||||
if text = options[:text]
|
||||
@options[:text] = Regexp.escape(text) unless text.kind_of?(Regexp)
|
||||
end
|
||||
unless options.has_key?(:visible)
|
||||
@options[:visible] = Capybara.ignore_hidden_elements
|
||||
end
|
||||
|
||||
if args[1]
|
||||
@selector = Selector.all[args[0]]
|
||||
@locator = args[1]
|
||||
else
|
||||
@selector = Selector.all.values.find { |s| s.match?(args[0]) }
|
||||
@locator = args[0]
|
||||
end
|
||||
@selector ||= Selector.all[Capybara.default_selector]
|
||||
|
||||
xpath = @selector.call(@locator)
|
||||
if xpath.respond_to?(:to_xpaths)
|
||||
@xpaths = xpath.to_xpaths
|
||||
else
|
||||
@xpaths = [xpath.to_s].flatten
|
||||
end
|
||||
end
|
||||
|
||||
def failure_message(node)
|
||||
message = selector.failure_message.call(node, self) if selector.failure_message
|
||||
message ||= options[:message]
|
||||
message ||= "Unable to find #{name} #{locator.inspect}"
|
||||
message
|
||||
end
|
||||
|
||||
def name; selector.name; end
|
||||
|
||||
def matches_filters?(node)
|
||||
return false if options[:text] and not node.text.match(options[:text])
|
||||
return false if options[:visible] and not node.visible?
|
||||
selector.custom_filters.each do |name, block|
|
||||
return false if options.has_key?(name) and not block.call(node, options[name])
|
||||
end
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
|
@ -2,53 +2,6 @@ module Capybara
|
|||
class Selector
|
||||
attr_reader :name, :custom_filters
|
||||
|
||||
class Normalized
|
||||
attr_accessor :selector, :locator, :options, :xpaths
|
||||
|
||||
def initialize(*args)
|
||||
@options = if args.last.is_a?(Hash) then args.pop.dup else {} end
|
||||
if text = options[:text]
|
||||
@options[:text] = Regexp.escape(text) unless text.kind_of?(Regexp)
|
||||
end
|
||||
unless options.has_key?(:visible)
|
||||
@options[:visible] = Capybara.ignore_hidden_elements
|
||||
end
|
||||
|
||||
if args[1]
|
||||
@selector = Selector.all[args[0]]
|
||||
@locator = args[1]
|
||||
else
|
||||
@selector = Selector.all.values.find { |s| s.match?(args[0]) }
|
||||
@locator = args[0]
|
||||
end
|
||||
@selector ||= Selector.all[Capybara.default_selector]
|
||||
|
||||
xpath = @selector.call(@locator)
|
||||
if xpath.respond_to?(:to_xpaths)
|
||||
@xpaths = xpath.to_xpaths
|
||||
else
|
||||
@xpaths = [xpath.to_s].flatten
|
||||
end
|
||||
end
|
||||
|
||||
def failure_message(node)
|
||||
message = selector.failure_message.call(node, self) if selector.failure_message
|
||||
message ||= options[:message]
|
||||
message ||= "Unable to find #{name} #{locator.inspect}"
|
||||
message
|
||||
end
|
||||
|
||||
def name; selector.name; end
|
||||
|
||||
def matches_filters?(node)
|
||||
return false if options[:text] and not node.text.match(options[:text])
|
||||
return false if options[:visible] and not node.visible?
|
||||
selector.custom_filters.each do |name, block|
|
||||
return false if options.has_key?(name) and not block.call(node, options[name])
|
||||
end
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
class << self
|
||||
def all
|
||||
|
@ -62,10 +15,6 @@ module Capybara
|
|||
def remove(name)
|
||||
all.delete(name.to_sym)
|
||||
end
|
||||
|
||||
def normalize(*args)
|
||||
Normalized.new(*args)
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(name, &block)
|
||||
|
|
Loading…
Add table
Reference in a new issue