rubocop driven style cleanup
This commit is contained in:
parent
5233962c7c
commit
24eb7a0702
1136
.rubocop.yml
1136
.rubocop.yml
File diff suppressed because it is too large
Load Diff
4
Gemfile
4
Gemfile
|
@ -3,8 +3,8 @@ source 'https://rubygems.org'
|
|||
gem 'bundler', '~> 1.1'
|
||||
gemspec
|
||||
|
||||
gem 'xpath', :git => 'git://github.com/teamcapybara/xpath.git'
|
||||
gem 'xpath', git: 'git://github.com/teamcapybara/xpath.git'
|
||||
|
||||
group :doc do
|
||||
gem 'redcarpet', :platforms => :mri
|
||||
gem 'redcarpet', platforms: :mri
|
||||
end
|
||||
|
|
6
Rakefile
6
Rakefile
|
@ -20,11 +20,11 @@ RSpec::Core::RakeTask.new(:spec_rack) do |t|
|
|||
t.pattern = './spec{,/*/**}/*{_spec.rb}'
|
||||
end
|
||||
|
||||
task :spec => [:spec_marionette]
|
||||
task spec: [:spec_marionette]
|
||||
|
||||
YARD::Rake::YardocTask.new do |t|
|
||||
t.files = ['lib/**/*.rb']
|
||||
t.options = %w(--markup=markdown)
|
||||
t.options = %w[--markup=markdown]
|
||||
end
|
||||
|
||||
Cucumber::Rake::Task.new(:cucumber) do |task|
|
||||
|
@ -52,4 +52,4 @@ task :release do
|
|||
'git push --tags'
|
||||
end
|
||||
|
||||
task :default => %i[spec cucumber]
|
||||
task default: %i[spec cucumber]
|
||||
|
|
|
@ -21,6 +21,5 @@ When(/^I use a matcher that fails$/) do
|
|||
end
|
||||
|
||||
Then(/^the failing exception should be nice$/) do
|
||||
expect(@error_message).to match %r(expected to find visible css \"h1#doesnotexist\")
|
||||
expect(@error_message).to match %r{expected to find visible css \"h1#doesnotexist\"}
|
||||
end
|
||||
|
||||
|
|
|
@ -20,4 +20,3 @@ Capybara.javascript_driver = :javascript_test
|
|||
Capybara.register_driver :named_test do |app|
|
||||
Capybara::RackTest::Driver.new(app)
|
||||
end
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@ module Capybara
|
|||
class WindowError < CapybaraError; end
|
||||
class ReadOnlyElementError < CapybaraError; end
|
||||
|
||||
|
||||
class << self
|
||||
extend Forwardable
|
||||
|
||||
|
@ -305,7 +304,7 @@ module Capybara
|
|||
# as cookies.
|
||||
#
|
||||
def reset_sessions!
|
||||
#reset in reverse so sessions that started servers are reset last
|
||||
# reset in reverse so sessions that started servers are reset last
|
||||
session_pool.reverse_each { |_mode, session| session.reset! }
|
||||
end
|
||||
alias_method :reset!, :reset_sessions!
|
||||
|
@ -359,10 +358,10 @@ module Capybara
|
|||
# @param [String] html The raw html
|
||||
# @return [Nokogiri::HTML::Document] HTML document
|
||||
#
|
||||
def HTML(html)
|
||||
def HTML(html) # rubocop:disable Naming/MethodName
|
||||
Nokogiri::HTML(html).tap do |document|
|
||||
document.xpath('//textarea').each do |textarea|
|
||||
textarea['_capybara_raw_value'] = textarea.content.sub(/\A\n/,'')
|
||||
textarea['_capybara_raw_value'] = textarea.content.sub(/\A\n/, '')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -377,6 +376,7 @@ module Capybara
|
|||
end
|
||||
|
||||
private
|
||||
|
||||
def config
|
||||
@config ||= Capybara::Config.new
|
||||
end
|
||||
|
@ -439,12 +439,12 @@ end
|
|||
|
||||
Capybara.register_server :webrick do |app, port, host, **options|
|
||||
require 'rack/handler/webrick'
|
||||
Rack::Handler::WEBrick.run(app, {Host: host, Port: port, AccessLog: [], Logger: WEBrick::Log::new(nil, 0)}.merge(options))
|
||||
Rack::Handler::WEBrick.run(app, { Host: host, Port: port, AccessLog: [], Logger: WEBrick::Log.new(nil, 0) }.merge(options))
|
||||
end
|
||||
|
||||
Capybara.register_server :puma do |app, port, host, **options|
|
||||
require 'rack/handler/puma'
|
||||
Rack::Handler::Puma.run(app, {Host: host, Port: port, Threads: "0:4", workers: 0, daemon: false}.merge(options))
|
||||
Rack::Handler::Puma.run(app, { Host: host, Port: port, Threads: "0:4", workers: 0, daemon: false }.merge(options))
|
||||
end
|
||||
|
||||
Capybara.configure do |config|
|
||||
|
@ -476,11 +476,11 @@ Capybara.register_driver :selenium do |app|
|
|||
end
|
||||
|
||||
Capybara.register_driver :selenium_chrome do |app|
|
||||
Capybara::Selenium::Driver.new(app, :browser => :chrome)
|
||||
Capybara::Selenium::Driver.new(app, browser: :chrome)
|
||||
end
|
||||
|
||||
Capybara.register_driver :selenium_chrome_headless do |app|
|
||||
browser_options = ::Selenium::WebDriver::Chrome::Options.new()
|
||||
browser_options = ::Selenium::WebDriver::Chrome::Options.new
|
||||
browser_options.args << '--headless'
|
||||
browser_options.args << '--disable-gpu'
|
||||
Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
|
||||
|
|
|
@ -22,9 +22,7 @@ module Capybara
|
|||
@session_options = Capybara::SessionConfig.new
|
||||
end
|
||||
|
||||
def reuse_server=(bool)
|
||||
@reuse_server = bool
|
||||
end
|
||||
attr_writer :reuse_server
|
||||
|
||||
def threadsafe=(bool)
|
||||
warn "Capybara.threadsafe == true is a BETA feature and may change in future minor versions" if bool
|
||||
|
@ -60,7 +58,7 @@ module Capybara
|
|||
def server=(name)
|
||||
name, options = *name if name.is_a? Array
|
||||
@server = if options
|
||||
Proc.new { |app, port, host| Capybara.servers[name.to_sym].call(app,port,host,options) }
|
||||
proc { |app, port, host| Capybara.servers[name.to_sym].call(app, port, host, options) }
|
||||
else
|
||||
Capybara.servers[name.to_sym]
|
||||
end
|
||||
|
@ -82,10 +80,10 @@ module Capybara
|
|||
@javascript_driver || :selenium
|
||||
end
|
||||
|
||||
def deprecate(method, alternate_method, once=false)
|
||||
def deprecate(method, alternate_method, once = false)
|
||||
@deprecation_notified ||= {}
|
||||
warn "DEPRECATED: ##{method} is deprecated, please use ##{alternate_method} instead" unless once and @deprecation_notified[method]
|
||||
@deprecation_notified[method]=true
|
||||
@deprecation_notified[method] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -22,8 +22,6 @@ end
|
|||
Before do |scenario|
|
||||
scenario.source_tag_names.each do |tag|
|
||||
driver_name = tag.sub(/^@/, '').to_sym
|
||||
if Capybara.drivers.has_key?(driver_name)
|
||||
Capybara.current_driver = driver_name
|
||||
end
|
||||
Capybara.current_driver = driver_name if Capybara.drivers.key?(driver_name)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -103,7 +103,6 @@ class Capybara::Driver::Base
|
|||
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#no_such_window_error'
|
||||
end
|
||||
|
||||
|
||||
##
|
||||
#
|
||||
# Execute the block, and then accept the modal opened.
|
||||
|
|
|
@ -40,15 +40,15 @@ module Capybara
|
|||
raise NotImplementedError
|
||||
end
|
||||
|
||||
def click(keys=[], offset={})
|
||||
def click(keys = [], offset = {})
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
def right_click(keys=[], offset={})
|
||||
def right_click(keys = [], offset = {})
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
def double_click(keys=[], offset={})
|
||||
def double_click(keys = [], offset = {})
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Capybara
|
||||
|
||||
# @api private
|
||||
module Helpers
|
||||
extend self
|
||||
|
@ -27,7 +26,7 @@ module Capybara
|
|||
# @param [String] text Text to escape
|
||||
# @return [String] Escaped text
|
||||
#
|
||||
def to_regexp(text, regexp_options=nil, exact=false)
|
||||
def to_regexp(text, regexp_options = nil, exact = false)
|
||||
if text.is_a?(Regexp)
|
||||
text
|
||||
else
|
||||
|
|
|
@ -42,9 +42,8 @@ module Capybara
|
|||
# @!method assert_no_current_path
|
||||
# see {Capybara::SessionMatchers#assert_no_current_path}
|
||||
|
||||
|
||||
%w(assert_text assert_no_text assert_title assert_no_title assert_current_path assert_no_current_path).each do |assertion_name|
|
||||
self.class_eval <<-ASSERTION, __FILE__, __LINE__ + 1
|
||||
%w[assert_text assert_no_text assert_title assert_no_title assert_current_path assert_no_current_path].each do |assertion_name|
|
||||
class_eval <<-ASSERTION, __FILE__, __LINE__ + 1
|
||||
def #{assertion_name} *args
|
||||
self.assertions +=1
|
||||
subject, args = determine_subject(args)
|
||||
|
@ -82,10 +81,10 @@ module Capybara
|
|||
# @!method assert_xpath
|
||||
# see {Capybara::Node::Matchers#assert_not_matches_selector}
|
||||
|
||||
%w(assert_selector assert_no_selector
|
||||
%w[assert_selector assert_no_selector
|
||||
assert_all_of_selectors assert_none_of_selectors
|
||||
assert_matches_selector assert_not_matches_selector).each do |assertion_name|
|
||||
self.class_eval <<-ASSERTION, __FILE__, __LINE__ + 1
|
||||
assert_matches_selector assert_not_matches_selector].each do |assertion_name|
|
||||
class_eval <<-ASSERTION, __FILE__, __LINE__ + 1
|
||||
def #{assertion_name} *args, &optional_filter_block
|
||||
self.assertions +=1
|
||||
subject, args = determine_subject(args)
|
||||
|
@ -99,7 +98,7 @@ module Capybara
|
|||
alias_method :refute_selector, :assert_no_selector
|
||||
alias_method :refute_matches_selector, :assert_not_matches_selector
|
||||
|
||||
%w(xpath css link button field select table).each do |selector_type|
|
||||
%w[xpath css link button field select table].each do |selector_type|
|
||||
define_method "assert_#{selector_type}" do |*args, &optional_filter_block|
|
||||
subject, args = determine_subject(args)
|
||||
locator, options = extract_locator(args)
|
||||
|
@ -114,7 +113,7 @@ module Capybara
|
|||
alias_method "refute_#{selector_type}", "assert_no_#{selector_type}"
|
||||
end
|
||||
|
||||
%w(checked unchecked).each do |field_type|
|
||||
%w[checked unchecked].each do |field_type|
|
||||
define_method "assert_#{field_type}_field" do |*args, &optional_filter_block|
|
||||
subject, args = determine_subject(args)
|
||||
locator, options = extract_locator(args)
|
||||
|
@ -129,7 +128,7 @@ module Capybara
|
|||
alias_method "refute_#{field_type}_field", "assert_no_#{field_type}_field"
|
||||
end
|
||||
|
||||
%w(xpath css).each do |selector_type|
|
||||
%w[xpath css].each do |selector_type|
|
||||
define_method "assert_matches_#{selector_type}" do |*args, &optional_filter_block|
|
||||
subject, args = determine_subject(args)
|
||||
assert_matches_selector(subject, selector_type.to_sym, *args, &optional_filter_block)
|
||||
|
@ -142,122 +141,122 @@ module Capybara
|
|||
alias_method "refute_matches_#{selector_type}", "assert_not_matches_#{selector_type}"
|
||||
end
|
||||
|
||||
##
|
||||
# Assertion that there is xpath
|
||||
#
|
||||
# @!method assert_xpath
|
||||
# see Capybara::Node::Matchers#has_xpath?
|
||||
##
|
||||
# Assertion that there is xpath
|
||||
#
|
||||
# @!method assert_xpath
|
||||
# see Capybara::Node::Matchers#has_xpath?
|
||||
|
||||
##
|
||||
# Assertion that there is no xpath
|
||||
#
|
||||
# @!method refute_xpath
|
||||
# @!method assert_no_xpath
|
||||
# see Capybara::Node::Matchers#has_no_xpath?
|
||||
##
|
||||
# Assertion that there is no xpath
|
||||
#
|
||||
# @!method refute_xpath
|
||||
# @!method assert_no_xpath
|
||||
# see Capybara::Node::Matchers#has_no_xpath?
|
||||
|
||||
##
|
||||
# Assertion that there is css
|
||||
#
|
||||
# @!method assert_css
|
||||
# see Capybara::Node::Matchers#has_css?
|
||||
##
|
||||
# Assertion that there is css
|
||||
#
|
||||
# @!method assert_css
|
||||
# see Capybara::Node::Matchers#has_css?
|
||||
|
||||
##
|
||||
# Assertion that there is no css
|
||||
#
|
||||
# @!method refute_css
|
||||
# @!method assert_no_css
|
||||
# see Capybara::Node::Matchers#has_no_css?
|
||||
##
|
||||
# Assertion that there is no css
|
||||
#
|
||||
# @!method refute_css
|
||||
# @!method assert_no_css
|
||||
# see Capybara::Node::Matchers#has_no_css?
|
||||
|
||||
##
|
||||
# Assertion that there is link
|
||||
#
|
||||
# @!method assert_link
|
||||
# see {Capybara::Node::Matchers#has_link?}
|
||||
##
|
||||
# Assertion that there is link
|
||||
#
|
||||
# @!method assert_link
|
||||
# see {Capybara::Node::Matchers#has_link?}
|
||||
|
||||
##
|
||||
# Assertion that there is no link
|
||||
#
|
||||
# @!method assert_no_link
|
||||
# @!method refute_link
|
||||
# see {Capybara::Node::Matchers#has_no_link?}
|
||||
##
|
||||
# Assertion that there is no link
|
||||
#
|
||||
# @!method assert_no_link
|
||||
# @!method refute_link
|
||||
# see {Capybara::Node::Matchers#has_no_link?}
|
||||
|
||||
##
|
||||
# Assertion that there is button
|
||||
#
|
||||
# @!method assert_button
|
||||
# see {Capybara::Node::Matchers#has_button?}
|
||||
##
|
||||
# Assertion that there is button
|
||||
#
|
||||
# @!method assert_button
|
||||
# see {Capybara::Node::Matchers#has_button?}
|
||||
|
||||
##
|
||||
# Assertion that there is no button
|
||||
#
|
||||
# @!method refute_button
|
||||
# @!method assert_no_button
|
||||
# see {Capybara::Node::Matchers#has_no_button?}
|
||||
##
|
||||
# Assertion that there is no button
|
||||
#
|
||||
# @!method refute_button
|
||||
# @!method assert_no_button
|
||||
# see {Capybara::Node::Matchers#has_no_button?}
|
||||
|
||||
##
|
||||
# Assertion that there is field
|
||||
#
|
||||
# @!method assert_field
|
||||
# see {Capybara::Node::Matchers#has_field?}
|
||||
##
|
||||
# Assertion that there is field
|
||||
#
|
||||
# @!method assert_field
|
||||
# see {Capybara::Node::Matchers#has_field?}
|
||||
|
||||
##
|
||||
# Assertion that there is no field
|
||||
#
|
||||
# @!method refute_field
|
||||
# @!method assert_no_field
|
||||
# see {Capybara::Node::Matchers#has_no_field?}
|
||||
##
|
||||
# Assertion that there is no field
|
||||
#
|
||||
# @!method refute_field
|
||||
# @!method assert_no_field
|
||||
# see {Capybara::Node::Matchers#has_no_field?}
|
||||
|
||||
##
|
||||
# Assertion that there is checked_field
|
||||
#
|
||||
# @!method assert_checked_field
|
||||
# see {Capybara::Node::Matchers#has_checked_field?}
|
||||
##
|
||||
# Assertion that there is checked_field
|
||||
#
|
||||
# @!method assert_checked_field
|
||||
# see {Capybara::Node::Matchers#has_checked_field?}
|
||||
|
||||
##
|
||||
# Assertion that there is no checked_field
|
||||
#
|
||||
# @!method assert_no_checked_field
|
||||
# @!method refute_checked_field
|
||||
##
|
||||
# Assertion that there is no checked_field
|
||||
#
|
||||
# @!method assert_no_checked_field
|
||||
# @!method refute_checked_field
|
||||
|
||||
##
|
||||
# Assertion that there is unchecked_field
|
||||
#
|
||||
# @!method assert_unchecked_field
|
||||
# see {Capybara::Node::Matchers#has_unchecked_field?}
|
||||
##
|
||||
# Assertion that there is unchecked_field
|
||||
#
|
||||
# @!method assert_unchecked_field
|
||||
# see {Capybara::Node::Matchers#has_unchecked_field?}
|
||||
|
||||
##
|
||||
# Assertion that there is no unchecked_field
|
||||
#
|
||||
# @!method assert_no_unchecked_field
|
||||
# @!method refute_unchecked_field
|
||||
##
|
||||
# Assertion that there is no unchecked_field
|
||||
#
|
||||
# @!method assert_no_unchecked_field
|
||||
# @!method refute_unchecked_field
|
||||
|
||||
##
|
||||
# Assertion that there is select
|
||||
#
|
||||
# @!method assert_select
|
||||
# see {Capybara::Node::Matchers#has_select?}
|
||||
##
|
||||
# Assertion that there is select
|
||||
#
|
||||
# @!method assert_select
|
||||
# see {Capybara::Node::Matchers#has_select?}
|
||||
|
||||
##
|
||||
# Assertion that there is no select
|
||||
#
|
||||
# @!method refute_select
|
||||
# @!method assert_no_select
|
||||
# see {Capybara::Node::Matchers#has_no_select?}
|
||||
##
|
||||
# Assertion that there is no select
|
||||
#
|
||||
# @!method refute_select
|
||||
# @!method assert_no_select
|
||||
# see {Capybara::Node::Matchers#has_no_select?}
|
||||
|
||||
##
|
||||
# Assertion that there is table
|
||||
#
|
||||
# @!method assert_table
|
||||
# see {Capybara::Node::Matchers#has_table?}
|
||||
##
|
||||
# Assertion that there is table
|
||||
#
|
||||
# @!method assert_table
|
||||
# see {Capybara::Node::Matchers#has_table?}
|
||||
|
||||
##
|
||||
# Assertion that there is no table
|
||||
#
|
||||
# @!method refute_table
|
||||
# @!method assert_no_table
|
||||
# see {Capybara::Node::Matchers#has_no_table?}
|
||||
##
|
||||
# Assertion that there is no table
|
||||
#
|
||||
# @!method refute_table
|
||||
# @!method assert_no_table
|
||||
# see {Capybara::Node::Matchers#has_no_table?}
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def determine_subject(args)
|
||||
case args.first
|
||||
|
|
|
@ -3,21 +3,22 @@ require 'minitest/spec'
|
|||
module Capybara
|
||||
module Minitest
|
||||
module Expectations
|
||||
%w(text content title current_path).each do |assertion|
|
||||
%w[text content title current_path].each do |assertion|
|
||||
infect_an_assertion "assert_#{assertion}", "must_have_#{assertion}", :reverse
|
||||
infect_an_assertion "refute_#{assertion}", "wont_have_#{assertion}", :reverse
|
||||
end
|
||||
|
||||
(%w(selector xpath css link button field select table checked_field unchecked_field).flat_map do |assertion|
|
||||
[["assert_#{assertion}", "must_have_#{assertion}"],
|
||||
["refute_#{assertion}", "wont_have_#{assertion}"]]
|
||||
end + [["assert_all_of_selectors", "must_have_all_of_selectors"],
|
||||
["assert_none_of_selectors", "must_have_none_of_selectors"]] +
|
||||
%w(selector xpath css).flat_map do |assertion|
|
||||
[["assert_matches_#{assertion}", "must_match_#{assertion}"],
|
||||
["refute_matches_#{assertion}", "wont_match_#{assertion}"]]
|
||||
# rubocop:disable Style/MultilineBlockChain
|
||||
(%w[selector xpath css link button field select table checked_field unchecked_field].flat_map do |assertion|
|
||||
[%W[assert_#{assertion} must_have_#{assertion}],
|
||||
%W[refute_#{assertion} wont_have_#{assertion}]]
|
||||
end + [%w[assert_all_of_selectors must_have_all_of_selectors],
|
||||
%w[assert_none_of_selectors must_have_none_of_selectors]] +
|
||||
%w[selector xpath css].flat_map do |assertion|
|
||||
[%W[assert_matches_#{assertion} must_match_#{assertion}],
|
||||
%W[refute_matches_#{assertion} wont_match_#{assertion}]]
|
||||
end).each do |(meth, new_name)|
|
||||
self.class_eval <<-ASSERTION, __FILE__, __LINE__ + 1
|
||||
class_eval <<-ASSERTION, __FILE__, __LINE__ + 1
|
||||
def #{new_name} *args, &block
|
||||
::Minitest::Expectation.new(self, ::Minitest::Spec.current).#{new_name}(*args, &block)
|
||||
end
|
||||
|
@ -29,6 +30,7 @@ module Capybara
|
|||
end
|
||||
ASSERTION
|
||||
end
|
||||
# rubocop:enable Style/MultilineBlockChain
|
||||
|
||||
##
|
||||
# Expectation that there is xpath
|
||||
|
@ -159,7 +161,6 @@ module Capybara
|
|||
#
|
||||
# @!method wont_have_current_path
|
||||
# see {Capybara::SessionMatchers#assert_no_current_path}
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
module Capybara
|
||||
module Node
|
||||
module Actions
|
||||
|
||||
##
|
||||
#
|
||||
# Finds a button or link and clicks it. See {Capybara::Node::Actions#click_button} and
|
||||
|
@ -21,7 +20,7 @@ module Capybara
|
|||
#
|
||||
# @return [Capybara::Node::Element] The element clicked
|
||||
#
|
||||
def click_link_or_button(locator=nil, **options)
|
||||
def click_link_or_button(locator = nil, **options)
|
||||
find(:link_or_button, locator, options).click
|
||||
end
|
||||
alias_method :click_on, :click_link_or_button
|
||||
|
@ -38,7 +37,7 @@ module Capybara
|
|||
# @param options See {Capybara::Node::Finders#find_link}
|
||||
#
|
||||
# @return [Capybara::Node::Element] The element clicked
|
||||
def click_link(locator=nil, **options)
|
||||
def click_link(locator = nil, **options)
|
||||
find(:link, locator, options).click
|
||||
end
|
||||
|
||||
|
@ -55,7 +54,7 @@ module Capybara
|
|||
# @param [String] locator Which button to find
|
||||
# @param options See {Capybara::Node::Finders#find_button}
|
||||
# @return [Capybara::Node::Element] The element clicked
|
||||
def click_button(locator=nil, **options)
|
||||
def click_button(locator = nil, **options)
|
||||
find(:button, locator, options).click
|
||||
end
|
||||
|
||||
|
@ -81,8 +80,8 @@ module Capybara
|
|||
# @option options [String, Array<String>] :class Match fields that match the class(es) provided
|
||||
#
|
||||
# @return [Capybara::Node::Element] The element filled_in
|
||||
def fill_in(locator=nil, with:, fill_options: {}, **options)
|
||||
options[:with] = options.delete(:currently_with) if options.has_key?(:currently_with)
|
||||
def fill_in(locator = nil, with:, fill_options: {}, **options)
|
||||
options[:with] = options.delete(:currently_with) if options.key?(:currently_with)
|
||||
find(:fillable_field, locator, options).set(with, fill_options)
|
||||
end
|
||||
|
||||
|
@ -107,7 +106,7 @@ module Capybara
|
|||
# @macro label_click
|
||||
#
|
||||
# @return [Capybara::Node::Element] The element chosen or the label clicked
|
||||
def choose(locator=nil, **options)
|
||||
def choose(locator = nil, **options)
|
||||
_check_with_label(:radio_button, true, locator, **options)
|
||||
end
|
||||
|
||||
|
@ -153,7 +152,7 @@ module Capybara
|
|||
# @macro waiting_behavior
|
||||
#
|
||||
# @return [Capybara::Node::Element] The element unchecked or the label clicked
|
||||
def uncheck(locator=nil, **options)
|
||||
def uncheck(locator = nil, **options)
|
||||
_check_with_label(:checkbox, false, locator, **options)
|
||||
end
|
||||
|
||||
|
@ -174,7 +173,7 @@ module Capybara
|
|||
# @option options [String] :from The id, name or label of the select box
|
||||
#
|
||||
# @return [Capybara::Node::Element] The option element selected
|
||||
def select(value=nil, from: nil, **options)
|
||||
def select(value = nil, from: nil, **options)
|
||||
if from
|
||||
find(:select, from, options).find(:option, value, options).select_option
|
||||
else
|
||||
|
@ -196,7 +195,7 @@ module Capybara
|
|||
# @param [Hash{:from => String}] options The id, name or label of the select box
|
||||
#
|
||||
# @return [Capybara::Node::Element] The option element unselected
|
||||
def unselect(value=nil, from: nil, **options)
|
||||
def unselect(value = nil, from: nil, **options)
|
||||
if from
|
||||
find(:select, from, options).find(:option, value, options).unselect_option
|
||||
else
|
||||
|
@ -225,23 +224,22 @@ 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, make_visible: nil, **options)
|
||||
def attach_file(locator = nil, path, make_visible: nil, **options) # rubocop:disable Style/OptionalArguments
|
||||
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 make_visible
|
||||
make_visible = { opacity: 1, display: 'block', visibility: 'visible' } if make_visible == true
|
||||
ff = find(:file_field, locator, options.merge({visible: :all}))
|
||||
ff = find(:file_field, locator, options.merge(visible: :all))
|
||||
_update_style(ff, make_visible)
|
||||
if ff.visible?
|
||||
begin
|
||||
ff.set(path)
|
||||
ensure
|
||||
_reset_style(ff)
|
||||
end
|
||||
else
|
||||
raise ExpectationNotMet, "The style changes in :make_visible did not make the file input visible"
|
||||
|
||||
raise ExpectationNotMet, "The style changes in :make_visible did not make the file input visible" unless ff.visible?
|
||||
|
||||
begin
|
||||
ff.set(path)
|
||||
ensure
|
||||
_reset_style(ff)
|
||||
end
|
||||
else
|
||||
find(:file_field, locator, options).set(path)
|
||||
|
@ -249,6 +247,7 @@ module Capybara
|
|||
end
|
||||
|
||||
private
|
||||
|
||||
def _update_style(element, style)
|
||||
script = <<-JS
|
||||
var el = arguments[0];
|
||||
|
@ -277,12 +276,12 @@ module Capybara
|
|||
JS
|
||||
begin
|
||||
session.execute_script(script, element)
|
||||
rescue
|
||||
rescue # swallow extra errors
|
||||
end
|
||||
end
|
||||
|
||||
def _check_with_label(selector, checked, locator, allow_label_click: session_options.automatic_label_click, **options)
|
||||
synchronize(Capybara::Queries::BaseQuery::wait(options, session_options.default_max_wait_time)) do
|
||||
synchronize(Capybara::Queries::BaseQuery.wait(options, session_options.default_max_wait_time)) do
|
||||
begin
|
||||
el = find(selector, locator, options)
|
||||
el.set(checked)
|
||||
|
@ -291,14 +290,13 @@ module Capybara
|
|||
begin
|
||||
el ||= find(selector, locator, options.merge(visible: :all))
|
||||
label = find(:label, for: el, visible: true)
|
||||
label.click unless (el.checked? == checked)
|
||||
rescue
|
||||
label.click unless el.checked? == checked
|
||||
rescue # swallow extra errors - raise original
|
||||
raise e
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
module Capybara
|
||||
module Node
|
||||
|
||||
##
|
||||
#
|
||||
# A {Capybara::Node::Base} represents either an element on a page through the subclass
|
||||
|
@ -75,7 +74,7 @@ module Capybara
|
|||
# @return [Object] The result of the given block
|
||||
# @raise [Capybara::FrozenInTime] If the return value of `Time.now` appears stuck
|
||||
#
|
||||
def synchronize(seconds=session_options.default_max_wait_time, errors: nil)
|
||||
def synchronize(seconds = session_options.default_max_wait_time, errors: nil)
|
||||
start_time = Capybara::Helpers.monotonic_time
|
||||
|
||||
if session.synchronized
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
module Capybara
|
||||
module Node
|
||||
|
||||
##
|
||||
#
|
||||
# A {Capybara::Document} represents an HTML document. Any operation
|
||||
|
@ -21,7 +20,7 @@ module Capybara
|
|||
#
|
||||
# @return [String] The text of the document
|
||||
#
|
||||
def text(type=nil)
|
||||
def text(type = nil)
|
||||
find(:xpath, '/html').text(type)
|
||||
end
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ module Capybara
|
|||
# @return [true]
|
||||
#
|
||||
def assert_title(title, **options)
|
||||
_verify_title(title,options) { |query| raise Capybara::ExpectationNotMet, query.failure_message unless query.resolves_for?(self) }
|
||||
_verify_title(title, options) { |query| raise Capybara::ExpectationNotMet, query.failure_message unless query.resolves_for?(self) }
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -28,7 +28,7 @@ module Capybara
|
|||
# @return [true]
|
||||
#
|
||||
def assert_no_title(title, **options)
|
||||
_verify_title(title,options) { |query| raise Capybara::ExpectationNotMet, query.negative_failure_message if query.resolves_for?(self) }
|
||||
_verify_title(title, options) { |query| raise Capybara::ExpectationNotMet, query.negative_failure_message if query.resolves_for?(self) }
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -55,7 +55,7 @@ module Capybara
|
|||
return false
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def _verify_title(title, options)
|
||||
query = Capybara::Queries::TitleQuery.new(title, options)
|
||||
|
@ -64,7 +64,6 @@ module Capybara
|
|||
end
|
||||
return true
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
module Capybara
|
||||
module Node
|
||||
|
||||
##
|
||||
#
|
||||
# A {Capybara::Node::Element} represents a single element on the page. It is possible
|
||||
|
@ -23,7 +22,6 @@ module Capybara
|
|||
# @see Capybara::Node
|
||||
#
|
||||
class Element < Base
|
||||
|
||||
def initialize(session, base, query_scope, query)
|
||||
super(session, base)
|
||||
@query_scope = query_scope
|
||||
|
@ -55,7 +53,7 @@ module Capybara
|
|||
# @param [:all, :visible] type Whether to return only visible or all text
|
||||
# @return [String] The text of the element
|
||||
#
|
||||
def text(type=nil)
|
||||
def text(type = nil)
|
||||
type ||= :all unless session_options.ignore_hidden_elements or session_options.visible_text_only
|
||||
synchronize do
|
||||
if type == :all
|
||||
|
@ -397,18 +395,15 @@ module Capybara
|
|||
rescue NotSupportedByDriverError
|
||||
%(#<Capybara::Node::Element tag="#{base.tag_name}">)
|
||||
rescue => e
|
||||
if session.driver.invalid_element_errors.any? { |et| e.is_a?(et)}
|
||||
%(Obsolete #<Capybara::Node::Element>)
|
||||
else
|
||||
raise
|
||||
end
|
||||
raise unless session.driver.invalid_element_errors.any? { |et| e.is_a?(et) }
|
||||
|
||||
%(Obsolete #<Capybara::Node::Element>)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def verify_click_options_support(method)
|
||||
if base.method(method).arity.zero?
|
||||
raise ArgumentError, "The current driver does not support #{method} options"
|
||||
end
|
||||
raise ArgumentError, "The current driver does not support #{method} options" if base.method(method).arity.zero?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
module Capybara
|
||||
module Node
|
||||
module Finders
|
||||
|
||||
##
|
||||
#
|
||||
# Find an {Capybara::Node::Element} based on the given arguments. +find+ will raise an error if the element
|
||||
|
@ -124,7 +123,7 @@ module Capybara
|
|||
# @return [Capybara::Node::Element] The found element
|
||||
#
|
||||
|
||||
def find_field(locator=nil, **options, &optional_filter_block)
|
||||
def find_field(locator = nil, **options, &optional_filter_block)
|
||||
find(:field, locator, options, &optional_filter_block)
|
||||
end
|
||||
alias_method :field_labeled, :find_field
|
||||
|
@ -145,7 +144,7 @@ module Capybara
|
|||
# @option options [String, Array<String>] class Match links that match the class(es) provided
|
||||
# @return [Capybara::Node::Element] The found element
|
||||
#
|
||||
def find_link(locator=nil, **options, &optional_filter_block)
|
||||
def find_link(locator = nil, **options, &optional_filter_block)
|
||||
find(:link, locator, options, &optional_filter_block)
|
||||
end
|
||||
|
||||
|
@ -173,7 +172,7 @@ module Capybara
|
|||
# @option options [String, Array<String>] class Match buttons that match the class(es) provided
|
||||
# @return [Capybara::Node::Element] The found element
|
||||
#
|
||||
def find_button(locator=nil, **options, &optional_filter_block)
|
||||
def find_button(locator = nil, **options, &optional_filter_block)
|
||||
find(:button, locator, options, &optional_filter_block)
|
||||
end
|
||||
|
||||
|
@ -256,8 +255,8 @@ module Capybara
|
|||
# @return [Capybara::Result] A collection of found elements
|
||||
# @raise [Capybara::ExpectationNotMet] The number of elements found doesn't match the specified conditions
|
||||
def all(*args, **options, &optional_filter_block)
|
||||
minimum_specified = %i[count minimum between].any? {|k| options.key?(k)}
|
||||
options = {minimum: 1}.merge(options) unless minimum_specified
|
||||
minimum_specified = %i[count minimum between].any? { |k| options.key?(k) }
|
||||
options = { minimum: 1 }.merge(options) unless minimum_specified
|
||||
options[:session_options] = session_options
|
||||
args.push(options)
|
||||
query = Capybara::Queries::SelectorQuery.new(*args, &optional_filter_block)
|
||||
|
@ -290,15 +289,15 @@ module Capybara
|
|||
# @raise [Capybara::ElementNotFound] If the element can't be found before time expires
|
||||
#
|
||||
def first(*args, **options, &optional_filter_block)
|
||||
options = {minimum: 1}.merge(options)
|
||||
options = { minimum: 1 }.merge(options)
|
||||
all(*args, **options, &optional_filter_block).first
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def synced_resolve(query)
|
||||
synchronize(query.wait) do
|
||||
if (query.match == :smart or query.match == :prefer_exact)
|
||||
if query.match == :smart or query.match == :prefer_exact
|
||||
result = query.resolve_for(self, true)
|
||||
result = query.resolve_for(self, false) if result.empty? && query.supports_exact? && !query.exact?
|
||||
else
|
||||
|
@ -306,11 +305,11 @@ module Capybara
|
|||
end
|
||||
|
||||
if query.match == :one or query.match == :smart and result.size > 1
|
||||
raise Capybara::Ambiguous.new("Ambiguous match, found #{result.size} elements matching #{query.description}")
|
||||
end
|
||||
if result.empty?
|
||||
raise Capybara::ElementNotFound.new("Unable to find #{query.description}")
|
||||
raise Capybara::Ambiguous, "Ambiguous match, found #{result.size} elements matching #{query.description}"
|
||||
end
|
||||
|
||||
raise Capybara::ElementNotFound, "Unable to find #{query.description}" if result.empty?
|
||||
|
||||
result.first
|
||||
end.tap(&:allow_reload!)
|
||||
end
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
module Capybara
|
||||
module Node
|
||||
module Matchers
|
||||
|
||||
##
|
||||
#
|
||||
# Checks if a given selector is on the page or a descendant of the current node.
|
||||
|
@ -114,7 +113,7 @@ module Capybara
|
|||
# @overload assert_all_of_selectors([kind = Capybara.default_selector], *locators, options = {})
|
||||
#
|
||||
def assert_all_of_selectors(*args, wait: session_options.default_max_wait_time, **options, &optional_filter_block)
|
||||
selector = if args.first.is_a?(Symbol) then args.shift else session_options.default_selector end
|
||||
selector = args.first.is_a?(Symbol) ? args.shift : session_options.default_selector
|
||||
synchronize(wait) do
|
||||
args.each do |locator|
|
||||
assert_selector(selector, locator, options, &optional_filter_block)
|
||||
|
@ -138,7 +137,7 @@ module Capybara
|
|||
# @overload assert_none_of_selectors([kind = Capybara.default_selector], *locators, options = {})
|
||||
#
|
||||
def assert_none_of_selectors(*args, wait: session_options.default_max_wait_time, **options, &optional_filter_block)
|
||||
selector = if args.first.is_a?(Symbol) then args.shift else session_options.default_selector end
|
||||
selector = args.first.is_a?(Symbol) ? args.shift : session_options.default_selector
|
||||
synchronize(wait) do
|
||||
args.each do |locator|
|
||||
assert_no_selector(selector, locator, options, &optional_filter_block)
|
||||
|
@ -265,7 +264,7 @@ module Capybara
|
|||
# @option options [String, Regexp] :href The value the href attribute must be
|
||||
# @return [Boolean] Whether it exists
|
||||
#
|
||||
def has_link?(locator=nil, **options, &optional_filter_block)
|
||||
def has_link?(locator = nil, **options, &optional_filter_block)
|
||||
has_selector?(:link, locator, options, &optional_filter_block)
|
||||
end
|
||||
|
||||
|
@ -277,7 +276,7 @@ module Capybara
|
|||
# @param (see Capybara::Node::Finders#has_link?)
|
||||
# @return [Boolean] Whether it doesn't exist
|
||||
#
|
||||
def has_no_link?(locator=nil, **options, &optional_filter_block)
|
||||
def has_no_link?(locator = nil, **options, &optional_filter_block)
|
||||
has_no_selector?(:link, locator, options, &optional_filter_block)
|
||||
end
|
||||
|
||||
|
@ -289,7 +288,7 @@ module Capybara
|
|||
# @param [String] locator The text, value or id of a button to check for
|
||||
# @return [Boolean] Whether it exists
|
||||
#
|
||||
def has_button?(locator=nil, **options, &optional_filter_block)
|
||||
def has_button?(locator = nil, **options, &optional_filter_block)
|
||||
has_selector?(:button, locator, options, &optional_filter_block)
|
||||
end
|
||||
|
||||
|
@ -301,7 +300,7 @@ module Capybara
|
|||
# @param [String] locator The text, value or id of a button to check for
|
||||
# @return [Boolean] Whether it doesn't exist
|
||||
#
|
||||
def has_no_button?(locator=nil, **options, &optional_filter_block)
|
||||
def has_no_button?(locator = nil, **options, &optional_filter_block)
|
||||
has_no_selector?(:button, locator, options, &optional_filter_block)
|
||||
end
|
||||
|
||||
|
@ -327,7 +326,7 @@ module Capybara
|
|||
# @option options [String] :type The type attribute of the field
|
||||
# @return [Boolean] Whether it exists
|
||||
#
|
||||
def has_field?(locator=nil, **options, &optional_filter_block)
|
||||
def has_field?(locator = nil, **options, &optional_filter_block)
|
||||
has_selector?(:field, locator, options, &optional_filter_block)
|
||||
end
|
||||
|
||||
|
@ -341,7 +340,7 @@ module Capybara
|
|||
# @option options [String] :type The type attribute of the field
|
||||
# @return [Boolean] Whether it doesn't exist
|
||||
#
|
||||
def has_no_field?(locator=nil, **options, &optional_filter_block)
|
||||
def has_no_field?(locator = nil, **options, &optional_filter_block)
|
||||
has_no_selector?(:field, locator, options, &optional_filter_block)
|
||||
end
|
||||
|
||||
|
@ -354,7 +353,7 @@ module Capybara
|
|||
# @param [String] locator The label, name or id of a checked field
|
||||
# @return [Boolean] Whether it exists
|
||||
#
|
||||
def has_checked_field?(locator=nil, **options, &optional_filter_block)
|
||||
def has_checked_field?(locator = nil, **options, &optional_filter_block)
|
||||
has_selector?(:field, locator, options.merge(checked: true), &optional_filter_block)
|
||||
end
|
||||
|
||||
|
@ -367,7 +366,7 @@ module Capybara
|
|||
# @param [String] locator The label, name or id of a checked field
|
||||
# @return [Boolean] Whether it doesn't exist
|
||||
#
|
||||
def has_no_checked_field?(locator=nil, **options, &optional_filter_block)
|
||||
def has_no_checked_field?(locator = nil, **options, &optional_filter_block)
|
||||
has_no_selector?(:field, locator, options.merge(checked: true), &optional_filter_block)
|
||||
end
|
||||
|
||||
|
@ -380,7 +379,7 @@ module Capybara
|
|||
# @param [String] locator The label, name or id of an unchecked field
|
||||
# @return [Boolean] Whether it exists
|
||||
#
|
||||
def has_unchecked_field?(locator=nil, **options, &optional_filter_block)
|
||||
def has_unchecked_field?(locator = nil, **options, &optional_filter_block)
|
||||
has_selector?(:field, locator, options.merge(unchecked: true), &optional_filter_block)
|
||||
end
|
||||
|
||||
|
@ -393,7 +392,7 @@ module Capybara
|
|||
# @param [String] locator The label, name or id of an unchecked field
|
||||
# @return [Boolean] Whether it doesn't exist
|
||||
#
|
||||
def has_no_unchecked_field?(locator=nil, **options, &optional_filter_block)
|
||||
def has_no_unchecked_field?(locator = nil, **options, &optional_filter_block)
|
||||
has_no_selector?(:field, locator, options.merge(unchecked: true), &optional_filter_block)
|
||||
end
|
||||
|
||||
|
@ -426,7 +425,7 @@ module Capybara
|
|||
# @option options [String, Array] :with_selected Partial set of options which should minimally be selected
|
||||
# @return [Boolean] Whether it exists
|
||||
#
|
||||
def has_select?(locator=nil, **options, &optional_filter_block)
|
||||
def has_select?(locator = nil, **options, &optional_filter_block)
|
||||
has_selector?(:select, locator, options, &optional_filter_block)
|
||||
end
|
||||
|
||||
|
@ -438,7 +437,7 @@ module Capybara
|
|||
# @param (see Capybara::Node::Matchers#has_select?)
|
||||
# @return [Boolean] Whether it doesn't exist
|
||||
#
|
||||
def has_no_select?(locator=nil, **options, &optional_filter_block)
|
||||
def has_no_select?(locator = nil, **options, &optional_filter_block)
|
||||
has_no_selector?(:select, locator, options, &optional_filter_block)
|
||||
end
|
||||
|
||||
|
@ -452,7 +451,7 @@ module Capybara
|
|||
# @param [String] locator The id or caption of a table
|
||||
# @return [Boolean] Whether it exist
|
||||
#
|
||||
def has_table?(locator=nil, **options, &optional_filter_block)
|
||||
def has_table?(locator = nil, **options, &optional_filter_block)
|
||||
has_selector?(:table, locator, options, &optional_filter_block)
|
||||
end
|
||||
|
||||
|
@ -464,7 +463,7 @@ module Capybara
|
|||
# @param (see Capybara::Node::Matchers#has_table?)
|
||||
# @return [Boolean] Whether it doesn't exist
|
||||
#
|
||||
def has_no_table?(locator=nil, **options, &optional_filter_block)
|
||||
def has_no_table?(locator = nil, **options, &optional_filter_block)
|
||||
has_no_selector?(:table, locator, options, &optional_filter_block)
|
||||
end
|
||||
|
||||
|
@ -568,7 +567,6 @@ module Capybara
|
|||
not_matches_selector?(:css, css, options, &optional_filter_block)
|
||||
end
|
||||
|
||||
|
||||
##
|
||||
# Asserts that the page or current node has the given text content,
|
||||
# ignoring any HTML tags.
|
||||
|
@ -658,7 +656,7 @@ module Capybara
|
|||
alias_method :has_no_content?, :has_no_text?
|
||||
|
||||
def ==(other)
|
||||
self.eql?(other) || (other.respond_to?(:base) && base == other.base)
|
||||
eql?(other) || (other.respond_to?(:base) && base == other.base)
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -677,7 +675,7 @@ module Capybara
|
|||
_set_query_session_options(query_args)
|
||||
query = Capybara::Queries::MatchQuery.new(*query_args, &optional_filter_block)
|
||||
synchronize(query.wait) do
|
||||
result = query.resolve_for(self.query_scope)
|
||||
result = query.resolve_for(query_scope)
|
||||
yield result
|
||||
end
|
||||
return true
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
module Capybara
|
||||
module Node
|
||||
|
||||
##
|
||||
#
|
||||
# A {Capybara::Node::Simple} is a simpler version of {Capybara::Node::Base} which
|
||||
|
@ -29,7 +28,7 @@ module Capybara
|
|||
#
|
||||
# @return [String] The text of the element
|
||||
#
|
||||
def text(_type=nil)
|
||||
def text(_type = nil)
|
||||
native.text
|
||||
end
|
||||
|
||||
|
@ -80,12 +79,12 @@ module Capybara
|
|||
native['_capybara_raw_value']
|
||||
elsif tag_name == 'select'
|
||||
if native['multiple'] == 'multiple'
|
||||
native.xpath(".//option[@selected='selected']").map { |option| option[:value] || option.content }
|
||||
native.xpath(".//option[@selected='selected']").map { |option| option[:value] || option.content }
|
||||
else
|
||||
option = native.xpath(".//option[@selected='selected']").first || native.xpath(".//option").first
|
||||
option[:value] || option.content if option
|
||||
end
|
||||
elsif tag_name == 'input' && %w(radio checkbox).include?(native[:type])
|
||||
elsif tag_name == 'input' && %w[radio checkbox].include?(native[:type])
|
||||
native[:value] || 'on'
|
||||
else
|
||||
native[:value]
|
||||
|
@ -101,13 +100,13 @@ module Capybara
|
|||
# @return [Boolean] Whether the element is visible
|
||||
#
|
||||
def visible?(check_ancestors = true)
|
||||
return false if (tag_name == 'input') && (native[:type]=="hidden")
|
||||
return false if (tag_name == 'input') && (native[:type] == "hidden")
|
||||
|
||||
if check_ancestors
|
||||
!native.xpath("boolean(./ancestor-or-self::*[contains(@style, 'display:none') or contains(@style, 'display: none') or @hidden or name()='script' or name()='head'])")
|
||||
else
|
||||
#no need for an xpath if only checking the current element
|
||||
!(native.has_attribute?('hidden') || (native[:style] =~ /display:\s?none/) || %w(script head).include?(tag_name))
|
||||
# No need for an xpath if only checking the current element
|
||||
!(native.has_attribute?('hidden') || (native[:style] =~ /display:\s?none/) || %w[script head].include?(tag_name))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -140,7 +139,7 @@ module Capybara
|
|||
native.has_attribute?('selected')
|
||||
end
|
||||
|
||||
def synchronize(_seconds=nil)
|
||||
def synchronize(_seconds = nil)
|
||||
yield # simple nodes don't need to wait
|
||||
end
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ module Capybara
|
|||
self.class.wait(options, session_options.default_max_wait_time)
|
||||
end
|
||||
|
||||
def self.wait(options, default=Capybara.default_max_wait_time)
|
||||
def self.wait(options, default = Capybara.default_max_wait_time)
|
||||
options.fetch(:wait, default) || 0
|
||||
end
|
||||
|
||||
|
@ -31,7 +31,7 @@ module Capybara
|
|||
# Returns false if query does not have any count options specified.
|
||||
#
|
||||
def expects_none?
|
||||
if COUNT_KEYS.any? { |k| options.has_key? k }
|
||||
if COUNT_KEYS.any? { |k| options.key? k }
|
||||
matches_count?(0)
|
||||
else
|
||||
false
|
||||
|
@ -48,10 +48,10 @@ module Capybara
|
|||
# @param [Integer] count The actual number. Should be coercible via Integer()
|
||||
#
|
||||
def matches_count?(count)
|
||||
return (Integer(options[:count]) == count) if options[:count]
|
||||
return (Integer(options[:count]) == count) if options[:count]
|
||||
return false if options[:maximum] && (Integer(options[:maximum]) < count)
|
||||
return false if options[:minimum] && (Integer(options[:minimum]) > count)
|
||||
return false if options[:between] && !(options[:between] === count)
|
||||
return false if options[:between] && !options[:between].include?(count)
|
||||
return true
|
||||
end
|
||||
|
||||
|
@ -67,10 +67,10 @@ module Capybara
|
|||
String.new("expected not to find #{description}") << count_message
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def count_message
|
||||
message = String.new()
|
||||
message = "".dup
|
||||
if options[:count]
|
||||
message << " #{options[:count]} #{Capybara::Helpers.declension('time', 'times', options[:count])}"
|
||||
elsif options[:between]
|
||||
|
@ -85,11 +85,11 @@ module Capybara
|
|||
|
||||
def assert_valid_keys
|
||||
invalid_keys = @options.keys - valid_keys
|
||||
unless invalid_keys.empty?
|
||||
invalid_names = invalid_keys.map(&:inspect).join(", ")
|
||||
valid_names = valid_keys.map(&:inspect).join(", ")
|
||||
raise ArgumentError, "invalid keys #{invalid_names}, should be one of #{valid_names}"
|
||||
end
|
||||
return if invalid_keys.empty?
|
||||
|
||||
invalid_names = invalid_keys.map(&:inspect).join(", ")
|
||||
valid_names = valid_keys.map(&:inspect).join(", ")
|
||||
raise ArgumentError, "invalid keys #{invalid_names}, should be one of #{valid_names}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -40,7 +40,7 @@ module Capybara
|
|||
failure_message_helper(' not')
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def failure_message_helper(negated = '')
|
||||
verb = @expected_path.is_a?(Regexp) ? 'match' : 'equal'
|
||||
|
@ -50,7 +50,6 @@ module Capybara
|
|||
def valid_keys
|
||||
%i[wait url ignore_query]
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,18 +2,18 @@ module Capybara
|
|||
module Queries
|
||||
class MatchQuery < Capybara::Queries::SelectorQuery
|
||||
def visible
|
||||
if options.has_key?(:visible)
|
||||
if options.key?(:visible)
|
||||
super
|
||||
else
|
||||
:all
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def valid_keys
|
||||
super - COUNT_KEYS
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -38,7 +38,7 @@ module Capybara
|
|||
def label; selector.label or selector.name; end
|
||||
|
||||
def description
|
||||
@description = String.new()
|
||||
@description = "".dup
|
||||
@description << "visible " if visible == :visible
|
||||
@description << "non-visible " if visible == :hidden
|
||||
@description << "#{label} #{locator.inspect}"
|
||||
|
@ -53,16 +53,16 @@ module Capybara
|
|||
end
|
||||
|
||||
def matches_filters?(node)
|
||||
return false unless matches_text_filter(node, options[:text]) if options[:text]
|
||||
return false unless matches_exact_text_filter(node, exact_text) if exact_text.is_a?(String)
|
||||
return false if options[:text] && !matches_text_filter(node, options[:text])
|
||||
return false if exact_text.is_a?(String) && !matches_exact_text_filter(node, exact_text)
|
||||
|
||||
case visible
|
||||
when :visible then return false unless node.visible?
|
||||
when :hidden then return false if node.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)
|
||||
if options.key?(name)
|
||||
filter.matches?(node, options[name])
|
||||
elsif filter.default?
|
||||
filter.matches?(node, filter.default)
|
||||
|
@ -71,11 +71,13 @@ module Capybara
|
|||
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?
|
||||
if @filter_block
|
||||
res &&= if node.respond_to?(:session)
|
||||
node.session.using_wait_time(0) { @filter_block.call(node) }
|
||||
else
|
||||
@filter_block.call(node)
|
||||
end
|
||||
end
|
||||
|
||||
res
|
||||
rescue *(node.respond_to?(:session) ? node.session.driver.invalid_element_errors : [])
|
||||
|
@ -83,15 +85,15 @@ module Capybara
|
|||
end
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
def exact?
|
||||
return false if !supports_exact?
|
||||
return false unless supports_exact?
|
||||
options.fetch(:exact, session_options.exact)
|
||||
end
|
||||
|
||||
|
@ -99,14 +101,10 @@ module Capybara
|
|||
options.fetch(:match, session_options.match)
|
||||
end
|
||||
|
||||
def xpath(exact=nil)
|
||||
exact = self.exact? if exact.nil?
|
||||
def xpath(exact = nil)
|
||||
exact = 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
|
||||
expr = exact ? expr.to_xpath(:exact) : expr.to_s if expr.respond_to?(:to_xpath)
|
||||
filtered_xpath(expr)
|
||||
end
|
||||
|
||||
|
@ -119,9 +117,9 @@ module Capybara
|
|||
@resolved_node = node
|
||||
node.synchronize do
|
||||
children = if selector.format == :css
|
||||
node.find_css(self.css)
|
||||
node.find_css(css)
|
||||
else
|
||||
node.find_xpath(self.xpath(exact))
|
||||
node.find_xpath(xpath(exact))
|
||||
end.map do |child|
|
||||
if node.is_a?(Capybara::Node::Base)
|
||||
Capybara::Node::Element.new(node.session, child, node, self)
|
||||
|
@ -138,14 +136,14 @@ module Capybara
|
|||
@expression.respond_to? :to_xpath
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def valid_keys
|
||||
VALID_KEYS + custom_keys
|
||||
end
|
||||
|
||||
def node_filters
|
||||
if options.has_key?(:filter_set)
|
||||
if options.key?(:filter_set)
|
||||
::Capybara::Selector::FilterSet.all[options[:filter_set]].node_filters
|
||||
else
|
||||
@selector.node_filters
|
||||
|
@ -154,7 +152,7 @@ module Capybara
|
|||
|
||||
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.merge ::Capybara::Selector::FilterSet.all[options[:filter_set]].expression_filters if options.key?(:filter_set)
|
||||
filters
|
||||
end
|
||||
|
||||
|
@ -170,10 +168,10 @@ module Capybara
|
|||
end
|
||||
|
||||
def filtered_xpath(expr)
|
||||
if options.has_key?(:id) || options.has_key?(:class)
|
||||
if options.key?(:id) || options.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)
|
||||
expr = "#{expr}[#{XPath.attr(:id) == options[:id]}]" if options.key?(:id) && !custom_keys.include?(:id)
|
||||
if options.key?(:class) && !custom_keys.include?(:class)
|
||||
class_xpath = Array(options[:class]).map do |klass|
|
||||
XPath.attr(:class).contains_word(klass)
|
||||
end.reduce(:&)
|
||||
|
@ -184,12 +182,12 @@ module Capybara
|
|||
end
|
||||
|
||||
def filtered_css(expr)
|
||||
if options.has_key?(:id) || options.has_key?(:class)
|
||||
if options.key?(:id) || options.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
|
||||
sel += "##{Capybara::Selector::CSS.escape(options[:id])}" if options.key?(:id) && !custom_keys.include?(:id)
|
||||
sel += Array(options[:class]).map { |k| ".#{Capybara::Selector::CSS.escape(k)}" }.join if options.key?(:class) && !custom_keys.include?(:class)
|
||||
sel
|
||||
end.join(", ")
|
||||
end
|
||||
expr
|
||||
|
@ -197,7 +195,7 @@ module Capybara
|
|||
|
||||
def apply_expression_filters(expr)
|
||||
expression_filters.inject(expr) do |memo, (name, ef)|
|
||||
if options.has_key?(name)
|
||||
if options.key?(name)
|
||||
ef.apply_filter(memo, options[name])
|
||||
elsif ef.default?
|
||||
ef.apply_filter(memo, ef.default)
|
||||
|
@ -208,9 +206,8 @@ module Capybara
|
|||
end
|
||||
|
||||
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}\" has no effect."
|
||||
end
|
||||
return unless options.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}\" has no effect."
|
||||
end
|
||||
|
||||
def exact_text
|
||||
|
|
|
@ -4,9 +4,9 @@ module Capybara
|
|||
# @api private
|
||||
module Queries
|
||||
class TextQuery < BaseQuery
|
||||
def initialize(type=nil, expected_text, session_options:, **options)
|
||||
def initialize(type = nil, expected_text, session_options:, **options) # rubocop:disable Style/OptionalArguments
|
||||
@type = type
|
||||
@type = Capybara.ignore_hidden_elements or Capybara.visible_text_only ? :visible : :all if @type.nil?
|
||||
@type = Capybara.ignore_hidden_elements || Capybara.visible_text_only ? :visible : :all if @type.nil?
|
||||
@expected_text = expected_text
|
||||
@options = options
|
||||
super(@options)
|
||||
|
@ -40,14 +40,14 @@ module Capybara
|
|||
end
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def exact?
|
||||
options.fetch(:exact, session_options.exact_text)
|
||||
end
|
||||
|
||||
def build_message(report_on_invisible)
|
||||
message = String.new()
|
||||
message = "".dup
|
||||
unless (COUNT_KEYS & @options.keys).empty?
|
||||
message << " but found #{@count} #{Capybara::Helpers.declension('time', 'times', @count)}"
|
||||
end
|
||||
|
@ -70,8 +70,7 @@ module Capybara
|
|||
if invisible_count != @count
|
||||
details_message << "it was found #{invisible_count} #{Capybara::Helpers.declension("time", "times", invisible_count)} including non-visible text"
|
||||
end
|
||||
rescue
|
||||
# An error getting the non-visible text (if element goes out of scope) should not affect the response
|
||||
rescue # An error getting the non-visible text (if element goes out of scope) should not affect the response
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ module Capybara
|
|||
failure_message_helper(' not')
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def failure_message_helper(negated = '')
|
||||
verb = @expected_title.is_a?(Regexp) ? 'match' : 'include'
|
||||
|
|
|
@ -29,23 +29,24 @@ class Capybara::RackTest::Browser
|
|||
end
|
||||
|
||||
def submit(method, path, attributes)
|
||||
path = request_path if not path or path.empty?
|
||||
process_and_follow_redirects(method, path, attributes, {'HTTP_REFERER' => current_url})
|
||||
path = request_path if path.nil? || path.empty?
|
||||
process_and_follow_redirects(method, path, attributes, 'HTTP_REFERER' => current_url)
|
||||
end
|
||||
|
||||
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})
|
||||
process_and_follow_redirects(method, path, attributes, 'HTTP_REFERER' => current_url)
|
||||
end
|
||||
|
||||
def process_and_follow_redirects(method, path, attributes = {}, env = {})
|
||||
process(method, path, attributes, env)
|
||||
if driver.follow_redirects?
|
||||
driver.redirect_limit.times do
|
||||
process(:get, last_response["Location"], {}, env) if last_response.redirect?
|
||||
end
|
||||
raise Capybara::InfiniteRedirectError, "redirected more than #{driver.redirect_limit} times, check for infinite redirects." if last_response.redirect?
|
||||
|
||||
return unless driver.follow_redirects?
|
||||
|
||||
driver.redirect_limit.times do
|
||||
process(:get, last_response["Location"], {}, env) if last_response.redirect?
|
||||
end
|
||||
raise Capybara::InfiniteRedirectError, "redirected more than #{driver.redirect_limit} times, check for infinite redirects." if last_response.redirect?
|
||||
end
|
||||
|
||||
def process(method, path, attributes = {}, env = {})
|
||||
|
@ -56,7 +57,7 @@ class Capybara::RackTest::Browser
|
|||
else
|
||||
new_uri.path = request_path if path.start_with?("?")
|
||||
new_uri.path = "/" if new_uri.path.empty?
|
||||
new_uri.path = request_path.sub(%r(/[^/]*$), '/') + new_uri.path unless new_uri.path.start_with?('/')
|
||||
new_uri.path = request_path.sub(%r{/[^/]*$}, '/') + new_uri.path unless new_uri.path.start_with?('/')
|
||||
end
|
||||
new_uri.scheme ||= @current_scheme
|
||||
new_uri.host ||= @current_host
|
||||
|
@ -92,7 +93,7 @@ class Capybara::RackTest::Browser
|
|||
end
|
||||
|
||||
def find(format, selector)
|
||||
if format==:css
|
||||
if format == :css
|
||||
dom.css(selector, Capybara::RackTest::CSSHandlers.new)
|
||||
else
|
||||
dom.xpath(selector)
|
||||
|
|
|
@ -3,10 +3,11 @@
|
|||
class Capybara::RackTest::CSSHandlers < BasicObject
|
||||
include ::Kernel
|
||||
|
||||
def disabled list
|
||||
def disabled(list)
|
||||
list.find_all { |node| node.has_attribute? 'disabled' }
|
||||
end
|
||||
def enabled list
|
||||
|
||||
def enabled(list)
|
||||
list.find_all { |node| !node.has_attribute? 'disabled' }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -74,7 +74,7 @@ class Capybara::RackTest::Driver < Capybara::Driver::Base
|
|||
end
|
||||
|
||||
def find_css(selector)
|
||||
browser.find(:css,selector)
|
||||
browser.find(:css, selector)
|
||||
end
|
||||
|
||||
def html
|
||||
|
|
|
@ -22,9 +22,9 @@ class Capybara::RackTest::Form < Capybara::RackTest::Node
|
|||
params = make_params
|
||||
|
||||
form_element_types = %i[input select textarea]
|
||||
form_elements_xpath=XPath.generate do |x|
|
||||
xpath=x.descendant(*form_element_types).where(~x.attr(:form))
|
||||
xpath=xpath.union(x.anywhere(*form_element_types).where(x.attr(:form) == native[:id])) if native[:id]
|
||||
form_elements_xpath = XPath.generate do |x|
|
||||
xpath = x.descendant(*form_element_types).where(~x.attr(:form))
|
||||
xpath = xpath.union(x.anywhere(*form_element_types).where(x.attr(:form) == native[:id])) if native[:id]
|
||||
xpath.where(~x.attr(:disabled))
|
||||
end.to_s
|
||||
|
||||
|
@ -82,15 +82,15 @@ private
|
|||
end
|
||||
|
||||
def add_input_param(field, params)
|
||||
if %w(radio checkbox).include? field['type']
|
||||
if %w[radio checkbox].include? field['type']
|
||||
if field['checked']
|
||||
node=Capybara::RackTest::Node.new(self.driver, field)
|
||||
node = Capybara::RackTest::Node.new(driver, field)
|
||||
merge_param!(params, field['name'].to_s, node.value.to_s)
|
||||
end
|
||||
elsif %w(submit image).include? field['type']
|
||||
elsif %w[submit image].include? field['type']
|
||||
# TO DO identify the click button here (in document order, rather
|
||||
# than leaving until the end of the params)
|
||||
elsif field['type'] =='file'
|
||||
elsif field['type'] == 'file'
|
||||
if multipart?
|
||||
file = \
|
||||
if (value = field['value']).to_s.empty?
|
||||
|
|
|
@ -20,8 +20,8 @@ class Capybara::RackTest::Node < Capybara::Driver::Node
|
|||
def set(value)
|
||||
return if disabled? || readonly?
|
||||
|
||||
if (Array === value) && !multiple?
|
||||
raise TypeError.new "Value cannot be an Array when 'multiple' attribute is not present. Not a #{value.class}"
|
||||
if value.is_a?(Array) && !multiple?
|
||||
raise TypeError, "Value cannot be an Array when 'multiple' attribute is not present. Not a #{value.class}"
|
||||
end
|
||||
|
||||
if radio?
|
||||
|
@ -55,13 +55,13 @@ class Capybara::RackTest::Node < Capybara::Driver::Node
|
|||
method = self["data-method"] if driver.options[:respect_data_method]
|
||||
method ||= :get
|
||||
driver.follow(method, self[:href].to_s)
|
||||
elsif (tag_name == 'input' and %w(submit image).include?(type)) or
|
||||
((tag_name == 'button') and type.nil? or type == "submit")
|
||||
elsif (tag_name == 'input' and %w[submit image].include?(type)) or
|
||||
(tag_name == 'button' and [nil, "submit"].include?(type))
|
||||
associated_form = form
|
||||
Capybara::RackTest::Form.new(driver, associated_form).submit(self) if associated_form
|
||||
elsif (tag_name == 'input' and %w(checkbox radio).include?(type))
|
||||
elsif tag_name == 'input' and %w[checkbox radio].include?(type)
|
||||
set(!checked?)
|
||||
elsif (tag_name == 'label')
|
||||
elsif tag_name == 'label'
|
||||
labelled_control = if native[:for]
|
||||
find_xpath("//input[@id='#{native[:for]}']").first
|
||||
else
|
||||
|
@ -91,7 +91,7 @@ class Capybara::RackTest::Node < Capybara::Driver::Node
|
|||
end
|
||||
|
||||
def disabled?
|
||||
if %w(option optgroup).include? tag_name
|
||||
if %w[option optgroup].include? tag_name
|
||||
string_node.disabled? || find_xpath("parent::*[self::optgroup or self::select]")[0].disabled?
|
||||
else
|
||||
string_node.disabled? || !find_xpath("parent::fieldset[@disabled] | ancestor::*[not(self::legend) or preceding-sibling::legend][parent::fieldset[@disabled]]").empty?
|
||||
|
@ -153,13 +153,13 @@ private
|
|||
end
|
||||
end
|
||||
|
||||
def set_radio(_value)
|
||||
def set_radio(_value) # rubocop:disable Naming/AccessorMethodName
|
||||
other_radios_xpath = XPath.generate { |x| x.anywhere(:input)[x.attr(:name) == self[:name]] }.to_s
|
||||
driver.dom.xpath(other_radios_xpath).each { |node| node.remove_attribute("checked") }
|
||||
native['checked'] = 'checked'
|
||||
end
|
||||
|
||||
def set_checkbox(value)
|
||||
def set_checkbox(value) # rubocop:disable Naming/AccessorMethodName
|
||||
if value && !native['checked']
|
||||
native['checked'] = 'checked'
|
||||
elsif !value && native['checked']
|
||||
|
@ -167,13 +167,13 @@ private
|
|||
end
|
||||
end
|
||||
|
||||
def set_input(value)
|
||||
def set_input(value) # rubocop:disable Naming/AccessorMethodName
|
||||
if text_or_password? && attribute_is_not_blank?(:maxlength)
|
||||
# Browser behavior for maxlength="0" is inconsistent, so we stick with
|
||||
# Firefox, allowing no input
|
||||
value = value.to_s[0...self[:maxlength].to_i]
|
||||
end
|
||||
if Array === value #Assert multiple attribute is present
|
||||
if value.is_a?(Array) # Assert multiple attribute is present
|
||||
value.each do |v|
|
||||
new_native = native.clone
|
||||
new_native.remove_attribute('value')
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
require 'forwardable'
|
||||
|
||||
module Capybara
|
||||
|
||||
##
|
||||
# A {Capybara::Result} represents a collection of {Capybara::Node::Element} on the page. It is possible to interact with this
|
||||
# collection similar to an Array because it implements Enumerable and offers the following Array methods through delegation:
|
||||
|
@ -100,7 +99,7 @@ module Capybara
|
|||
break if @result_cache.size > max
|
||||
@result_cache << @results_enum.next
|
||||
end
|
||||
return 0 if (@query.options[:between] === @result_cache.size)
|
||||
return 0 if @query.options[:between].include?(@result_cache.size)
|
||||
return -1 if @result_cache.size < min
|
||||
return 1
|
||||
end
|
||||
|
@ -131,7 +130,7 @@ module Capybara
|
|||
failure_message.sub(/(to find)/, 'not \1')
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def full_results
|
||||
loop { @result_cache << @results_enum.next }
|
||||
|
@ -147,7 +146,7 @@ module Capybara
|
|||
# causes a concurrency issue with network requests here
|
||||
# https://github.com/jruby/jruby/issues/4212
|
||||
if RUBY_PLATFORM == 'java'
|
||||
@elements.select(&block).to_enum # non-lazy evaluation
|
||||
@elements.select(&block).to_enum # non-lazy evaluation
|
||||
else
|
||||
@elements.lazy.select(&block)
|
||||
end
|
||||
|
|
|
@ -7,9 +7,9 @@ require 'capybara/rspec/features'
|
|||
require 'capybara/rspec/matcher_proxies'
|
||||
|
||||
RSpec.configure do |config|
|
||||
config.include Capybara::DSL, :type => :feature
|
||||
config.include Capybara::RSpecMatchers, :type => :feature
|
||||
config.include Capybara::RSpecMatchers, :type => :view
|
||||
config.include Capybara::DSL, type: :feature
|
||||
config.include Capybara::RSpecMatchers, type: :feature
|
||||
config.include Capybara::RSpecMatchers, type: :view
|
||||
|
||||
# The before and after blocks must run instantaneously, because Capybara
|
||||
# might not actually be used in all examples where it's included.
|
||||
|
@ -28,4 +28,3 @@ RSpec.configure do |config|
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ module Capybara
|
|||
include ::RSpec::Matchers::Composable
|
||||
|
||||
def and(matcher)
|
||||
Capybara::RSpecMatchers::Compound::And.new(self,matcher)
|
||||
Capybara::RSpecMatchers::Compound::And.new(self, matcher)
|
||||
end
|
||||
|
||||
def and_then(matcher)
|
||||
|
@ -15,12 +15,11 @@ module Capybara
|
|||
Capybara::RSpecMatchers::Compound::Or.new(self, matcher)
|
||||
end
|
||||
|
||||
|
||||
class CapybaraEvaluator
|
||||
def initialize(actual, matcher1, matcher2)
|
||||
@actual = actual
|
||||
@matcher1 = matcher1
|
||||
@matcher2 = matcher2
|
||||
@actual = actual
|
||||
@matcher1 = matcher1
|
||||
@matcher2 = matcher2
|
||||
@match_results = Hash.new { |h, matcher| h[matcher] = matcher.matches?(@actual) }
|
||||
end
|
||||
|
||||
|
@ -34,16 +33,15 @@ module Capybara
|
|||
end
|
||||
|
||||
class And < ::RSpec::Matchers::BuiltIn::Compound::And
|
||||
|
||||
private
|
||||
|
||||
def match(_expected, actual)
|
||||
@evaluator = CapybaraEvaluator.new(actual, matcher1, matcher2)
|
||||
@evaluator = CapybaraEvaluator.new(actual, matcher_1, matcher_2)
|
||||
syncer = sync_element(actual)
|
||||
begin
|
||||
syncer.synchronize do
|
||||
@evaluator.reset
|
||||
raise ::Capybara::ElementNotFound unless [matcher1_matches?, matcher2_matches?].all?
|
||||
raise ::Capybara::ElementNotFound unless [matcher_1_matches?, matcher_2_matches?].all?
|
||||
true
|
||||
end
|
||||
rescue
|
||||
|
@ -63,16 +61,15 @@ module Capybara
|
|||
end
|
||||
|
||||
class Or < ::RSpec::Matchers::BuiltIn::Compound::Or
|
||||
|
||||
private
|
||||
|
||||
def match(_expected, actual)
|
||||
@evaluator = CapybaraEvaluator.new(actual, matcher1, matcher2)
|
||||
@evaluator = CapybaraEvaluator.new(actual, matcher_1, matcher_2)
|
||||
syncer = sync_element(actual)
|
||||
begin
|
||||
syncer.synchronize do
|
||||
@evaluator.reset
|
||||
raise ::Capybara::ElementNotFound unless [matcher1_matches?, matcher2_matches?].any?
|
||||
raise ::Capybara::ElementNotFound unless [matcher_1_matches?, matcher_2_matches?].any?
|
||||
true
|
||||
end
|
||||
rescue
|
||||
|
|
|
@ -18,7 +18,7 @@ module Capybara
|
|||
end
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def wrap_matches?(actual)
|
||||
yield(wrap(actual))
|
||||
|
@ -62,11 +62,11 @@ module Capybara
|
|||
end
|
||||
|
||||
def matches?(actual)
|
||||
wrap_matches?(actual){ |el| el.assert_selector(*@args, &@filter_block) }
|
||||
wrap_matches?(actual) { |el| el.assert_selector(*@args, &@filter_block) }
|
||||
end
|
||||
|
||||
def does_not_match?(actual)
|
||||
wrap_does_not_match?(actual){ |el| el.assert_no_selector(*@args, &@filter_block) }
|
||||
wrap_does_not_match?(actual) { |el| el.assert_no_selector(*@args, &@filter_block) }
|
||||
end
|
||||
|
||||
def description
|
||||
|
@ -85,7 +85,7 @@ module Capybara
|
|||
end
|
||||
|
||||
def matches?(actual)
|
||||
wrap_matches?(actual){ |el| el.assert_all_of_selectors(*@args, &@filter_block) }
|
||||
wrap_matches?(actual) { |el| el.assert_all_of_selectors(*@args, &@filter_block) }
|
||||
end
|
||||
|
||||
def does_not_match?(_actual)
|
||||
|
@ -104,7 +104,7 @@ module Capybara
|
|||
end
|
||||
|
||||
def matches?(actual)
|
||||
wrap_matches?(actual){ |el| el.assert_none_of_selectors(*@args, &@filter_block) }
|
||||
wrap_matches?(actual) { |el| el.assert_none_of_selectors(*@args, &@filter_block) }
|
||||
end
|
||||
|
||||
def does_not_match?(_actual)
|
||||
|
@ -302,43 +302,43 @@ module Capybara
|
|||
|
||||
# RSpec matcher for links
|
||||
# See {Capybara::Node::Matchers#has_link?}
|
||||
def have_link(locator=nil, **options, &optional_filter_block)
|
||||
def have_link(locator = nil, **options, &optional_filter_block)
|
||||
HaveSelector.new(:link, locator, options, &optional_filter_block)
|
||||
end
|
||||
|
||||
# RSpec matcher for buttons
|
||||
# See {Capybara::Node::Matchers#has_button?}
|
||||
def have_button(locator=nil, **options, &optional_filter_block)
|
||||
def have_button(locator = nil, **options, &optional_filter_block)
|
||||
HaveSelector.new(:button, locator, options, &optional_filter_block)
|
||||
end
|
||||
|
||||
# RSpec matcher for links
|
||||
# See {Capybara::Node::Matchers#has_field?}
|
||||
def have_field(locator=nil, **options, &optional_filter_block)
|
||||
def have_field(locator = nil, **options, &optional_filter_block)
|
||||
HaveSelector.new(:field, locator, options, &optional_filter_block)
|
||||
end
|
||||
|
||||
# RSpec matcher for checked fields
|
||||
# See {Capybara::Node::Matchers#has_checked_field?}
|
||||
def have_checked_field(locator=nil, **options, &optional_filter_block)
|
||||
def have_checked_field(locator = nil, **options, &optional_filter_block)
|
||||
HaveSelector.new(:field, locator, options.merge(checked: true), &optional_filter_block)
|
||||
end
|
||||
|
||||
# RSpec matcher for unchecked fields
|
||||
# See {Capybara::Node::Matchers#has_unchecked_field?}
|
||||
def have_unchecked_field(locator=nil, **options, &optional_filter_block)
|
||||
def have_unchecked_field(locator = nil, **options, &optional_filter_block)
|
||||
HaveSelector.new(:field, locator, options.merge(unchecked: true), &optional_filter_block)
|
||||
end
|
||||
|
||||
# RSpec matcher for select elements
|
||||
# See {Capybara::Node::Matchers#has_select?}
|
||||
def have_select(locator=nil, **options, &optional_filter_block)
|
||||
def have_select(locator = nil, **options, &optional_filter_block)
|
||||
HaveSelector.new(:select, locator, options, &optional_filter_block)
|
||||
end
|
||||
|
||||
# RSpec matcher for table elements
|
||||
# See {Capybara::Node::Matchers#has_table?}
|
||||
def have_table(locator=nil, **options, &optional_filter_block)
|
||||
def have_table(locator = nil, **options, &optional_filter_block)
|
||||
HaveSelector.new(:table, locator, options, &optional_filter_block)
|
||||
end
|
||||
|
||||
|
@ -352,4 +352,4 @@ module Capybara
|
|||
BecomeClosed.new(options)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,16 +2,16 @@
|
|||
|
||||
require 'capybara/selector/selector'
|
||||
Capybara::Selector::FilterSet.add(:_field) do
|
||||
filter(:checked, :boolean) { |node, value| not(value ^ node.checked?) }
|
||||
filter(:checked, :boolean) { |node, value| !(value ^ node.checked?) }
|
||||
filter(:unchecked, :boolean) { |node, value| (value ^ node.checked?) }
|
||||
filter(:disabled, :boolean, default: false, skip_if: :all) { |node, value| not(value ^ node.disabled?) }
|
||||
filter(:disabled, :boolean, default: false, skip_if: :all) { |node, value| !(value ^ node.disabled?) }
|
||||
filter(:multiple, :boolean) { |node, value| !(value ^ node.multiple?) }
|
||||
|
||||
expression_filter(:name) { |xpath, val| xpath[XPath.attr(:name) == val] }
|
||||
expression_filter(:placeholder) { |xpath, val| xpath[XPath.attr(:placeholder) == val] }
|
||||
expression_filter(:placeholder) { |xpath, val| xpath[XPath.attr(:placeholder) == val] }
|
||||
|
||||
describe do |checked: nil, unchecked: nil, disabled: nil, multiple: nil, **_options|
|
||||
desc, states = String.new, []
|
||||
desc, states = "".dup, []
|
||||
states << 'checked' if checked || (unchecked == false)
|
||||
states << 'not checked' if unchecked || (checked == false)
|
||||
states << 'disabled' if disabled == true
|
||||
|
@ -80,7 +80,7 @@ Capybara.add_selector(:field) do
|
|||
|
||||
expression_filter(:type) do |expr, type|
|
||||
type = type.to_s
|
||||
if ['textarea', 'select'].include?(type)
|
||||
if %w[textarea select].include?(type)
|
||||
expr.self(type.to_sym)
|
||||
else
|
||||
expr[XPath.attr(:type) == type]
|
||||
|
@ -89,15 +89,15 @@ Capybara.add_selector(:field) do
|
|||
|
||||
filter_set(:_field) # checked/unchecked/disabled/multiple/name/placeholder
|
||||
|
||||
filter(:readonly, :boolean) { |node, value| not(value ^ node.readonly?) }
|
||||
filter(:readonly, :boolean) { |node, value| !(value ^ node.readonly?) }
|
||||
filter(:with) do |node, with|
|
||||
with.is_a?(Regexp) ? node.value =~ with : node.value == with.to_s
|
||||
end
|
||||
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 = "".dup
|
||||
(expression_filters.keys - [:type]).each { |ef| desc << " with #{ef} #{options[ef]}" if options.key?(ef) }
|
||||
desc << " of type #{type.inspect}" if type
|
||||
desc << " with value #{options[:with].to_s.inspect}" if options.has_key?(:with)
|
||||
desc << " with value #{options[:with].to_s.inspect}" if options.key?(:with)
|
||||
desc
|
||||
end
|
||||
end
|
||||
|
@ -167,7 +167,7 @@ Capybara.add_selector(:link) do
|
|||
end
|
||||
|
||||
describe do |**options|
|
||||
desc = String.new()
|
||||
desc = "".dup
|
||||
desc << " with href #{options[:href].inspect}" if options[:href]
|
||||
desc << " with no href attribute" if options.fetch(:href, true).nil?
|
||||
end
|
||||
|
@ -211,10 +211,10 @@ Capybara.add_selector(:button) do
|
|||
res_xpath
|
||||
end
|
||||
|
||||
filter(:disabled, :boolean, default: false, skip_if: :all) { |node, value| not(value ^ node.disabled?) }
|
||||
filter(:disabled, :boolean, default: false, skip_if: :all) { |node, value| !(value ^ node.disabled?) }
|
||||
|
||||
describe do |disabled: nil, **options|
|
||||
desc = String.new
|
||||
desc = "".dup
|
||||
desc << " that is disabled" if disabled == true
|
||||
desc << describe_all_expression_filters(options)
|
||||
desc
|
||||
|
@ -228,10 +228,10 @@ end
|
|||
Capybara.add_selector(:link_or_button) do
|
||||
label "link or button"
|
||||
xpath do |locator, **options|
|
||||
self.class.all.values_at(:link, :button).map {|selector| selector.xpath.call(locator, options)}.reduce(:union)
|
||||
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?) }
|
||||
filter(:disabled, :boolean, default: false, skip_if: :all) { |node, value| node.tag_name == "a" or !(value ^ node.disabled?) }
|
||||
|
||||
describe { |disabled: nil, **_options| " that is disabled" if disabled == true }
|
||||
end
|
||||
|
@ -274,9 +274,9 @@ Capybara.add_selector(:fillable_field) do
|
|||
end
|
||||
|
||||
describe do |options|
|
||||
desc = String.new
|
||||
desc = "".dup
|
||||
desc << describe_all_expression_filters(options)
|
||||
desc << " with value #{options[:with].to_s.inspect}" if options.has_key?(:with)
|
||||
desc << " with value #{options[:with].to_s.inspect}" if options.key?(:with)
|
||||
desc
|
||||
end
|
||||
end
|
||||
|
@ -304,10 +304,10 @@ Capybara.add_selector(:radio_button) do
|
|||
|
||||
filter_set(:_field, %i[checked unchecked disabled name])
|
||||
|
||||
filter(:option) { |node, value| node.value == value.to_s }
|
||||
filter(:option) { |node, value| node.value == value.to_s }
|
||||
|
||||
describe do |option: nil, **options|
|
||||
desc = String.new
|
||||
desc = "".dup
|
||||
desc << " with value #{option.inspect}" if option
|
||||
desc << describe_all_expression_filters(options)
|
||||
desc
|
||||
|
@ -328,7 +328,6 @@ end
|
|||
# @filter [String] :option Match the value
|
||||
#
|
||||
Capybara.add_selector(:checkbox) do
|
||||
|
||||
xpath do |locator, **options|
|
||||
xpath = XPath.descendant(:input)[XPath.attr(:type) == 'checkbox']
|
||||
locate_field(xpath, locator, options)
|
||||
|
@ -336,10 +335,10 @@ Capybara.add_selector(:checkbox) do
|
|||
|
||||
filter_set(:_field, %i[checked unchecked disabled name])
|
||||
|
||||
filter(:option) { |node, value| node.value == value.to_s }
|
||||
filter(:option) { |node, value| node.value == value.to_s }
|
||||
|
||||
describe do |option: nil, **options|
|
||||
desc = String.new
|
||||
desc = "".dup
|
||||
desc << " with value #{option.inspect}" if option
|
||||
desc << describe_all_expression_filters(options)
|
||||
desc
|
||||
|
@ -374,7 +373,7 @@ Capybara.add_selector(:select) do
|
|||
|
||||
filter(:options) do |node, options|
|
||||
actual = if node.visible?
|
||||
node.all(:xpath, './/option', wait: false).map { |option| option.text }
|
||||
node.all(:xpath, './/option', wait: false).map(&:text)
|
||||
else
|
||||
node.all(:xpath, './/option', visible: false, wait: false).map { |option| option.text(:all) }
|
||||
end
|
||||
|
@ -383,9 +382,7 @@ Capybara.add_selector(:select) do
|
|||
|
||||
filter(:with_options) do |node, options|
|
||||
finder_settings = { minimum: 0 }
|
||||
if !node.visible?
|
||||
finder_settings[:visible] = false
|
||||
end
|
||||
finder_settings[:visible] = false unless node.visible?
|
||||
options.all? { |option| node.first(:option, option, finder_settings) }
|
||||
end
|
||||
|
||||
|
@ -400,7 +397,7 @@ Capybara.add_selector(:select) do
|
|||
end
|
||||
|
||||
describe do |options: nil, with_options: nil, selected: nil, with_selected: nil, **opts|
|
||||
desc = String.new
|
||||
desc = "".dup
|
||||
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
|
||||
|
@ -425,13 +422,13 @@ Capybara.add_selector(:option) do
|
|||
xpath
|
||||
end
|
||||
|
||||
filter(:disabled, :boolean) { |node, value| not(value ^ node.disabled?) }
|
||||
filter(:selected, :boolean) { |node, value| not(value ^ node.selected?) }
|
||||
filter(:disabled, :boolean) { |node, value| !(value ^ node.disabled?) }
|
||||
filter(:selected, :boolean) { |node, value| !(value ^ node.selected?) }
|
||||
|
||||
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)
|
||||
desc = "".dup
|
||||
desc << " that is#{' not' unless options[:disabled]} disabled" if options.key?(:disabled)
|
||||
desc << " that is#{' not' unless options[:selected]} selected" if options.key?(:selected)
|
||||
desc
|
||||
end
|
||||
end
|
||||
|
@ -457,7 +454,7 @@ Capybara.add_selector(:file_field) do
|
|||
filter_set(:_field, %i[disabled multiple name])
|
||||
|
||||
describe do |**options|
|
||||
desc = String.new
|
||||
desc = "".dup
|
||||
desc << describe_all_expression_filters(options)
|
||||
desc
|
||||
end
|
||||
|
@ -475,9 +472,9 @@ Capybara.add_selector(:label) do
|
|||
xpath(:for) do |locator, options|
|
||||
xpath = XPath.descendant(:label)
|
||||
xpath = xpath[XPath.string.n.is(locator.to_s) | (XPath.attr(:id) == locator.to_s)] unless locator.nil?
|
||||
if options.has_key?(:for) && !options[:for].is_a?(Capybara::Node::Element)
|
||||
if options.key?(:for) && !options[:for].is_a?(Capybara::Node::Element)
|
||||
with_attr = XPath.attr(:for).equals(options[:for].to_s)
|
||||
labelable_elements = %i(button input keygen meter output progress select textarea)
|
||||
labelable_elements = %i[button input keygen meter output progress select textarea]
|
||||
wrapped = !XPath.attr(:for) &
|
||||
XPath.descendant(*labelable_elements)[XPath.attr(:id) == options[:for].to_s]
|
||||
xpath = xpath[with_attr | wrapped]
|
||||
|
@ -493,13 +490,13 @@ Capybara.add_selector(:label) do
|
|||
field_or_value.find_xpath('./ancestor::label[1]').include? node.base
|
||||
end
|
||||
else
|
||||
#Non element values were handled through the expression filter
|
||||
# Non element values were handled through the expression filter
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
describe do |**options|
|
||||
desc = String.new
|
||||
desc = "".dup
|
||||
desc << " for #{options[:for]}" if options[:for]
|
||||
desc
|
||||
end
|
||||
|
@ -523,7 +520,7 @@ Capybara.add_selector(:table) do
|
|||
end
|
||||
|
||||
describe do |caption: nil, **_options|
|
||||
desc = String.new
|
||||
desc = "".dup
|
||||
desc << " with caption #{caption}" if caption
|
||||
desc
|
||||
end
|
||||
|
@ -547,7 +544,7 @@ Capybara.add_selector(:frame) do
|
|||
end
|
||||
|
||||
describe do |name: nil, **_options|
|
||||
desc = String.new
|
||||
desc = "".dup
|
||||
desc << " with name #{name}" if name
|
||||
desc
|
||||
end
|
||||
|
|
|
@ -2,20 +2,16 @@ module Capybara
|
|||
class Selector
|
||||
class CSS
|
||||
def self.escape(str)
|
||||
out = String.new("")
|
||||
out = "".dup
|
||||
value = str.dup
|
||||
out << value.slice!(0...1) if value =~ /^[-_]/
|
||||
out << if value[0] =~ NMSTART
|
||||
value.slice!(0...1)
|
||||
else
|
||||
escape_char(value.slice!(0...1))
|
||||
end
|
||||
out << value.gsub(/[^a-zA-Z0-9_-]/) {|c| escape_char c}
|
||||
out << (value[0] =~ NMSTART ? value.slice!(0...1) : escape_char(value.slice!(0...1)))
|
||||
out << value.gsub(/[^a-zA-Z0-9_-]/) { |c| escape_char c }
|
||||
out
|
||||
end
|
||||
|
||||
def self.escape_char(c)
|
||||
return "\\%06x" % c.ord() unless c =~ %r{[ -/:-~]}
|
||||
return format("\\%06x", c.ord) unless c =~ %r{[ -/:-~]}
|
||||
"\\#{c}"
|
||||
end
|
||||
|
||||
|
@ -27,4 +23,4 @@ module Capybara
|
|||
NMSTART = /[_a-zA-Z]|#{NONASCII}|#{ESCAPE}/
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -28,7 +28,7 @@ module Capybara
|
|||
def description(**options)
|
||||
options_with_defaults = options.dup
|
||||
filters.each do |name, filter|
|
||||
options_with_defaults[name] = filter.default if filter.default? && !options_with_defaults.has_key?(name)
|
||||
options_with_defaults[name] = filter.default if filter.default? && !options_with_defaults.key?(name)
|
||||
end
|
||||
|
||||
@descriptions.map do |desc|
|
||||
|
@ -45,11 +45,10 @@ module Capybara
|
|||
end
|
||||
|
||||
def expression_filters
|
||||
filters.select { |_n, f| f.nil? || f.is_a?(Filters::ExpressionFilter) }.freeze
|
||||
filters.select { |_n, f| f.nil? || f.is_a?(Filters::ExpressionFilter) }.freeze
|
||||
end
|
||||
|
||||
class << self
|
||||
|
||||
def all
|
||||
@filter_sets ||= {}
|
||||
end
|
||||
|
@ -63,12 +62,12 @@ module Capybara
|
|||
end
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def add_filter(name, filter_class, *types, **options, &block)
|
||||
types.each { |k| options[k] = true}
|
||||
types.each { |k| options[k] = true }
|
||||
filters[name] = filter_class.new(name, block, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,11 +8,11 @@ module Capybara
|
|||
@name = name
|
||||
@block = block
|
||||
@options = options
|
||||
@options[:valid_values] = [true,false] if options[:boolean]
|
||||
@options[:valid_values] = [true, false] if options[:boolean]
|
||||
end
|
||||
|
||||
def default?
|
||||
@options.has_key?(:default)
|
||||
@options.key?(:default)
|
||||
end
|
||||
|
||||
def default
|
||||
|
@ -20,13 +20,13 @@ module Capybara
|
|||
end
|
||||
|
||||
def skip?(value)
|
||||
@options.has_key?(:skip_if) && value == @options[:skip_if]
|
||||
@options.key?(:skip_if) && value == @options[:skip_if]
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def valid_value?(value)
|
||||
!@options.has_key?(:valid_values) || Array(@options[:valid_values]).include?(value)
|
||||
!@options.key?(:valid_values) || Array(@options[:valid_values]).include?(value)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,7 +9,7 @@ module Capybara
|
|||
def apply_filter(expr, value)
|
||||
return expr if skip?(value)
|
||||
|
||||
if !valid_value?(value)
|
||||
unless valid_value?(value)
|
||||
msg = "Invalid value #{value.inspect} passed to expression filter #{@name} - "
|
||||
if default?
|
||||
warn msg + "defaulting to #{default}"
|
||||
|
@ -37,4 +37,4 @@ module Capybara
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,7 +9,7 @@ module Capybara
|
|||
def matches?(node, value)
|
||||
return true if skip?(value)
|
||||
|
||||
if !valid_value?(value)
|
||||
unless valid_value?(value)
|
||||
msg = "Invalid value #{value.inspect} passed to filter #{@name} - "
|
||||
if default?
|
||||
warn msg + "defaulting to #{default}"
|
||||
|
|
|
@ -4,7 +4,7 @@ require 'capybara/selector/filter_set'
|
|||
require 'capybara/selector/css'
|
||||
require 'xpath'
|
||||
|
||||
#Patch XPath to allow a nil condition in where
|
||||
# Patch XPath to allow a nil condition in where
|
||||
module XPath
|
||||
class Renderer
|
||||
undef :where if method_defined?(:where)
|
||||
|
@ -21,7 +21,6 @@ end
|
|||
|
||||
module Capybara
|
||||
class Selector
|
||||
|
||||
attr_reader :name, :format
|
||||
|
||||
class << self
|
||||
|
@ -44,7 +43,7 @@ module Capybara
|
|||
|
||||
def initialize(name, &block)
|
||||
@name = name
|
||||
@filter_set = FilterSet.add(name){}
|
||||
@filter_set = FilterSet.add(name) {}
|
||||
@match = nil
|
||||
@label = nil
|
||||
@failure_message = nil
|
||||
|
@ -135,7 +134,7 @@ module Capybara
|
|||
# @overload label()
|
||||
# @return [String] The currently set label
|
||||
#
|
||||
def label(label=nil)
|
||||
def label(label = nil)
|
||||
@label = label if label
|
||||
@label
|
||||
end
|
||||
|
@ -202,7 +201,7 @@ module Capybara
|
|||
f_set.descriptions.each { |desc| @filter_set.describe(&desc) }
|
||||
end
|
||||
|
||||
def describe &block
|
||||
def describe(&block)
|
||||
@filter_set.describe(&block)
|
||||
end
|
||||
|
||||
|
@ -227,22 +226,22 @@ module Capybara
|
|||
end
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def add_filter(name, filter_class, *types, **options, &block)
|
||||
types.each { |k| options[k] = true}
|
||||
types.each { |k| options[k] = true }
|
||||
custom_filters[name] = filter_class.new(name, block, options)
|
||||
end
|
||||
|
||||
def locate_field(xpath, locator, enable_aria_label: false, **_options)
|
||||
locate_xpath = xpath #need to save original xpath for the label wrap
|
||||
locate_xpath = xpath # Need to save original xpath for the label wrap
|
||||
if locator
|
||||
locator = locator.to_s
|
||||
attr_matchers = [XPath.attr(:id).equals(locator),
|
||||
XPath.attr(:name).equals(locator),
|
||||
XPath.attr(:placeholder).equals(locator),
|
||||
XPath.attr(:id).equals(XPath.anywhere(:label)[XPath.string.n.is(locator)].attr(:for))].reduce(:|)
|
||||
attr_matchers = attr_matchers | XPath.attr(:'aria-label').is(locator) if enable_aria_label
|
||||
attr_matchers |= 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))
|
||||
|
@ -253,7 +252,7 @@ module Capybara
|
|||
end
|
||||
|
||||
def describe_all_expression_filters(**opts)
|
||||
expression_filters.map { |ef| " with #{ef} #{opts[ef]}" if opts.has_key?(ef) }.join
|
||||
expression_filters.map { |ef| " with #{ef} #{opts[ef]}" if opts.key?(ef) }.join
|
||||
end
|
||||
|
||||
def find_by_attr(attribute, value)
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "uri"
|
||||
require "English"
|
||||
|
||||
class Capybara::Selenium::Driver < Capybara::Driver::Base
|
||||
|
||||
DEFAULT_OPTIONS = {
|
||||
:browser => :firefox,
|
||||
browser: :firefox,
|
||||
clear_local_storage: false,
|
||||
clear_session_storage: false
|
||||
}.freeze
|
||||
|
@ -17,10 +17,10 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|||
unless @browser
|
||||
if firefox?
|
||||
options[:desired_capabilities] ||= {}
|
||||
options[:desired_capabilities].merge!({ unexpectedAlertBehaviour: "ignore" })
|
||||
options[:desired_capabilities][:unexpectedAlertBehaviour] = "ignore"
|
||||
end
|
||||
|
||||
@processed_options = options.reject { |key,_val| SPECIAL_OPTIONS.include?(key) }
|
||||
@processed_options = options.reject { |key, _val| SPECIAL_OPTIONS.include?(key) }
|
||||
@browser = Selenium::WebDriver.for(options[:browser], @processed_options)
|
||||
|
||||
@w3c = ((defined?(Selenium::WebDriver::Remote::W3CCapabilities) && @browser.capabilities.is_a?(Selenium::WebDriver::Remote::W3CCapabilities)) ||
|
||||
|
@ -28,7 +28,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|||
main = Process.pid
|
||||
at_exit do
|
||||
# Store the exit status of the test run since it goes away after calling the at_exit proc...
|
||||
@exit_status = $!.status if $!.is_a?(SystemExit)
|
||||
@exit_status = $ERROR_INFO.status if $ERROR_INFO.is_a?(SystemExit)
|
||||
quit if Process.pid == main
|
||||
exit @exit_status if @exit_status # Force exit with stored status
|
||||
end
|
||||
|
@ -89,7 +89,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|||
def needs_server?; true; end
|
||||
|
||||
def execute_script(script, *args)
|
||||
browser.execute_script(script, *args.map { |arg| arg.is_a?(Capybara::Selenium::Node) ? arg.native : arg} )
|
||||
browser.execute_script(script, *args.map { |arg| arg.is_a?(Capybara::Selenium::Node) ? arg.native : arg })
|
||||
end
|
||||
|
||||
def evaluate_script(script, *args)
|
||||
|
@ -99,7 +99,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|||
|
||||
def evaluate_async_script(script, *args)
|
||||
browser.manage.timeouts.script_timeout = Capybara.default_max_wait_time
|
||||
result = browser.execute_async_script(script, *args.map { |arg| arg.is_a?(Capybara::Selenium::Node) ? arg.native : arg} )
|
||||
result = browser.execute_async_script(script, *args.map { |arg| arg.is_a?(Capybara::Selenium::Node) ? arg.native : arg })
|
||||
unwrap_script_result(result)
|
||||
end
|
||||
|
||||
|
@ -109,43 +109,43 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|||
|
||||
def reset!
|
||||
# Use instance variable directly so we avoid starting the browser just to reset the session
|
||||
if @browser
|
||||
navigated = false
|
||||
start_time = Capybara::Helpers.monotonic_time
|
||||
begin
|
||||
if !navigated
|
||||
# Only trigger a navigation if we haven't done it already, otherwise it
|
||||
# can trigger an endless series of unload modals
|
||||
begin
|
||||
@browser.manage.delete_all_cookies
|
||||
clear_storage
|
||||
rescue Selenium::WebDriver::Error::UnhandledError
|
||||
# delete_all_cookies fails when we've previously gone
|
||||
# to about:blank, so we rescue this error and do nothing
|
||||
# instead.
|
||||
end
|
||||
@browser.navigate.to("about:blank")
|
||||
end
|
||||
navigated = true
|
||||
return unless @browser
|
||||
|
||||
#Ensure the page is empty and trigger an UnhandledAlertError for any modals that appear during unload
|
||||
until find_xpath("/html/body/*").empty? do
|
||||
raise Capybara::ExpectationNotMet.new('Timed out waiting for Selenium session reset') if (Capybara::Helpers.monotonic_time - start_time) >= 10
|
||||
sleep 0.05
|
||||
end
|
||||
rescue Selenium::WebDriver::Error::UnhandledAlertError, Selenium::WebDriver::Error::UnexpectedAlertOpenError
|
||||
# This error is thrown if an unhandled alert is on the page
|
||||
# Firefox appears to automatically dismiss this alert, chrome does not
|
||||
# We'll try to accept it
|
||||
navigated = false
|
||||
start_time = Capybara::Helpers.monotonic_time
|
||||
begin
|
||||
unless navigated
|
||||
# Only trigger a navigation if we haven't done it already, otherwise it
|
||||
# can trigger an endless series of unload modals
|
||||
begin
|
||||
@browser.switch_to.alert.accept
|
||||
sleep 0.25 # allow time for the modal to be handled
|
||||
rescue modal_error
|
||||
# The alert is now gone - nothing to do
|
||||
@browser.manage.delete_all_cookies
|
||||
clear_storage
|
||||
rescue Selenium::WebDriver::Error::UnhandledError
|
||||
# delete_all_cookies fails when we've previously gone
|
||||
# to about:blank, so we rescue this error and do nothing
|
||||
# instead.
|
||||
end
|
||||
# try cleaning up the browser again
|
||||
retry
|
||||
@browser.navigate.to("about:blank")
|
||||
end
|
||||
navigated = true
|
||||
|
||||
# Ensure the page is empty and trigger an UnhandledAlertError for any modals that appear during unload
|
||||
until find_xpath("/html/body/*").empty?
|
||||
raise Capybara::ExpectationNotMet, 'Timed out waiting for Selenium session reset' if (Capybara::Helpers.monotonic_time - start_time) >= 10
|
||||
sleep 0.05
|
||||
end
|
||||
rescue Selenium::WebDriver::Error::UnhandledAlertError, Selenium::WebDriver::Error::UnexpectedAlertOpenError
|
||||
# This error is thrown if an unhandled alert is on the page
|
||||
# Firefox appears to automatically dismiss this alert, chrome does not
|
||||
# We'll try to accept it
|
||||
begin
|
||||
@browser.switch_to.alert.accept
|
||||
sleep 0.25 # allow time for the modal to be handled
|
||||
rescue modal_error
|
||||
# The alert is now gone - nothing to do
|
||||
end
|
||||
# try cleaning up the browser again
|
||||
retry
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -269,7 +269,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|||
::Selenium::WebDriver::Error::ElementNotInteractableError,
|
||||
::Selenium::WebDriver::Error::ElementClickInterceptedError,
|
||||
::Selenium::WebDriver::Error::InvalidElementStateError,
|
||||
::Selenium::WebDriver::Error::ElementNotSelectableError,
|
||||
::Selenium::WebDriver::Error::ElementNotSelectableError
|
||||
]
|
||||
end
|
||||
|
||||
|
@ -303,8 +303,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|||
return false
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
# @api private
|
||||
def browser_name
|
||||
|
@ -393,7 +392,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|||
# rubocop:enable Metrics/MethodLength
|
||||
|
||||
def within_given_window(handle)
|
||||
original_handle = self.current_window_handle
|
||||
original_handle = current_window_handle
|
||||
if handle == original_handle
|
||||
yield
|
||||
else
|
||||
|
@ -408,7 +407,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|||
# Selenium has its own built in wait (2 seconds)for a modal to show up, so this wait is really the minimum time
|
||||
# Actual wait time may be longer than specified
|
||||
wait = Selenium::WebDriver::Wait.new(
|
||||
timeout: options.fetch(:wait, session_options.default_max_wait_time) || 0 ,
|
||||
timeout: options.fetch(:wait, session_options.default_max_wait_time) || 0,
|
||||
ignore: modal_error
|
||||
)
|
||||
begin
|
||||
|
@ -418,7 +417,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|||
alert.text.match(regexp) ? alert : nil
|
||||
end
|
||||
rescue Selenium::WebDriver::Error::TimeOutError
|
||||
raise Capybara::ModalNotFound.new("Unable to find modal dialog#{" with #{text}" if text}")
|
||||
raise Capybara::ModalNotFound, "Unable to find modal dialog#{" with #{text}" if text}"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -426,7 +425,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|||
# Selenium has its own built in wait (2 seconds)for a modal to show up, so this wait is really the minimum time
|
||||
# Actual wait time may be longer than specified
|
||||
wait = Selenium::WebDriver::Wait.new(
|
||||
timeout: options.fetch(:wait, session_options.default_max_wait_time) || 0 ,
|
||||
timeout: options.fetch(:wait, session_options.default_max_wait_time) || 0,
|
||||
ignore: modal_error
|
||||
)
|
||||
begin
|
||||
|
@ -438,7 +437,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|||
if alert_text.match(regexp)
|
||||
alert_text
|
||||
else
|
||||
raise Capybara::ModalNotFound.new("Unable to find modal dialog#{" with #{text}" if text}")
|
||||
raise Capybara::ModalNotFound, "Unable to find modal dialog#{" with #{text}" if text}"
|
||||
end
|
||||
elsif called.nil?
|
||||
# page changed so modal_handler data has gone away
|
||||
|
@ -449,7 +448,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|||
end
|
||||
end
|
||||
rescue Selenium::WebDriver::Error::TimeOutError
|
||||
raise Capybara::ModalNotFound.new("Unable to find modal dialog#{" with #{options[:text]}" if options[:text]}")
|
||||
raise Capybara::ModalNotFound, "Unable to find modal dialog#{" with #{options[:text]}" if options[:text]}"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -475,21 +474,19 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|||
end
|
||||
|
||||
def load_selenium
|
||||
begin
|
||||
require 'selenium-webdriver'
|
||||
# Fix for selenium-webdriver 3.4.0 which misnamed these
|
||||
if !defined?(::Selenium::WebDriver::Error::ElementNotInteractableError)
|
||||
::Selenium::WebDriver::Error.const_set('ElementNotInteractableError', Class.new(::Selenium::WebDriver::Error::WebDriverError))
|
||||
end
|
||||
if !defined?(::Selenium::WebDriver::Error::ElementClickInterceptedError)
|
||||
::Selenium::WebDriver::Error.const_set('ElementClickInterceptedError', Class.new(::Selenium::WebDriver::Error::WebDriverError))
|
||||
end
|
||||
rescue LoadError => e
|
||||
if e.message =~ /selenium-webdriver/
|
||||
raise LoadError, "Capybara's selenium driver is unable to load `selenium-webdriver`, please install the gem and add `gem 'selenium-webdriver'` to your Gemfile if you are using bundler."
|
||||
else
|
||||
raise e
|
||||
end
|
||||
require 'selenium-webdriver'
|
||||
# Fix for selenium-webdriver 3.4.0 which misnamed these
|
||||
unless defined?(::Selenium::WebDriver::Error::ElementNotInteractableError)
|
||||
::Selenium::WebDriver::Error.const_set('ElementNotInteractableError', Class.new(::Selenium::WebDriver::Error::WebDriverError))
|
||||
end
|
||||
unless defined?(::Selenium::WebDriver::Error::ElementClickInterceptedError)
|
||||
::Selenium::WebDriver::Error.const_set('ElementClickInterceptedError', Class.new(::Selenium::WebDriver::Error::WebDriverError))
|
||||
end
|
||||
rescue LoadError => e
|
||||
if e.message =~ /selenium-webdriver/
|
||||
raise LoadError, "Capybara's selenium driver is unable to load `selenium-webdriver`, please install the gem and add `gem 'selenium-webdriver'` to your Gemfile if you are using bundler."
|
||||
else
|
||||
raise e
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Capybara::Selenium::Node < Capybara::Driver::Node
|
||||
|
||||
def visible_text
|
||||
# Selenium doesn't normalize Unicode whitespace.
|
||||
Capybara::Helpers.normalize_whitespace(native.text)
|
||||
|
@ -41,8 +40,8 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
|
|||
tag_name = self.tag_name
|
||||
type = self[:type]
|
||||
|
||||
if (Array === value) && !multiple?
|
||||
raise ArgumentError.new "Value cannot be an Array when 'multiple' attribute is not present. Not a #{value.class}"
|
||||
if value.is_a?(Array) && !multiple?
|
||||
raise ArgumentError, "Value cannot be an Array when 'multiple' attribute is not present. Not a #{value.class}"
|
||||
end
|
||||
|
||||
case tag_name
|
||||
|
@ -60,9 +59,7 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
|
|||
when 'textarea'
|
||||
set_text(value, options)
|
||||
else
|
||||
if content_editable?
|
||||
set_content_editable(value)
|
||||
end
|
||||
set_content_editable(value) if content_editable?
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -71,11 +68,11 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
|
|||
end
|
||||
|
||||
def unselect_option
|
||||
raise Capybara::UnselectNotAllowed, "Cannot unselect option from single select box." if !select_node.multiple?
|
||||
raise Capybara::UnselectNotAllowed, "Cannot unselect option from single select box." unless select_node.multiple?
|
||||
native.click if selected?
|
||||
end
|
||||
|
||||
def click(keys=[], options={})
|
||||
def click(keys = [], options = {})
|
||||
if keys.empty? && !(options[:x] && options[:y])
|
||||
native.click
|
||||
else
|
||||
|
@ -94,13 +91,13 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
|
|||
e.message =~ /Other element would receive the click/
|
||||
begin
|
||||
driver.execute_script("arguments[0].scrollIntoView({behavior: 'instant', block: 'center', inline: 'center'})", self)
|
||||
rescue
|
||||
rescue # Swallow error if scrollIntoView with options isn't supported
|
||||
end
|
||||
end
|
||||
raise e
|
||||
end
|
||||
|
||||
def right_click(keys=[], options={})
|
||||
def right_click(keys = [], options = {})
|
||||
scroll_if_needed do
|
||||
action_with_modifiers(keys, options) do |a|
|
||||
if options[:x] && options[:y]
|
||||
|
@ -112,7 +109,7 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
|
|||
end
|
||||
end
|
||||
|
||||
def double_click(keys=[], options={})
|
||||
def double_click(keys = [], options = {})
|
||||
scroll_if_needed do
|
||||
action_with_modifiers(keys, options) do |a|
|
||||
if options[:x] && options[:y]
|
||||
|
@ -158,7 +155,7 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
|
|||
def disabled?
|
||||
# workaround for selenium-webdriver/geckodriver reporting elements as enabled when they are nested in disabling elements
|
||||
if driver.marionette?
|
||||
if %w(option optgroup).include? tag_name
|
||||
if %w[option optgroup].include? tag_name
|
||||
!native.enabled? || find_xpath("parent::*[self::optgroup or self::select]")[0].disabled?
|
||||
else
|
||||
!native.enabled? || !find_xpath("parent::fieldset[@disabled] | ancestor::*[not(self::legend) or preceding-sibling::legend][parent::fieldset[@disabled]]").empty?
|
||||
|
@ -208,7 +205,7 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
|
|||
result.unshift node.tag_name
|
||||
else
|
||||
index = siblings.index(node)
|
||||
result.unshift "#{node.tag_name}[#{index+1}]"
|
||||
result.unshift "#{node.tag_name}[#{index + 1}]"
|
||||
end
|
||||
else
|
||||
result.unshift node.tag_name
|
||||
|
@ -219,6 +216,7 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
|
|||
end
|
||||
|
||||
private
|
||||
|
||||
# a reference to the select node if this is an option node
|
||||
def select_node
|
||||
find_xpath('./ancestor::select[1]').first
|
||||
|
@ -258,7 +256,7 @@ private
|
|||
yield
|
||||
end
|
||||
|
||||
def set_file(value)
|
||||
def set_file(value) # rubocop:disable Naming/AccessorMethodName
|
||||
path_names = value.to_s.empty? ? [] : value
|
||||
if driver.chrome?
|
||||
native.send_keys(Array(path_names).join("\n"))
|
||||
|
@ -267,8 +265,8 @@ private
|
|||
end
|
||||
end
|
||||
|
||||
def set_content_editable(value)
|
||||
#ensure we are focused on the element
|
||||
def set_content_editable(value) # rubocop:disable Naming/AccessorMethodName
|
||||
# Ensure we are focused on the element
|
||||
click
|
||||
|
||||
script = <<-JS
|
||||
|
|
|
@ -61,7 +61,7 @@ module Capybara
|
|||
|
||||
attr_reader :app, :port, :host
|
||||
|
||||
def initialize(app, port=Capybara.server_port, host=Capybara.server_host, server_errors=Capybara.server_errors)
|
||||
def initialize(app, port = Capybara.server_port, host = Capybara.server_host, server_errors = Capybara.server_errors)
|
||||
@app = app
|
||||
@server_thread = nil # suppress warnings
|
||||
@host, @port, @server_errors = host, port, server_errors
|
||||
|
|
|
@ -4,7 +4,6 @@ require 'capybara/session/matchers'
|
|||
require 'addressable/uri'
|
||||
|
||||
module Capybara
|
||||
|
||||
##
|
||||
#
|
||||
# The Session class represents a single user's interaction with the system. The Session can use
|
||||
|
@ -75,7 +74,7 @@ module Capybara
|
|||
attr_reader :mode, :app, :server
|
||||
attr_accessor :synchronized
|
||||
|
||||
def initialize(mode, app=nil)
|
||||
def initialize(mode, app = nil)
|
||||
raise TypeError, "The second parameter to Session::new should be a rack app if passed." if app && !app.respond_to?(:call)
|
||||
@@instance_created = true
|
||||
@mode = mode
|
||||
|
@ -94,8 +93,8 @@ module Capybara
|
|||
|
||||
def driver
|
||||
@driver ||= begin
|
||||
unless Capybara.drivers.has_key?(mode)
|
||||
other_drivers = Capybara.drivers.keys.map { |key| key.inspect }
|
||||
unless Capybara.drivers.key?(mode)
|
||||
other_drivers = Capybara.drivers.keys.map(&:inspect)
|
||||
raise Capybara::DriverNotFoundError, "no driver called #{mode.inspect} was found, available drivers: #{other_drivers.join(', ')}"
|
||||
end
|
||||
driver = Capybara.drivers[mode].call(app)
|
||||
|
@ -145,7 +144,7 @@ module Capybara
|
|||
raise CapybaraError, "Your application server raised an error - It has been raised in your test code because Capybara.raise_server_errors == true"
|
||||
end
|
||||
rescue CapybaraError
|
||||
#needed to get the cause set correctly in JRuby -- otherwise we could just do raise @server.error
|
||||
# needed to get the cause set correctly in JRuby -- otherwise we could just do raise @server.error
|
||||
raise @server.error, @server.error.message, @server.error.backtrace
|
||||
ensure
|
||||
@server.reset_error!
|
||||
|
@ -197,7 +196,7 @@ module Capybara
|
|||
# Addressable doesn't support opaque URIs - we want nil here
|
||||
return nil if uri.scheme == "about"
|
||||
path = uri.path
|
||||
path if path and not path.empty?
|
||||
path if path && !path.empty?
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -259,7 +258,7 @@ module Capybara
|
|||
if visit_uri.relative?
|
||||
uri_base.port ||= @server.port if @server && config.always_include_port
|
||||
|
||||
visit_uri_parts = visit_uri.to_hash.delete_if { |_k,v| v.nil? }
|
||||
visit_uri_parts = visit_uri.to_hash.delete_if { |_k, v| v.nil? }
|
||||
|
||||
# Useful to people deploying to a subdirectory
|
||||
# and/or single page apps where only the url fragment changes
|
||||
|
@ -335,7 +334,7 @@ module Capybara
|
|||
# @raise [Capybara::ElementNotFound] If the scope can't be found before time expires
|
||||
#
|
||||
def within(*args)
|
||||
new_scope = if args.first.is_a?(Capybara::Node::Base) then args.first else find(*args) end
|
||||
new_scope = args.first.is_a?(Capybara::Node::Base) ? args.first : find(*args)
|
||||
begin
|
||||
scopes.push(new_scope)
|
||||
yield
|
||||
|
@ -390,15 +389,19 @@ module Capybara
|
|||
driver.switch_to_frame(frame)
|
||||
scopes.push(:frame)
|
||||
when :parent
|
||||
raise Capybara::ScopeError, "`switch_to_frame(:parent)` cannot be called from inside a descendant frame's "\
|
||||
"`within` block." if scopes.last() != :frame
|
||||
if scopes.last != :frame
|
||||
raise Capybara::ScopeError, "`switch_to_frame(:parent)` cannot be called from inside a descendant frame's "\
|
||||
"`within` block."
|
||||
end
|
||||
scopes.pop
|
||||
driver.switch_to_frame(:parent)
|
||||
when :top
|
||||
idx = scopes.index(:frame)
|
||||
if idx
|
||||
raise Capybara::ScopeError, "`switch_to_frame(:top)` cannot be called from inside a descendant frame's "\
|
||||
"`within` block." if scopes.slice(idx..-1).any? {|scope| ![:frame, nil].include?(scope)}
|
||||
if scopes.slice(idx..-1).any? { |scope| ![:frame, nil].include?(scope) }
|
||||
raise Capybara::ScopeError, "`switch_to_frame(:top)` cannot be called from inside a descendant frame's "\
|
||||
"`within` block."
|
||||
end
|
||||
scopes.slice!(idx..-1)
|
||||
driver.switch_to_frame(:top)
|
||||
end
|
||||
|
@ -477,11 +480,9 @@ module Capybara
|
|||
#
|
||||
def switch_to_window(window = nil, **options, &window_locator)
|
||||
block_given = block_given?
|
||||
if window && block_given
|
||||
raise ArgumentError, "`switch_to_window` can take either a block or a window, not both"
|
||||
elsif !window && !block_given
|
||||
raise ArgumentError, "`switch_to_window`: either window or block should be provided"
|
||||
elsif !scopes.last.nil?
|
||||
raise ArgumentError, "`switch_to_window` can take either a block or a window, not both" if window && block_given
|
||||
raise ArgumentError, "`switch_to_window`: either window or block should be provided" if !window && !block_given
|
||||
unless scopes.last.nil?
|
||||
raise Capybara::ScopeError, "`switch_to_window` is not supposed to be invoked from "\
|
||||
"`within` or `within_frame` blocks."
|
||||
end
|
||||
|
@ -585,7 +586,7 @@ module Capybara
|
|||
driver.execute_script(script)
|
||||
else
|
||||
raise Capybara::NotSupportedByDriverError, "The current driver does not support execute_script arguments" if driver.method(:execute_script).arity == 1
|
||||
driver.execute_script(script, *args.map { |arg| arg.is_a?(Capybara::Node::Element) ? arg.base : arg} )
|
||||
driver.execute_script(script, *args.map { |arg| arg.is_a?(Capybara::Node::Element) ? arg.base : arg })
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -604,7 +605,7 @@ module Capybara
|
|||
driver.evaluate_script(script)
|
||||
else
|
||||
raise Capybara::NotSupportedByDriverError, "The current driver does not support evaluate_script arguments" if driver.method(:evaluate_script).arity == 1
|
||||
driver.evaluate_script(script, *args.map { |arg| arg.is_a?(Capybara::Node::Element) ? arg.base : arg} )
|
||||
driver.evaluate_script(script, *args.map { |arg| arg.is_a?(Capybara::Node::Element) ? arg.base : arg })
|
||||
end
|
||||
element_script_result(result)
|
||||
end
|
||||
|
@ -622,7 +623,7 @@ module Capybara
|
|||
driver.evaluate_async_script(script)
|
||||
else
|
||||
raise Capybara::NotSupportedByDriverError, "The current driver does not support evaluate_async_script arguments" if driver.method(:evaluate_async_script).arity == 1
|
||||
driver.evaluate_async_script(script, *args.map { |arg| arg.is_a?(Capybara::Node::Element) ? arg.base : arg} )
|
||||
driver.evaluate_async_script(script, *args.map { |arg| arg.is_a?(Capybara::Node::Element) ? arg.base : arg })
|
||||
end
|
||||
element_script_result(result)
|
||||
end
|
||||
|
@ -647,7 +648,7 @@ module Capybara
|
|||
# @return [String] the message shown in the modal
|
||||
# @raise [Capybara::ModalNotFound] if modal dialog hasn't been found
|
||||
#
|
||||
def accept_alert(text=nil, **options, &blk)
|
||||
def accept_alert(text = nil, **options, &blk)
|
||||
accept_modal(:alert, text, options, &blk)
|
||||
end
|
||||
|
||||
|
@ -657,7 +658,7 @@ module Capybara
|
|||
#
|
||||
# @macro modal_params
|
||||
#
|
||||
def accept_confirm(text=nil, **options, &blk)
|
||||
def accept_confirm(text = nil, **options, &blk)
|
||||
accept_modal(:confirm, text, options, &blk)
|
||||
end
|
||||
|
||||
|
@ -667,7 +668,7 @@ module Capybara
|
|||
#
|
||||
# @macro modal_params
|
||||
#
|
||||
def dismiss_confirm(text=nil, **options, &blk)
|
||||
def dismiss_confirm(text = nil, **options, &blk)
|
||||
dismiss_modal(:confirm, text, options, &blk)
|
||||
end
|
||||
|
||||
|
@ -678,7 +679,7 @@ module Capybara
|
|||
# @macro modal_params
|
||||
# @option options [String] :with Response to provide to the prompt
|
||||
#
|
||||
def accept_prompt(text=nil, **options, &blk)
|
||||
def accept_prompt(text = nil, **options, &blk)
|
||||
accept_modal(:prompt, text, options, &blk)
|
||||
end
|
||||
|
||||
|
@ -688,7 +689,7 @@ module Capybara
|
|||
#
|
||||
# @macro modal_params
|
||||
#
|
||||
def dismiss_prompt(text=nil, **options, &blk)
|
||||
def dismiss_prompt(text = nil, **options, &blk)
|
||||
dismiss_modal(:prompt, text, options, &blk)
|
||||
end
|
||||
|
||||
|
@ -826,6 +827,7 @@ module Capybara
|
|||
Capybara::ReadOnlySessionConfig.new(Capybara.session_options)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@instance_created = false
|
||||
|
@ -838,20 +840,18 @@ module Capybara
|
|||
driver.dismiss_modal(type, modal_options(text_or_options, options), &blk)
|
||||
end
|
||||
|
||||
def modal_options(text=nil, **options)
|
||||
def modal_options(text = nil, **options)
|
||||
options[:text] ||= text unless text.nil?
|
||||
options[:wait] ||= config.default_max_wait_time
|
||||
options
|
||||
end
|
||||
|
||||
def open_file(path)
|
||||
begin
|
||||
require "launchy"
|
||||
Launchy.open(path)
|
||||
rescue LoadError
|
||||
warn "File saved to #{path}."
|
||||
warn "Please install the launchy gem to open the file automatically."
|
||||
end
|
||||
require "launchy"
|
||||
Launchy.open(path)
|
||||
rescue LoadError
|
||||
warn "File saved to #{path}."
|
||||
warn "Please install the launchy gem to open the file automatically."
|
||||
end
|
||||
|
||||
def prepare_path(path, extension)
|
||||
|
@ -892,7 +892,7 @@ module Capybara
|
|||
find(*args)
|
||||
when Integer
|
||||
idx = args[0]
|
||||
all(:frame, minimum: idx+1)[idx]
|
||||
all(:frame, minimum: idx + 1)[idx]
|
||||
else
|
||||
raise TypeError
|
||||
end
|
||||
|
@ -912,9 +912,7 @@ module Capybara
|
|||
begin
|
||||
driver.window_handles.each do |handle|
|
||||
driver.switch_to_window handle
|
||||
if yield
|
||||
return Window.new(self, handle)
|
||||
end
|
||||
return Window.new(self, handle) if yield
|
||||
end
|
||||
rescue => e
|
||||
driver.switch_to_window(original_window_handle)
|
||||
|
@ -926,6 +924,5 @@ module Capybara
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,51 +5,51 @@ require 'delegate'
|
|||
module Capybara
|
||||
class SessionConfig
|
||||
OPTIONS = %i[always_include_port run_server default_selector default_max_wait_time ignore_hidden_elements
|
||||
automatic_reload match exact exact_text raise_server_errors visible_text_only
|
||||
automatic_label_click enable_aria_label save_path asset_host default_host app_host
|
||||
server_host server_port server_errors].freeze
|
||||
automatic_reload match exact exact_text raise_server_errors visible_text_only
|
||||
automatic_label_click enable_aria_label save_path asset_host default_host app_host
|
||||
server_host server_port server_errors].freeze
|
||||
|
||||
attr_accessor(*OPTIONS)
|
||||
|
||||
##
|
||||
#@!method always_include_port
|
||||
# See {Capybara.configure}
|
||||
#@!method run_server
|
||||
# See {Capybara.configure}
|
||||
#@!method default_selector
|
||||
# See {Capybara.configure}
|
||||
#@!method default_max_wait_time
|
||||
# See {Capybara.configure}
|
||||
#@!method ignore_hidden_elements
|
||||
# See {Capybara.configure}
|
||||
#@!method automatic_reload
|
||||
# See {Capybara.configure}
|
||||
#@!method match
|
||||
# See {Capybara.configure}
|
||||
#@!method exact
|
||||
# See {Capybara.configure}
|
||||
#@!method raise_server_errors
|
||||
# See {Capybara.configure}
|
||||
#@!method visible_text_only
|
||||
# See {Capybara.configure}
|
||||
#@!method automatic_label_click
|
||||
# See {Capybara.configure}
|
||||
#@!method enable_aria_label
|
||||
# See {Capybara.configure}
|
||||
#@!method save_path
|
||||
# See {Capybara.configure}
|
||||
#@!method asset_host
|
||||
# See {Capybara.configure}
|
||||
#@!method default_host
|
||||
# See {Capybara.configure}
|
||||
#@!method app_host
|
||||
# See {Capybara.configure}
|
||||
#@!method server_host
|
||||
# See {Capybara.configure}
|
||||
#@!method server_port
|
||||
# See {Capybara.configure}
|
||||
#@!method server_errors
|
||||
# See {Capybara.configure}
|
||||
# @!method always_include_port
|
||||
# See {Capybara.configure}
|
||||
# @!method run_server
|
||||
# See {Capybara.configure}
|
||||
# @!method default_selector
|
||||
# See {Capybara.configure}
|
||||
# @!method default_max_wait_time
|
||||
# See {Capybara.configure}
|
||||
# @!method ignore_hidden_elements
|
||||
# See {Capybara.configure}
|
||||
# @!method automatic_reload
|
||||
# See {Capybara.configure}
|
||||
# @!method match
|
||||
# See {Capybara.configure}
|
||||
# @!method exact
|
||||
# See {Capybara.configure}
|
||||
# @!method raise_server_errors
|
||||
# See {Capybara.configure}
|
||||
# @!method visible_text_only
|
||||
# See {Capybara.configure}
|
||||
# @!method automatic_label_click
|
||||
# See {Capybara.configure}
|
||||
# @!method enable_aria_label
|
||||
# See {Capybara.configure}
|
||||
# @!method save_path
|
||||
# See {Capybara.configure}
|
||||
# @!method asset_host
|
||||
# See {Capybara.configure}
|
||||
# @!method default_host
|
||||
# See {Capybara.configure}
|
||||
# @!method app_host
|
||||
# See {Capybara.configure}
|
||||
# @!method server_host
|
||||
# See {Capybara.configure}
|
||||
# @!method server_port
|
||||
# See {Capybara.configure}
|
||||
# @!method server_errors
|
||||
# See {Capybara.configure}
|
||||
|
||||
remove_method :server_host
|
||||
|
||||
|
@ -68,13 +68,13 @@ module Capybara
|
|||
|
||||
remove_method :app_host=
|
||||
def app_host=(url)
|
||||
raise ArgumentError.new("Capybara.app_host should be set to a url (http://www.example.com)") unless url.nil? || (url =~ URI::DEFAULT_PARSER.make_regexp)
|
||||
raise ArgumentError, "Capybara.app_host should be set to a url (http://www.example.com)" unless url.nil? || (url =~ URI::DEFAULT_PARSER.make_regexp)
|
||||
@app_host = url
|
||||
end
|
||||
|
||||
remove_method :default_host=
|
||||
def default_host=(url)
|
||||
raise ArgumentError.new("Capybara.default_host should be set to a url (http://www.example.com)") unless url.nil? || (url =~ URI::DEFAULT_PARSER.make_regexp)
|
||||
raise ArgumentError, "Capybara.default_host should be set to a url (http://www.example.com)" unless url.nil? || (url =~ URI::DEFAULT_PARSER.make_regexp)
|
||||
@default_host = url
|
||||
end
|
||||
|
||||
|
@ -91,4 +91,4 @@ module Capybara
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,7 +20,7 @@ module Capybara
|
|||
# @return [true]
|
||||
#
|
||||
def assert_current_path(path, **options)
|
||||
_verify_current_path(path,options) { |query| raise Capybara::ExpectationNotMet, query.failure_message unless query.resolves_for?(self) }
|
||||
_verify_current_path(path, options) { |query| raise Capybara::ExpectationNotMet, query.failure_message unless query.resolves_for?(self) }
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -34,7 +34,7 @@ module Capybara
|
|||
# @return [true]
|
||||
#
|
||||
def assert_no_current_path(path, **options)
|
||||
_verify_current_path(path,options) { |query| raise Capybara::ExpectationNotMet, query.negative_failure_message if query.resolves_for?(self) }
|
||||
_verify_current_path(path, options) { |query| raise Capybara::ExpectationNotMet, query.negative_failure_message if query.resolves_for?(self) }
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -67,7 +67,7 @@ module Capybara
|
|||
return false
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def _verify_current_path(path, options)
|
||||
query = Capybara::Queries::CurrentPathQuery.new(path, options)
|
||||
|
|
|
@ -102,7 +102,7 @@ module Capybara
|
|||
end
|
||||
|
||||
def eql?(other)
|
||||
other.kind_of?(self.class) && @session == other.session && @handle == other.handle
|
||||
other.is_a?(self.class) && @session == other.session && @handle == other.handle
|
||||
end
|
||||
alias_method :==, :eql?
|
||||
|
||||
|
@ -114,9 +114,9 @@ module Capybara
|
|||
"#<Window @handle=#{@handle.inspect}>"
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def wait_for_stable_size(seconds=session.config.default_max_wait_time)
|
||||
def wait_for_stable_size(seconds = session.config.default_max_wait_time)
|
||||
res = yield if block_given?
|
||||
prev_size = size
|
||||
start_time = Capybara::Helpers.monotonic_time
|
||||
|
@ -130,9 +130,7 @@ module Capybara
|
|||
end
|
||||
|
||||
def raise_unless_current(what)
|
||||
unless current?
|
||||
raise Capybara::WindowError, "#{what} not current window is not possible."
|
||||
end
|
||||
raise Capybara::WindowError, "#{what} not current window is not possible." unless current?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
require 'spec_helper'
|
||||
require 'selenium-webdriver'
|
||||
require 'shared_selenium_session'
|
||||
require 'rspec/shared_spec_matchers'
|
||||
|
||||
CHROME_DRIVER = if ENV['HEADLESS'] then :selenium_chrome_headless else :selenium_chrome end
|
||||
|
||||
|
@ -12,7 +13,7 @@ CHROME_DRIVER = if ENV['HEADLESS'] then :selenium_chrome_headless else :selenium
|
|||
Capybara.register_driver :selenium_chrome_clear_storage do |app|
|
||||
chrome_options = {
|
||||
browser: :chrome,
|
||||
options: ::Selenium::WebDriver::Chrome::Options.new()
|
||||
options: ::Selenium::WebDriver::Chrome::Options.new
|
||||
}
|
||||
chrome_options[:options].args << 'headless' if ENV['HEADLESS']
|
||||
Capybara::Selenium::Driver.new(app, chrome_options.merge(clear_local_storage: true, clear_session_storage: true))
|
||||
|
@ -31,6 +32,7 @@ Capybara::SpecHelper.run_specs TestSessions::Chrome, CHROME_DRIVER.to_s, capybar
|
|||
RSpec.describe "Capybara::Session with chrome" do
|
||||
include Capybara::SpecHelper
|
||||
include_examples "Capybara::Session", TestSessions::Chrome, CHROME_DRIVER
|
||||
include_examples Capybara::RSpecMatchers, TestSessions::Chrome, CHROME_DRIVER
|
||||
|
||||
context "storage" do
|
||||
describe "#reset!" do
|
||||
|
|
Loading…
Reference in New Issue