This commit is contained in:
Thomas Walpole 2017-05-01 18:39:08 -07:00
parent 0399ec37ee
commit efe48bb685
10 changed files with 66 additions and 65 deletions

View File

@ -37,7 +37,8 @@ module Capybara
# The block returned receives a rack app, port, and host/ip and should run a Rack handler
# By default, Capybara will try to run webrick.
#
def server(&block)
def server
raise ArgumentError, "Capybara#server no longer accepts a block" if block_given?
@server
end

View File

@ -224,15 +224,15 @@ module Capybara
# @option options [true, Hash] make_visible A Hash of CSS styles to change before attempting to attach the file, if `true` { opacity: 1, display: 'block', visibility: 'visible' } is used (may not be supported by all drivers)
#
# @return [Capybara::Node::Element] The file field element
def attach_file(locator=nil, path, style: nil, **options)
def attach_file(locator=nil, path, make_visible: nil, **options)
Array(path).each do |p|
raise Capybara::FileNotFound, "cannot attach file, #{p} does not exist" unless File.exist?(p.to_s)
end
# Allow user to update the CSS style of the file input since they are so often hidden on a page
if style = options.delete(:make_visible)
style = { opacity: 1, display: 'block', visibility: 'visible' } if style == true
if make_visible
make_visible = { opacity: 1, display: 'block', visibility: 'visible' } if make_visible == true
ff = find(:file_field, locator, options.merge({visible: :all}))
_update_style(ff, style)
_update_style(ff, make_visible)
if ff.visible?
begin
ff.set(path)

View File

@ -253,12 +253,9 @@ module Capybara
# @yieldreturn [Boolean] Should the element be considered in the results?
# @return [Capybara::Result] A collection of found elements
#
def all(*args, &optional_filter_block)
if args.last.is_a? Hash
args.last[:session_options] = session_options
else
args.push(session_options: session_options)
end
def all(*args, **options, &optional_filter_block)
options[:session_options] = session_options
args.push(options)
query = Capybara::Queries::SelectorQuery.new(*args, &optional_filter_block)
synchronize(query.wait) do
result = query.resolve_for(self)

View File

@ -14,7 +14,6 @@ module Capybara
@expected_text = Capybara::Helpers.normalize_whitespace(@expected_text)
end
@search_regexp = Capybara::Helpers.to_regexp(@expected_text, nil, exact?)
warn "Unused parameters passed to #{self.class.name} : #{args}" unless args.empty?
assert_valid_keys
end

View File

@ -17,7 +17,7 @@ class Capybara::RackTest::Browser
driver.options
end
def visit(path, attributes = {})
def visit(path, **attributes)
reset_host!
process_and_follow_redirects(:get, path, attributes)
end
@ -32,7 +32,7 @@ class Capybara::RackTest::Browser
process_and_follow_redirects(method, path, attributes, {'HTTP_REFERER' => current_url})
end
def follow(method, path, attributes = {})
def follow(method, path, **attributes)
return if path.gsub(/^#{Regexp.escape(request_path)}/, '').start_with?('#') || path.downcase.start_with?('javascript:')
process_and_follow_redirects(method, path, attributes, {'HTTP_REFERER' => current_url})
end

View File

@ -40,7 +40,7 @@ class Capybara::RackTest::Driver < Capybara::Driver::Base
browser.last_request
end
def visit(path, attributes = {})
def visit(path, **attributes)
browser.visit(path, attributes)
end
@ -52,7 +52,7 @@ class Capybara::RackTest::Driver < Capybara::Driver::Base
browser.submit(method, path, attributes)
end
def follow(method, path, attributes = {})
def follow(method, path, **attributes)
browser.follow(method, path, attributes)
end

View File

@ -9,15 +9,15 @@ Capybara::Selector::FilterSet.add(:_field) do
expression_filter(:name) { |xpath, val| xpath[XPath.attr(:name).equals(val)] }
expression_filter(:placeholder) { |xpath, val| xpath[XPath.attr(:placeholder).equals(val)] }
describe do |options|
describe do |checked: nil, unchecked: nil, disabled: nil, multiple: nil, **options|
desc, states = String.new, []
states << 'checked' if options[:checked] || (options[:unchecked] == false)
states << 'not checked' if options[:unchecked] || (options[:checked] == false)
states << 'disabled' if options[:disabled] == true
states << 'not disabled' if options[:disabled] == false
states << 'checked' if checked || (unchecked == false)
states << 'not checked' if unchecked || (checked == false)
states << 'disabled' if disabled == true
states << 'not disabled' if disabled == false
desc << " that is #{states.join(' and ')}" unless states.empty?
desc << " with the multiple attribute" if options[:multiple] == true
desc << " without the multiple attribute" if options[:multiple] == false
desc << " with the multiple attribute" if multiple == true
desc << " without the multiple attribute" if multiple == false
desc
end
end
@ -89,10 +89,10 @@ Capybara.add_selector(:field) do
filter(:with) do |node, with|
with.is_a?(Regexp) ? node.value =~ with : node.value == with.to_s
end
describe do |options|
describe do |type: nil, **options|
desc = String.new
(expression_filters.keys - [:type]).each { |ef| desc << " with #{ef} #{options[ef]}" if options.has_key?(ef) }
desc << " of type #{options[:type].inspect}" if options[:type]
desc << " of type #{type.inspect}" if type
desc << " with value #{options[:with].to_s.inspect}" if options.has_key?(:with)
desc
end
@ -130,7 +130,7 @@ end
# @filter [String, Regexp,nil] :href Matches the normalized href of the link, if nil will find <a> elements with no href attribute
#
Capybara.add_selector(:link) do
xpath(:title, :alt) do |locator, href: true, **options|
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)]
@ -143,11 +143,11 @@ Capybara.add_selector(:link) do
XPath.string.n.is(locator)).or(
XPath.attr(:title).is(locator)).or(
XPath.descendant(:img)[XPath.attr(:alt).is(locator)])
matchers = matchers.or XPath.attr(:'aria-label').is(locator) if options[:enable_aria_label]
matchers = matchers.or XPath.attr(:'aria-label').is(locator) if enable_aria_label
xpath = xpath[matchers]
end
xpath = [:title].inject(xpath) { |memo, ef| memo[find_by_attr(ef, options[ef])] }
xpath = xpath[XPath.descendant(:img)[XPath.attr(:alt).equals(options[:alt])]] if options[:alt]
xpath = xpath[find_by_attr(:title, title)]
xpath = xpath[XPath.descendant(:img)[XPath.attr(:alt).equals(alt)]] if alt
xpath
end
@ -162,7 +162,7 @@ Capybara.add_selector(:link) do
end
end
describe do |options|
describe do |**options|
desc = String.new()
desc << " with href #{options[:href].inspect}" if options[:href]
desc << " with no href attribute" if options.fetch(:href, true).nil?
@ -209,9 +209,9 @@ Capybara.add_selector(:button) do
filter(:disabled, :boolean, default: false, skip_if: :all) { |node, value| not(value ^ node.disabled?) }
describe do |options|
describe do |disabled: nil, **options|
desc = String.new
desc << " that is disabled" if options[:disabled] == true
desc << " that is disabled" if disabled == true
desc << describe_all_expression_filters(options)
desc
end
@ -223,13 +223,13 @@ end
#
Capybara.add_selector(:link_or_button) do
label "link or button"
xpath do |locator, options|
xpath do |locator, **options|
self.class.all.values_at(:link, :button).map {|selector| selector.xpath.call(locator, options)}.reduce(:union)
end
filter(:disabled, :boolean, default: false, skip_if: :all) { |node, value| node.tag_name == "a" or not(value ^ node.disabled?) }
describe { |options| " that is disabled" if options[:disabled] }
describe { |disabled: nil, **options| " that is disabled" if disabled == true }
end
##
@ -248,7 +248,8 @@ end
#
Capybara.add_selector(:fillable_field) do
label "field"
xpath do |locator, options|
xpath do |locator, **options|
xpath = XPath.descendant(:input, :textarea)[~XPath.attr(:type).one_of('submit', 'image', 'radio', 'checkbox', 'hidden', 'file')]
locate_field(xpath, locator, options)
end
@ -291,7 +292,8 @@ end
#
Capybara.add_selector(:radio_button) do
label "radio button"
xpath do |locator, options|
xpath do |locator, **options|
xpath = XPath.descendant(:input)[XPath.attr(:type).equals('radio')]
locate_field(xpath, locator, options)
end
@ -300,9 +302,9 @@ Capybara.add_selector(:radio_button) do
filter(:option) { |node, value| node.value == value.to_s }
describe do |options|
describe do |option: option, **options|
desc = String.new
desc << " with value #{options[:option].inspect}" if options[:option]
desc << " with value #{option.inspect}" if option
desc << describe_all_expression_filters(options)
desc
end
@ -322,7 +324,8 @@ end
# @filter [String] :option Match the value
#
Capybara.add_selector(:checkbox) do
xpath do |locator, options|
xpath do |locator, **options|
xpath = XPath.descendant(:input)[XPath.attr(:type).equals('checkbox')]
locate_field(xpath, locator, options)
end
@ -331,9 +334,9 @@ Capybara.add_selector(:checkbox) do
filter(:option) { |node, value| node.value == value.to_s }
describe do |options|
describe do |option: nil, **options|
desc = String.new
desc << " with value #{options[:option].inspect}" if options[:option]
desc << " with value #{option.inspect}" if option
desc << describe_all_expression_filters(options)
desc
end
@ -357,7 +360,8 @@ end
#
Capybara.add_selector(:select) do
label "select box"
xpath do |locator, options|
xpath do |locator, **options|
xpath = XPath.descendant(:select)
locate_field(xpath, locator, options)
end
@ -391,13 +395,13 @@ Capybara.add_selector(:select) do
(Array(selected) - actual).empty?
end
describe do |options|
describe do |options: nil, with_options: nil, selected: nil, with_selected: nil, **opts|
desc = String.new
desc << " with options #{options[:options].inspect}" if options[:options]
desc << " with at least options #{options[:with_options].inspect}" if options[:with_options]
desc << " with #{options[:selected].inspect} selected" if options[:selected]
desc << " with at least #{options[:with_selected].inspect} selected" if options[:with_selected]
desc << describe_all_expression_filters(options)
desc << " with options #{options.inspect}" if options
desc << " with at least options #{with_options.inspect}" if with_options
desc << " with #{selected.inspect} selected" if selected
desc << " with at least #{with_selected.inspect} selected" if with_selected
desc << describe_all_expression_filters(opts)
desc
end
end
@ -420,7 +424,7 @@ Capybara.add_selector(:option) do
filter(:disabled, :boolean) { |node, value| not(value ^ node.disabled?) }
filter(:selected, :boolean) { |node, value| not(value ^ node.selected?) }
describe do |options|
describe do |**options|
desc = String.new
desc << " that is#{' not' unless options[:disabled]} disabled" if options.has_key?(:disabled)
desc << " that is#{' not' unless options[:selected]} selected" if options.has_key?(:selected)
@ -448,7 +452,7 @@ Capybara.add_selector(:file_field) do
filter_set(:_field, [:disabled, :multiple, :name])
describe do |options|
describe do |**options|
desc = String.new
desc << describe_all_expression_filters(options)
desc
@ -486,7 +490,7 @@ Capybara.add_selector(:label) do
end
end
describe do |options|
describe do |**options|
desc = String.new
desc << " for #{options[:for]}" if options[:for]
desc
@ -510,9 +514,9 @@ Capybara.add_selector(:table) do
xpath
end
describe do |options|
describe do |caption: nil, **options|
desc = String.new
desc << " with caption #{options[:caption]}" if options[:caption]
desc << " with caption #{caption}" if caption
desc
end
end
@ -527,16 +531,16 @@ end
# @filter [String, Array<String>] :class Matches the class(es) provided
#
Capybara.add_selector(:frame) do
xpath(:name) do |locator, options|
xpath(:name) do |locator, **options|
xpath = XPath.descendant(:iframe).union(XPath.descendant(:frame))
xpath = xpath[XPath.attr(:id).equals(locator.to_s).or XPath.attr(:name).equals(locator)] unless locator.nil?
xpath = expression_filters.keys.inject(xpath) { |memo, ef| memo[find_by_attr(ef, options[ef])] }
xpath
end
describe do |options|
describe do |name: nil, **options|
desc = String.new
desc << " with name #{options[:name]}" if options[:name]
desc << " with name #{name}" if name
desc
end
end

View File

@ -233,7 +233,7 @@ module Capybara
custom_filters[name] = filter_class.new(name, block, options)
end
def locate_field(xpath, locator, **options)
def locate_field(xpath, locator, enable_aria_label: false, **options)
locate_xpath = xpath #need to save original xpath for the label wrap
if locator
locator = locator.to_s
@ -241,7 +241,7 @@ module Capybara
XPath.attr(:name).equals(locator)).or(
XPath.attr(:placeholder).equals(locator)).or(
XPath.attr(:id).equals(XPath.anywhere(:label)[XPath.string.n.is(locator)].attr(:for)))
attr_matchers = attr_matchers.or XPath.attr(:'aria-label').is(locator) if options[:enable_aria_label]
attr_matchers = attr_matchers.or XPath.attr(:'aria-label').is(locator) if enable_aria_label
locate_xpath = locate_xpath[attr_matchers]
locate_xpath = locate_xpath.union(XPath.descendant(:label)[XPath.string.n.is(locator)].descendant(xpath))
@ -251,7 +251,7 @@ module Capybara
locate_xpath
end
def describe_all_expression_filters(opts={})
def describe_all_expression_filters(**opts)
expression_filters.map { |ef| " with #{ef} #{opts[ef]}" if opts.has_key?(ef) }.join
end

View File

@ -224,18 +224,18 @@ private
find_xpath('./ancestor::select[1]').first
end
def set_text(value, options)
def set_text(value, clear: nil, **)
if value.to_s.empty? && options[:clear].nil?
native.clear
else
if options[:clear] == :backspace
if clear == :backspace
# Clear field by sending the correct number of backspace keys.
backspaces = [:backspace] * self.value.to_s.length
native.send_keys(*(backspaces + [value.to_s]))
elsif options[:clear] == :none
elsif clear == :none
native.send_keys(value.to_s)
elsif options[:clear].is_a? Array
native.send_keys(*options[:clear], value.to_s)
elsif clear.is_a? Array
native.send_keys(*clear, value.to_s)
else
# Clear field by JavaScript assignment of the value property.
# Script can change a readonly element which user input cannot, so

View File

@ -566,7 +566,7 @@ module Capybara
# @raise [Capybara::WindowError] if block passed to window hasn't opened window
# or opened more than one window
#
def window_opened_by(options = {}, &block)
def window_opened_by(**options, &block)
old_handles = driver.window_handles
block.call