Skip to content

Commit

Permalink
Split selector definition and configured selector
Browse files Browse the repository at this point in the history
  • Loading branch information
twalpole committed Apr 22, 2019
1 parent eca6ad4 commit 12efb5f
Show file tree
Hide file tree
Showing 11 changed files with 391 additions and 300 deletions.
40 changes: 30 additions & 10 deletions lib/capybara/queries/selector_query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ def initialize(*args,
session_options:,
enable_aria_label: session_options.enable_aria_label,
test_id: session_options.test_id,
# selector_format: nil,
**options,
&filter_block)
@resolved_node = nil
Expand All @@ -19,14 +20,17 @@ def initialize(*args,
super(@options)
self.session_options = session_options

@selector = find_selector(args[0].is_a?(Symbol) ? args.shift : args[0])
@selector = Selector.new(
find_selector(args[0].is_a?(Symbol) ? args.shift : args[0]),
config: { enable_aria_label: enable_aria_label, test_id: test_id }
)

@locator = args.shift
@filter_block = filter_block

raise ArgumentError, "Unused parameters passed to #{self.class.name} : #{args}" unless args.empty?

selector_config = { enable_aria_label: enable_aria_label, test_id: test_id }
@expression = selector.call(@locator, @options.merge(selector_config: selector_config))
@expression = selector.call(@locator, @options)

warn_exact_usage

Expand Down Expand Up @@ -129,7 +133,9 @@ def resolve_for(node, exact = nil)

# @api private
def supports_exact?
@expression.respond_to? :to_xpath
return @expression.respond_to? :to_xpath if @selector.supports_exact?.nil?

@selector.supports_exact?
end

def failure_message
Expand All @@ -142,6 +148,10 @@ def negative_failure_message

private

def selector_format
@selector.format
end

def text_fragments
text = (options[:text] || options[:exact_text])
text.is_a?(String) ? text.split : []
Expand Down Expand Up @@ -192,23 +202,23 @@ def find_selector(locator)
def find_nodes_by_selector_format(node, exact)
hints = {}
hints[:uses_visibility] = true unless visible == :all
hints[:texts] = text_fragments unless selector.format == :xpath
hints[:texts] = text_fragments unless selector_format == :xpath
hints[:styles] = options[:style] if use_default_style_filter?

if selector.format == :css
if selector_format == :css
if node.method(:find_css).arity != 1
node.find_css(css, **hints)
else
node.find_css(css)
end
elsif selector.format == :xpath
elsif selector_format == :xpath
if node.method(:find_xpath).arity != 1
node.find_xpath(xpath(exact), **hints)
else
node.find_xpath(xpath(exact))
end
else
raise ArgumentError, "Unknown format: #{selector.format}"
raise ArgumentError, "Unknown format: #{selector_format}"
end
end

Expand All @@ -230,6 +240,8 @@ def matches_node_filters?(node, errors)
unapplied_options = options.keys - valid_keys
@selector.with_filter_errors(errors) do
node_filters.all? do |filter_name, filter|
next true unless apply_filter?(filter)

if filter.matcher?
unapplied_options.select { |option_name| filter.handles_option?(option_name) }.all? do |option_name|
unapplied_options.delete(option_name)
Expand Down Expand Up @@ -320,6 +332,8 @@ def use_default_style_filter?
def apply_expression_filters(expression)
unapplied_options = options.keys - valid_keys
expression_filters.inject(expression) do |expr, (name, ef)|
next expr unless apply_filter?(ef)

if ef.matcher?
unapplied_options.select(&ef.method(:handles_option?)).inject(expr) do |memo, option_name|
unapplied_options.delete(option_name)
Expand Down Expand Up @@ -358,10 +372,16 @@ def simple_root?(node)
node.is_a?(::Capybara::Node::Simple) && node.path == '/'
end

def apply_filter?(filter)
require 'byebug'
byebug unless filter.format.nil?
filter.format.nil? || (filter.format == selector_format)
end

def matches_locator_filter?(node)
return true unless @selector.locator_filter
return true unless @selector.locator_filter && apply_filter?(@selector.locator_filter)

@selector.locator_filter.matches?(node, @locator, @selector)
@selector.locator_filter.matches?(node, @locator, @selector, exact: exact?)
end

def matches_system_filters?(node)
Expand Down
10 changes: 6 additions & 4 deletions lib/capybara/selector.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@

Capybara.add_selector(:field, locator_type: [String, Symbol]) do
visible { |options| :hidden if options[:type].to_s == 'hidden' }

xpath do |locator, **options|
invalid_types = %w[submit image]
invalid_types << 'hidden' unless options[:type].to_s == 'hidden'
Expand All @@ -69,6 +70,7 @@
filter_set(:_field) # checked/unchecked/disabled/multiple/name/placeholder

node_filter(:readonly, :boolean) { |node, value| !(value ^ node.readonly?) }

node_filter(:with) do |node, with|
val = node.value
(with.is_a?(Regexp) ? with.match?(val) : val == with.to_s).tap do |res|
Expand Down Expand Up @@ -185,8 +187,8 @@
Capybara.add_selector(:link_or_button, locator_type: [String, Symbol]) do
label 'link or button'
xpath do |locator, **options|
self.class.all.values_at(:link, :button).map do |selector|
instance_exec(locator, options, &selector.xpath)
%i[link button].map do |selector|
expression_for(selector, locator, **options)
end.reduce(:union)
end

Expand Down Expand Up @@ -297,7 +299,7 @@

expression_filter(:with_options) do |expr, options|
options.inject(expr) do |xpath, option|
xpath[self.class.all[:option].call(option)]
xpath[expression_for(:option, option)]
end
end

Expand Down Expand Up @@ -350,7 +352,7 @@

expression_filter(:with_options) do |expr, options|
options.inject(expr) do |xpath, option|
xpath[XPath.attr(:list) == XPath.anywhere(:datalist)[self.class.all[:datalist_option].call(option)].attr(:id)]
xpath[XPath.attr(:list) == XPath.anywhere(:datalist)[expression_for(:datalist_option, option)].attr(:id)]
end
end

Expand Down
2 changes: 2 additions & 0 deletions lib/capybara/selector/css.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require 'capybara/selector/selector'

module Capybara
class Selector
class CSS
Expand Down
Loading

0 comments on commit 12efb5f

Please sign in to comment.