update
This commit is contained in:
parent
0399ec37ee
commit
efe48bb685
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue