class Capybara::Queries::SelectorQuery
Constants
- VALID_KEYS
- VALID_MATCH
Attributes
expression[RW]
find[RW]
locator[RW]
negative[RW]
options[RW]
selector[RW]
Public Class Methods
new(*args, &filter_block)
click to toggle source
Calls superclass method
Capybara::Queries::BaseQuery.new
# File lib/capybara/queries/selector_query.rb, line 9 def initialize(*args, &filter_block) @options = if args.last.is_a?(Hash) then args.pop.dup else {} end super(@options) @filter_block = filter_block if args[0].is_a?(Symbol) @selector = Selector.all.fetch(args.shift) do |selector_type| raise ArgumentError, "Unknown selector type (:#{selector_type})" nil end @locator = args.shift else @selector = Selector.all.values.find { |s| s.match?(args[0]) } @locator = args.shift end @selector ||= Selector.all[session_options.default_selector] warn "Unused parameters passed to #{self.class.name} : #{args.to_s}" unless args.empty? # for compatibility with Capybara 2.0 if session_options.exact_options and @selector == Selector.all[:option] @options[:exact] = true end @expression = @selector.call(@locator, @options.merge(enable_aria_label: session_options.enable_aria_label)) warn_exact_usage assert_valid_keys end
Public Instance Methods
css()
click to toggle source
# File lib/capybara/queries/selector_query.rb, line 133 def css filtered_css(apply_expression_filters(@expression)) end
description()
click to toggle source
# File lib/capybara/queries/selector_query.rb, line 44 def description @description = String.new("#{label} #{locator.inspect}") @description << " with#{" exact" if exact_text == true} text #{options[:text].inspect}" if options[:text] @description << " with exact text #{options[:exact_text]}" if options[:exact_text].is_a?(String) @description << " with id #{options[:id]}" if options[:id] @description << " with classes [#{Array(options[:class]).join(',')}]" if options[:class] @description << selector.description(options) @description << " that also matches the custom filter block" if @filter_block @description end
exact?()
click to toggle source
# File lib/capybara/queries/selector_query.rb, line 113 def exact? return false if !supports_exact? options.fetch(:exact, session_options.exact) end
label()
click to toggle source
# File lib/capybara/queries/selector_query.rb, line 42 def label; selector.label or selector.name; end
match()
click to toggle source
# File lib/capybara/queries/selector_query.rb, line 118 def match options.fetch(:match, session_options.match) end
matches_filters?(node)
click to toggle source
# File lib/capybara/queries/selector_query.rb, line 55 def matches_filters?(node) if options[:text] regexp = if options[:text].is_a?(Regexp) options[:text] else if exact_text == true /\A#{Regexp.escape(options[:text].to_s)}\z/ else Regexp.escape(options[:text].to_s) end end text_visible = visible text_visible = :all if text_visible == :hidden return false if not node.text(text_visible).match(regexp) end if exact_text.is_a?(String) regexp = /\A#{Regexp.escape(options[:exact_text])}\z/ text_visible = visible text_visible = :all if text_visible == :hidden return false if not node.text(text_visible).match(regexp) end case visible when :visible then return false unless node.visible? when :hidden then return false if node.visible? end res = node_filters.all? do |name, filter| if options.has_key?(name) filter.matches?(node, options[name]) elsif filter.default? filter.matches?(node, filter.default) else true end end res &&= if node.respond_to?(:session) node.session.using_wait_time(0){ @filter_block.call(node) } else @filter_block.call(node) end unless @filter_block.nil? res rescue *(node.respond_to?(:session) ? node.session.driver.invalid_element_errors : []) return false end
name()
click to toggle source
# File lib/capybara/queries/selector_query.rb, line 41 def name; selector.name; end
resolve_for(node, exact = nil)
click to toggle source
@api private
# File lib/capybara/queries/selector_query.rb, line 138 def resolve_for(node, exact = nil) node.synchronize do children = if selector.format == :css node.find_css(self.css) else node.find_xpath(self.xpath(exact)) end.map do |child| if node.is_a?(Capybara::Node::Base) Capybara::Node::Element.new(node.session, child, node, self) else Capybara::Node::Simple.new(child) end end Capybara::Result.new(children, self) end end
supports_exact?()
click to toggle source
@api private
# File lib/capybara/queries/selector_query.rb, line 156 def supports_exact? @expression.respond_to? :to_xpath end
visible()
click to toggle source
# File lib/capybara/queries/selector_query.rb, line 105 def visible case (vis = options.fetch(:visible){ @selector.default_visibility(session_options.ignore_hidden_elements) }) when true then :visible when false then :all else vis end end
xpath(exact=nil)
click to toggle source
# File lib/capybara/queries/selector_query.rb, line 122 def xpath(exact=nil) exact = self.exact? if exact.nil? expr = apply_expression_filters(@expression) expr = if expr.respond_to?(:to_xpath) and exact expr.to_xpath(:exact) else expr.to_s end filtered_xpath(expr) end
Private Instance Methods
apply_expression_filters(expr)
click to toggle source
# File lib/capybara/queries/selector_query.rb, line 217 def apply_expression_filters(expr) expression_filters.inject(expr) do |memo, (name, ef)| if options.has_key?(name) ef.apply_filter(memo, options[name]) elsif ef.default? ef.apply_filter(memo, ef.default) else memo end end end
assert_valid_keys()
click to toggle source
Calls superclass method
Capybara::Queries::BaseQuery#assert_valid_keys
# File lib/capybara/queries/selector_query.rb, line 184 def assert_valid_keys super unless VALID_MATCH.include?(match) raise ArgumentError, "invalid option #{match.inspect} for :match, should be one of #{VALID_MATCH.map(&:inspect).join(", ")}" end end
custom_keys()
click to toggle source
# File lib/capybara/queries/selector_query.rb, line 180 def custom_keys @custom_keys ||= node_filters.keys + expression_filters.keys end
exact_text()
click to toggle source
# File lib/capybara/queries/selector_query.rb, line 235 def exact_text options.fetch(:exact_text, session_options.exact_text) end
expression_filters()
click to toggle source
# File lib/capybara/queries/selector_query.rb, line 174 def expression_filters filters = @selector.expression_filters filters.merge ::Capybara::Selector::FilterSet.all[options[:filter_set]].expression_filters if options.has_key?(:filter_set) filters end
filtered_css(expr)
click to toggle source
# File lib/capybara/queries/selector_query.rb, line 205 def filtered_css(expr) if options.has_key?(:id) || options.has_key?(:class) css_selectors = expr.split(',').map(&:rstrip) expr = css_selectors.map do |sel| sel += "##{Capybara::Selector::CSS.escape(options[:id])}" if options.has_key?(:id) && !custom_keys.include?(:id) sel += Array(options[:class]).map { |k| ".#{Capybara::Selector::CSS.escape(k)}"}.join if options.has_key?(:class) && !custom_keys.include?(:class) sel end.join(", ") end expr end
filtered_xpath(expr)
click to toggle source
# File lib/capybara/queries/selector_query.rb, line 191 def filtered_xpath(expr) if options.has_key?(:id) || options.has_key?(:class) expr = "(#{expr})" expr = "#{expr}[#{XPath.attr(:id) == options[:id]}]" if options.has_key?(:id) && !custom_keys.include?(:id) if options.has_key?(:class) && !custom_keys.include?(:class) class_xpath = Array(options[:class]).map do |klass| "contains(concat(' ',normalize-space(@class),' '),' #{klass} ')" end.join(" and ") expr = "#{expr}[#{class_xpath}]" end end expr end
node_filters()
click to toggle source
# File lib/capybara/queries/selector_query.rb, line 166 def node_filters if options.has_key?(:filter_set) ::Capybara::Selector::FilterSet.all[options[:filter_set]].node_filters else @selector.node_filters end end
valid_keys()
click to toggle source
# File lib/capybara/queries/selector_query.rb, line 162 def valid_keys VALID_KEYS + custom_keys end
warn_exact_usage()
click to toggle source
# File lib/capybara/queries/selector_query.rb, line 229 def warn_exact_usage if options.has_key?(:exact) && !supports_exact? warn "The :exact option only has an effect on queries using the XPath#is method. Using it with the query \"#{expression.to_s}\" has no effect." end end