reduce unnecessary wirecalls

This commit is contained in:
Thomas Walpole 2018-05-08 16:44:57 -07:00
parent 170bc99d68
commit 8e2e291ced
3 changed files with 35 additions and 20 deletions

View File

@ -136,11 +136,19 @@ end
Capybara.add_selector(:link) do
xpath(:title, :alt) do |locator, href: true, enable_aria_label: false, alt: nil, title: nil, **_options|
xpath = XPath.descendant(:a)
xpath = if href.nil?
xpath[!XPath.attr(:href)]
xpath = xpath[
case href
when nil, false
!XPath.attr(:href)
when true
XPath.attr(:href)
when Regexp
nil # needs to be handled in filter
else
xpath[XPath.attr(:href)]
XPath.attr(:href) == href.to_s
end
]
unless locator.nil?
locator = locator.to_s
matchers = [XPath.attr(:id) == locator,
@ -150,20 +158,15 @@ Capybara.add_selector(:link) do
matchers |= XPath.attr(:'aria-label').is(locator) if enable_aria_label
xpath = xpath[matchers]
end
xpath = xpath[find_by_attr(:title, title)]
xpath = xpath[XPath.descendant(:img)[XPath.attr(:alt) == alt]] if alt
xpath
end
filter(:href) do |node, href|
case href
when nil
true
when Regexp
node[:href].match href
else
node.first(:xpath, XPath.self[XPath.attr(:href) == href.to_s], minimum: 0)
end
# If not a Regexp it's been handled in the main XPath
href.is_a?(Regexp) ? node[:href].match(href) : true
end
describe do |**options|
@ -380,10 +383,11 @@ Capybara.add_selector(:select) do
options.sort == actual.sort
end
filter(:with_options) do |node, options|
finder_settings = { minimum: 0 }
finder_settings[:visible] = false unless node.visible?
options.all? { |option| node.first(:option, option, finder_settings) }
expression_filter(:with_options) do |expr, options|
options.each do |option|
expr = expr[Capybara::Selector.all[:option].call(option)]
end
expr
end
filter(:selected) do |node, selected|
@ -422,8 +426,11 @@ Capybara.add_selector(:datalist_input) do
options.sort == actual.sort
end
filter(:with_options) do |node, options|
options.all? { |option| node.find("//datalist[@id=#{node[:list]}]", visible: :all).first(:datalist_option, option) }
expression_filter(:with_options) do |expr, options|
options.each do |option|
expr = expr[XPath.attr(:list) == XPath.anywhere(:datalist)[Capybara::Selector.all[:datalist_option].call(option)].attr(:id)]
end
expr
end
describe do |options: nil, with_options: nil, **opts|

View File

@ -199,7 +199,7 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
parent = path.first
selector = node.tag_name
if parent
siblings = parent.find_xpath(node.tag_name)
siblings = parent.find_xpath(selector)
selector += "[#{siblings.index(node) + 1}]" unless siblings.size == 1
end
result.push selector

View File

@ -100,6 +100,14 @@ Capybara::SpecHelper.spec '#has_selector?' do
end
end
end
context "datalist" do
it "should match options" do
@session.visit('/form')
expect(@session).to have_selector(:datalist_input, with_options: %w[Jaguar Audi Mercedes])
expect(@session).not_to have_selector(:datalist_input, with_options: %w[Ford Chevy])
end
end
end
Capybara::SpecHelper.spec '#has_no_selector?' do