Rubocop driven cleanup

This commit is contained in:
Thomas Walpole 2018-01-08 12:23:54 -08:00
parent e0afe31a1e
commit e68051f6ac
57 changed files with 236 additions and 194 deletions

View File

@ -1,9 +1,10 @@
AllCops:
DisabledByDefault: true
DisabledByDefault: false
TargetRubyVersion: 2.2.2
Exclude:
- 'spec/**/*'
- 'lib/capybara/spec/**/*'
- 'capybara.gemspec'
#################### Lint ################################
Lint/AmbiguousOperator:
@ -1016,11 +1017,6 @@ Layout/SpaceAroundOperators:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-operators'
Enabled: false
Layout/SpaceInsideBrackets:
Description: 'No spaces after [ or before ].'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-spaces-braces'
Enabled: false
Layout/SpaceInsideHashLiteralBraces:
Description: "Use spaces inside hash literal braces - or don't."
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-operators'

View File

@ -34,11 +34,10 @@ end
task :travis do
if ENV['CAPYBARA_FF']
Rake::Task[:spec_marionette].invoke
Rake::Task[:cucumber].invoke
else
Rake::Task[:spec_chrome].invoke
Rake::Task[:cucumber].invoke
end
Rake::Task[:cucumber].invoke
end
task :release do
@ -53,4 +52,4 @@ task :release do
'git push --tags'
end
task :default => [:spec, :cucumber]
task :default => %i[spec cucumber]

View File

@ -1,4 +1,3 @@
# -*- encoding: utf-8 -*-
lib = File.expand_path('../lib/', __FILE__)
$:.unshift lib unless $:.include?(lib)
@ -20,29 +19,29 @@ Gem::Specification.new do |s|
s.require_paths = ["lib"]
s.summary = "Capybara aims to simplify the process of integration testing Rack applications, such as Rails, Sinatra or Merb"
s.add_runtime_dependency("nokogiri", ["~> 1.8"])
s.add_runtime_dependency("addressable")
s.add_runtime_dependency("mini_mime", [">= 0.1.3"])
s.add_runtime_dependency("nokogiri", ["~> 1.8"])
s.add_runtime_dependency("rack", [">= 1.6.0"])
s.add_runtime_dependency("rack-test", [">= 0.6.3"])
s.add_runtime_dependency("xpath", ["~>3.0"])
s.add_runtime_dependency("addressable")
s.add_development_dependency("selenium-webdriver", [">= 3.0", "< 4.0", "!=3.4.1"])
s.add_development_dependency("webdrivers") if ENV['TRAVIS']
s.add_development_dependency("sinatra", [">= 1.4.0"])
s.add_development_dependency("rspec", [">= 3.4.0"])
s.add_development_dependency("launchy", [">= 2.0.4"])
s.add_development_dependency("yard", [">= 0.9.0"])
s.add_development_dependency("fuubar", [">= 1.0.0"])
s.add_development_dependency("cucumber", [">= 2.3.0"])
s.add_development_dependency("minitest")
s.add_development_dependency("rake")
s.add_development_dependency("puma")
s.add_development_dependency("erubi") # dependency specification needed by rbx
s.add_development_dependency("fuubar", [">= 1.0.0"])
s.add_development_dependency("launchy", [">= 2.0.4"])
s.add_development_dependency("minitest")
s.add_development_dependency("puma")
s.add_development_dependency("rake")
s.add_development_dependency("rspec", [">= 3.4.0"])
s.add_development_dependency("selenium-webdriver", [">= 3.0", "< 4.0", "!=3.4.1"])
s.add_development_dependency("sinatra", [">= 1.4.0"])
s.add_development_dependency("webdrivers") if ENV['TRAVIS']
s.add_development_dependency("yard", [">= 0.9.0"])
if RUBY_ENGINE == 'rbx' then
s.add_development_dependency("racc")
s.add_development_dependency("json")
s.add_development_dependency("racc")
s.add_development_dependency("rubysl")
end

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
When(/^I visit the (?:root|home) page$/) do
visit('/')
end

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
require 'rubygems'
require 'bundler/setup'

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
require 'timeout'
require 'nokogiri'
require 'xpath'

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
require 'forwardable'
require 'capybara/session/config'
@ -6,7 +7,7 @@ module Capybara
class Config
extend Forwardable
OPTIONS = [:app, :reuse_server, :threadsafe, :default_wait_time, :server, :default_driver, :javascript_driver]
OPTIONS = %i[app reuse_server threadsafe default_wait_time server default_driver javascript_driver].freeze
attr_accessor :app
attr_reader :reuse_server, :threadsafe

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
require 'capybara/dsl'
require 'capybara/rspec/matchers'
require 'capybara/rspec/matcher_proxies'

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
class Capybara::Driver::Base
attr_writer :session
@ -138,8 +139,7 @@ class Capybara::Driver::Base
false
end
def reset!
end
def reset!; end
def needs_server?
false

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
module Capybara
module Driver
class Node

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
require 'capybara'
module Capybara

View File

@ -1,4 +1,3 @@
# encoding: UTF-8
# frozen_string_literal: true
module Capybara

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
require 'minitest'
require 'capybara/dsl'
@ -43,15 +44,15 @@ module Capybara
%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 <<-EOM, __FILE__, __LINE__ + 1
self.class_eval <<-ASSERTION, __FILE__, __LINE__ + 1
def #{assertion_name} *args
self.assertions +=1
subject, *args = determine_subject(args)
subject, args = determine_subject(args)
subject.#{assertion_name}(*args)
rescue Capybara::ExpectationNotMet => e
raise ::Minitest::Assertion, e.message
end
EOM
ASSERTION
end
alias_method :refute_title, :assert_no_title
@ -84,30 +85,29 @@ module Capybara
%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 <<-EOM, __FILE__, __LINE__ + 1
self.class_eval <<-ASSERTION, __FILE__, __LINE__ + 1
def #{assertion_name} *args, &optional_filter_block
self.assertions +=1
subject, *args = determine_subject(args)
subject, args = determine_subject(args)
subject.#{assertion_name}(*args, &optional_filter_block)
rescue Capybara::ExpectationNotMet => e
raise ::Minitest::Assertion, e.message
end
EOM
ASSERTION
end
alias_method :refute_selector, :assert_no_selector
alias_method :refute_matches_selector, :assert_not_matches_selector
# rubocop:disable Lint/UnusedBlockArgument
%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)
subject, args = determine_subject(args)
locator, options = extract_locator(args)
assert_selector(subject, selector_type.to_sym, locator, options, &optional_filter_block)
end
define_method "assert_no_#{selector_type}" do |*args, &optional_filter_block|
subject, *args = determine_subject(args)
subject, args = determine_subject(args)
locator, options = extract_locator(args)
assert_no_selector(subject, selector_type.to_sym, locator, options, &optional_filter_block)
end
@ -116,13 +116,13 @@ module Capybara
%w(checked unchecked).each do |field_type|
define_method "assert_#{field_type}_field" do |*args, &optional_filter_block|
subject, *args = determine_subject(args)
subject, args = determine_subject(args)
locator, options = extract_locator(args)
assert_selector(subject, :field, locator, options.merge(field_type.to_sym => true), &optional_filter_block)
end
define_method "assert_no_#{field_type}_field" do |*args, &optional_filter_block|
subject, *args = determine_subject(args)
subject, args = determine_subject(args)
locator, options = extract_locator(args)
assert_no_selector(subject, :field, locator, options.merge(field_type.to_sym => true), &optional_filter_block)
end
@ -131,17 +131,16 @@ module Capybara
%w(xpath css).each do |selector_type|
define_method "assert_matches_#{selector_type}" do |*args, &optional_filter_block|
subject, *args = determine_subject(args)
subject, args = determine_subject(args)
assert_matches_selector(subject, selector_type.to_sym, *args, &optional_filter_block)
end
define_method "assert_not_matches_#{selector_type}" do |*args, &optional_filter_block|
subject, *args = determine_subject(args)
subject, args = determine_subject(args)
assert_not_matches_selector(subject, selector_type.to_sym, *args, &optional_filter_block)
end
alias_method "refute_matches_#{selector_type}", "assert_not_matches_#{selector_type}"
end
# rubocop:enable Lint/UnusedBlockArgument
##
# Assertion that there is xpath
@ -263,9 +262,9 @@ module Capybara
def determine_subject(args)
case args.first
when Capybara::Session, Capybara::Node::Base, Capybara::Node::Simple
args
[args.shift, args]
else
[page, *args]
[page, args]
end
end

View File

@ -17,17 +17,17 @@ module Capybara
[["assert_matches_#{assertion}", "must_match_#{assertion}"],
["refute_matches_#{assertion}", "wont_match_#{assertion}"]]
end).each do |(meth, new_name)|
self.class_eval <<-EOM, __FILE__, __LINE__ + 1
self.class_eval <<-ASSERTION, __FILE__, __LINE__ + 1
def #{new_name} *args, &block
::Minitest::Expectation.new(self, ::Minitest::Spec.current).#{new_name}(*args, &block)
end
EOM
ASSERTION
::Minitest::Expectation.class_eval <<-EOM, __FILE__, __LINE__ + 1
::Minitest::Expectation.class_eval <<-ASSERTION, __FILE__, __LINE__ + 1
def #{new_name} *args, &block
ctx.#{meth}(target, *args, &block)
end
EOM
ASSERTION
end
##

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
module Capybara
module Node
module Actions

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
module Capybara
module Node

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
module Capybara
module Node

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
module Capybara
module Node
module DocumentMatchers

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
module Capybara
module Node
@ -405,7 +406,7 @@ module Capybara
private
def verify_click_options_support(method)
if base.method(method).arity == 0
if base.method(method).arity.zero?
raise ArgumentError, "The current driver does not support #{method} options"
end
end

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
module Capybara
module Node
module Finders
@ -255,7 +256,7 @@ 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 = [:count, :minimum, :between].any? {|k| options.key?(k)}
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)

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
module Capybara
module Node
module Matchers
@ -91,7 +92,7 @@ module Capybara
#
def assert_selector(*args, &optional_filter_block)
_verify_selector_result(args, optional_filter_block) do |result, query|
unless result.matches_count? && ((!result.empty?) || query.expects_none?)
unless result.matches_count? && (!result.empty? || query.expects_none?)
raise Capybara::ExpectationNotMet, result.failure_message
end
end
@ -163,7 +164,7 @@ module Capybara
#
def assert_no_selector(*args, &optional_filter_block)
_verify_selector_result(args, optional_filter_block) do |result, query|
if result.matches_count? && ((!result.empty?) || query.expects_none?)
if result.matches_count? && (!result.empty? || query.expects_none?)
raise Capybara::ExpectationNotMet, result.negative_failure_message
end
end
@ -662,22 +663,22 @@ module Capybara
private
def _verify_selector_result(query_args, optional_filter_block, &result_block)
def _verify_selector_result(query_args, optional_filter_block)
_set_query_session_options(query_args)
query = Capybara::Queries::SelectorQuery.new(*query_args, &optional_filter_block)
synchronize(query.wait) do
result = query.resolve_for(self)
result_block.call(result, query)
yield result, query
end
return true
end
def _verify_match_result(query_args, optional_filter_block, &result_block)
def _verify_match_result(query_args, optional_filter_block)
_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_block.call(result)
yield result
end
return true
end

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
module Capybara
module Node
@ -45,7 +46,7 @@ module Capybara
attr_name = name.to_s
if attr_name == 'value'
value
elsif 'input' == tag_name and 'checkbox' == native[:type] and 'checked' == attr_name
elsif tag_name == 'input' and native[:type] == 'checkbox' and attr_name == 'checked'
native['checked'] == 'checked'
else
native[attr_name]

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
module Capybara
module Queries
class AncestorQuery < MatchQuery

View File

@ -1,9 +1,10 @@
# frozen_string_literal: true
module Capybara
# @api private
module Queries
class BaseQuery
COUNT_KEYS = [:count, :minimum, :maximum, :between]
COUNT_KEYS = %i[count minimum maximum between].freeze
attr_reader :options
attr_writer :session_options

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
require 'addressable/uri'
module Capybara
@ -42,12 +43,12 @@ module Capybara
private
def failure_message_helper(negated = '')
verb = (@expected_path.is_a?(Regexp))? 'match' : 'equal'
verb = @expected_path.is_a?(Regexp) ? 'match' : 'equal'
"expected #{@actual_path.inspect}#{negated} to #{verb} #{@expected_path.inspect}"
end
def valid_keys
[:wait, :url, :ignore_query]
%i[wait url ignore_query]
end
end

View File

@ -1,11 +1,12 @@
# frozen_string_literal: true
module Capybara
module Queries
class SelectorQuery < Queries::BaseQuery
attr_accessor :selector, :locator, :options, :expression, :find, :negative
VALID_KEYS = COUNT_KEYS + [:text, :id, :class, :visible, :exact, :exact_text, :match, :wait, :filter_set]
VALID_MATCH = [:first, :smart, :prefer_exact, :one]
VALID_KEYS = COUNT_KEYS + %i[text id class visible exact exact_text match wait filter_set]
VALID_MATCH = %i[first smart prefer_exact one].freeze
def initialize(*args, session_options:, **options, &filter_block)
@resolved_node = nil
@ -14,15 +15,14 @@ module Capybara
self.session_options = session_options
@filter_block = filter_block
if args[0].is_a?(Symbol)
@selector = Selector.all.fetch(args.shift) do |selector_type|
@selector = if args[0].is_a?(Symbol)
Selector.all.fetch(args.shift) do |selector_type|
raise ArgumentError, "Unknown selector type (:#{selector_type})"
end
@locator = args.shift
else
@selector = Selector.all.values.find { |s| s.match?(args[0]) }
@locator = args.shift
Selector.all.values.find { |s| s.match?(args[0]) }
end
@locator = args.shift
@selector ||= Selector.all[session_options.default_selector]
warn "Unused parameters passed to #{self.class.name} : #{args}" unless args.empty?
@ -225,12 +225,10 @@ module Capybara
def matches_text_filter(node, text_option)
regexp = if text_option.is_a?(Regexp)
text_option
elsif exact_text == true
/\A#{Regexp.escape(text_option.to_s)}\z/
else
if exact_text == true
/\A#{Regexp.escape(text_option.to_s)}\z/
else
Regexp.escape(text_option.to_s)
end
Regexp.escape(text_option.to_s)
end
text_visible = visible
text_visible = :all if text_visible == :hidden

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
module Capybara
module Queries
class SiblingQuery < MatchQuery

View File

@ -1,11 +1,12 @@
# frozen_string_literal: true
module Capybara
# @api private
module Queries
class TextQuery < BaseQuery
def initialize(type=nil, expected_text, session_options:, **options)
@type = type
@type = (Capybara.ignore_hidden_elements or Capybara.visible_text_only) ? :visible : :all if @type.nil?
@type = Capybara.ignore_hidden_elements or Capybara.visible_text_only ? :visible : :all if @type.nil?
@expected_text = expected_text
@options = options
super(@options)
@ -80,7 +81,7 @@ module Capybara
end
def valid_keys
COUNT_KEYS + [:wait, :exact]
COUNT_KEYS + %i[wait exact]
end
def check_visible_text?

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
module Capybara
# @api private
module Queries
@ -30,12 +31,12 @@ module Capybara
private
def failure_message_helper(negated = '')
verb = (@expected_title.is_a?(Regexp))? 'match' : 'include'
verb = @expected_title.is_a?(Regexp) ? 'match' : 'include'
"expected #{@actual_title.inspect}#{negated} to #{verb} #{@expected_title.inspect}"
end
def valid_keys
[:wait, :exact]
%i[wait exact]
end
end
end

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
class Capybara::RackTest::Browser
include ::Rack::Test::Methods

View File

@ -1,10 +1,11 @@
# frozen_string_literal: true
class Capybara::RackTest::CSSHandlers < BasicObject
include ::Kernel
def disabled list
list.find_all { |node| node.has_attribute? 'disabled' }
end
end
def enabled list
list.find_all { |node| !node.has_attribute? 'disabled' }
end

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
require 'rack/test'
require 'rack/utils'
require 'mini_mime'
@ -10,7 +11,7 @@ class Capybara::RackTest::Driver < Capybara::Driver::Base
respect_data_method: false,
follow_redirects: true,
redirect_limit: 5
}
}.freeze
attr_reader :app, :options
def initialize(app, **options)

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
class Capybara::RackTest::Form < Capybara::RackTest::Node
# This only needs to inherit from Rack::Test::UploadedFile because Rack::Test checks for
# the class specifically when determining whether to construct the request as multipart.
@ -20,7 +21,7 @@ class Capybara::RackTest::Form < Capybara::RackTest::Node
def params(button)
params = make_params
form_element_types=[:input, :select, :textarea]
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]

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
class Capybara::RackTest::Node < Capybara::Driver::Node
def all_text
Capybara::Helpers.normalize_whitespace(native.text)

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
require 'capybara/dsl'
Capybara.app = Rack::Builder.new do

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
require 'forwardable'
module Capybara
@ -41,7 +42,7 @@ module Capybara
loop do
next_result = @results_enum.next
@result_cache << next_result
block.call(next_result)
yield next_result
end
self
end
@ -109,7 +110,7 @@ module Capybara
# rubocop:enable Metrics/MethodLength
def matches_count?
compare_count == 0
compare_count.zero?
end
def failure_message

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
require 'rspec/core'
require 'capybara/dsl'
require 'capybara/rspec/matchers'

View File

@ -17,10 +17,10 @@ module Capybara
class CapybaraEvaluator
def initialize(actual, matcher_1, matcher_2)
def initialize(actual, matcher1, matcher2)
@actual = actual
@matcher_1 = matcher_1
@matcher_2 = matcher_2
@matcher1 = matcher1
@matcher2 = matcher2
@match_results = Hash.new { |h, matcher| h[matcher] = matcher.matches?(@actual) }
end
@ -38,12 +38,12 @@ module Capybara
private
def match(_expected, actual)
@evaluator = CapybaraEvaluator.new(actual, matcher_1, matcher_2)
@evaluator = CapybaraEvaluator.new(actual, matcher1, matcher2)
syncer = sync_element(actual)
begin
syncer.synchronize do
@evaluator.reset
raise ::Capybara::ElementNotFound unless [matcher_1_matches?, matcher_2_matches?].all?
raise ::Capybara::ElementNotFound unless [matcher1_matches?, matcher2_matches?].all?
true
end
rescue
@ -67,12 +67,12 @@ module Capybara
private
def match(_expected, actual)
@evaluator = CapybaraEvaluator.new(actual, matcher_1, matcher_2)
@evaluator = CapybaraEvaluator.new(actual, matcher1, matcher2)
syncer = sync_element(actual)
begin
syncer.synchronize do
@evaluator.reset
raise ::Capybara::ElementNotFound unless [matcher_1_matches?, matcher_2_matches?].any?
raise ::Capybara::ElementNotFound unless [matcher1_matches?, matcher2_matches?].any?
true
end
rescue

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
RSpec.shared_context "Capybara Features", capybara_feature: true do
instance_eval do
alias background before

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
module Capybara
module RSpecMatcherProxies
def all(*args)

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
module Capybara
module RSpecMatchers
class Matcher
@ -87,7 +88,7 @@ module Capybara
wrap_matches?(actual){ |el| el.assert_all_of_selectors(*@args, &@filter_block) }
end
def does_not_match?(actual)
def does_not_match?(_actual)
raise ArgumentError, "The have_all_selectors matcher does not support use with not_to/should_not"
end
@ -106,7 +107,7 @@ module Capybara
wrap_matches?(actual){ |el| el.assert_none_of_selectors(*@args, &@filter_block) }
end
def does_not_match?(actual)
def does_not_match?(_actual)
raise ArgumentError, "The have_none_of_selectors matcher does not support use with not_to/should_not"
end
@ -142,7 +143,7 @@ module Capybara
# are set just for backwards compatability
@type = args.shift if args.first.is_a?(Symbol)
@content = args.shift
@options = (args.first.is_a?(Hash))? args.first : {}
@options = args.first.is_a?(Hash) ? args.first : {}
end
def matches?(actual)

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
require 'capybara/selector/selector'
Capybara::Selector::FilterSet.add(:_field) do
filter(:checked, :boolean) { |node, value| not(value ^ node.checked?) }
@ -22,6 +23,9 @@ Capybara::Selector::FilterSet.add(:_field) do
end
end
# rubocop:disable Metrics/BlockLength
# rubocop:disable Metrics/ParameterLists
##
#
# Select elements by XPath expression
@ -130,7 +134,6 @@ end
# @filter [String, Regexp,nil] :href Matches the normalized href of the link, if nil will find <a> elements with no href attribute
#
Capybara.add_selector(:link) do
# rubocop: disable Metrics/ParameterLists:
xpath(:title, :alt) do |locator, href: true, enable_aria_label: false, alt: nil, title: nil, **_options|
xpath = XPath.descendant(:a)
xpath = if href.nil?
@ -140,10 +143,10 @@ Capybara.add_selector(:link) do
end
unless locator.nil?
locator = locator.to_s
matchers = [ XPath.attr(:id).equals(locator),
XPath.string.n.is(locator),
XPath.attr(:title).is(locator),
XPath.descendant(:img)[XPath.attr(:alt).is(locator)] ].reduce(:|)
matchers = [XPath.attr(:id).equals(locator),
XPath.string.n.is(locator),
XPath.attr(:title).is(locator),
XPath.descendant(:img)[XPath.attr(:alt).is(locator)]].reduce(:|)
matchers = matchers.or XPath.attr(:'aria-label').is(locator) if enable_aria_label
xpath = xpath[matchers]
end
@ -264,7 +267,7 @@ Capybara.add_selector(:fillable_field) do
end
end
filter_set(:_field, [:disabled, :multiple, :name, :placeholder])
filter_set(:_field, %i[disabled multiple name placeholder])
filter(:with) do |node, with|
with.is_a?(Regexp) ? node.value =~ with : node.value == with.to_s
@ -299,7 +302,7 @@ Capybara.add_selector(:radio_button) do
locate_field(xpath, locator, options)
end
filter_set(:_field, [:checked, :unchecked, :disabled, :name])
filter_set(:_field, %i[checked unchecked disabled name])
filter(:option) { |node, value| node.value == value.to_s }
@ -331,7 +334,7 @@ Capybara.add_selector(:checkbox) do
locate_field(xpath, locator, options)
end
filter_set(:_field, [:checked, :unchecked, :disabled, :name])
filter_set(:_field, %i[checked unchecked disabled name])
filter(:option) { |node, value| node.value == value.to_s }
@ -367,13 +370,13 @@ Capybara.add_selector(:select) do
locate_field(xpath, locator, options)
end
filter_set(:_field, [:disabled, :multiple, :name, :placeholder])
filter_set(:_field, %i[disabled multiple name placeholder])
filter(:options) do |node, options|
if node.visible?
actual = node.all(:xpath, './/option', wait: false).map { |option| option.text }
actual = if node.visible?
node.all(:xpath, './/option', wait: false).map { |option| option.text }
else
actual = node.all(:xpath, './/option', visible: false, wait: false).map { |option| option.text(:all) }
node.all(:xpath, './/option', visible: false, wait: false).map { |option| option.text(:all) }
end
options.sort == actual.sort
end
@ -451,7 +454,7 @@ Capybara.add_selector(:file_field) do
locate_field(xpath, locator, options)
end
filter_set(:_field, [:disabled, :multiple, :name])
filter_set(:_field, %i[disabled multiple name])
describe do |**options|
desc = String.new
@ -549,3 +552,6 @@ Capybara.add_selector(:frame) do
desc
end
end
# rubocop:enable Metrics/BlockLength
# rubocop:enable Metrics/ParameterLists

View File

@ -19,7 +19,7 @@ module Capybara
"\\#{c}"
end
S = '\u{80}-\u{D7FF}\u{E000}-\u{FFFD}\u{10000}-\u{10FFFF}'
S = '\u{80}-\u{D7FF}\u{E000}-\u{FFFD}\u{10000}-\u{10FFFF}'.freeze
H = /[0-9a-fA-F]/
UNICODE = /\\#{H}{1,6}[ \t\r\n\f]?/
NONASCII = /[#{S}]/

View File

@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'capybara/selector/filters/node_filter'
require 'capybara/selector/filters/expression_filter'

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
require 'capybara/selector/filter'
module Capybara

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
module Capybara
class Selector
module Filters

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
require 'capybara/selector/filters/base'
module Capybara
@ -24,8 +25,7 @@ module Capybara
end
class IdentityExpressionFilter < ExpressionFilter
def initialize
end
def initialize; end
def default?
false

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
require 'capybara/selector/filters/base'
module Capybara

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
require 'capybara/selector/filter_set'
require 'capybara/selector/css'
require 'xpath'
@ -12,7 +13,7 @@ module XPath
if !condition.empty?
"#{on}[#{condition}]"
else
"#{on}"
on.to_s
end
end
end
@ -237,10 +238,10 @@ module Capybara
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 = [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
locate_xpath = locate_xpath[attr_matchers]

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
require "uri"
class Capybara::Selenium::Driver < Capybara::Driver::Base
@ -7,8 +8,8 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
:browser => :firefox,
clear_local_storage: false,
clear_session_storage: false
}
SPECIAL_OPTIONS = [:browser, :clear_local_storage, :clear_session_storage]
}.freeze
SPECIAL_OPTIONS = %i[browser clear_local_storage clear_session_storage].freeze
attr_reader :app, :options
@ -260,14 +261,15 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
end
def invalid_element_errors
[::Selenium::WebDriver::Error::StaleElementReferenceError,
::Selenium::WebDriver::Error::UnhandledError,
::Selenium::WebDriver::Error::ElementNotVisibleError,
::Selenium::WebDriver::Error::InvalidSelectorError, # Work around a race condition that can occur with chromedriver and #go_back/#go_forward
::Selenium::WebDriver::Error::ElementNotInteractableError,
::Selenium::WebDriver::Error::ElementClickInterceptedError,
::Selenium::WebDriver::Error::InvalidElementStateError,
::Selenium::WebDriver::Error::ElementNotSelectableError,
[
::Selenium::WebDriver::Error::StaleElementReferenceError,
::Selenium::WebDriver::Error::UnhandledError,
::Selenium::WebDriver::Error::ElementNotVisibleError,
::Selenium::WebDriver::Error::InvalidSelectorError, # Work around a race condition that can occur with chromedriver and #go_back/#go_forward
::Selenium::WebDriver::Error::ElementNotInteractableError,
::Selenium::WebDriver::Error::ElementClickInterceptedError,
::Selenium::WebDriver::Error::InvalidElementStateError,
::Selenium::WebDriver::Error::ElementNotSelectableError,
]
end
@ -407,7 +409,8 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
# Actual wait time may be longer than specified
wait = Selenium::WebDriver::Wait.new(
timeout: options.fetch(:wait, session_options.default_max_wait_time) || 0 ,
ignore: modal_error)
ignore: modal_error
)
begin
wait.until do
alert = @browser.switch_to.alert
@ -424,7 +427,8 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
# Actual wait time may be longer than specified
wait = Selenium::WebDriver::Wait.new(
timeout: options.fetch(:wait, session_options.default_max_wait_time) || 0 ,
ignore: modal_error)
ignore: modal_error
)
begin
wait.until do
called, alert_text = evaluate_script('window.capybara && window.capybara.current_modal_status()')
@ -454,7 +458,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
end
def silenced_unknown_error_messages
[ /Error communicating with the remote browser/ ]
[/Error communicating with the remote browser/]
end
def unwrap_script_result(arg)

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
class Capybara::Selenium::Node < Capybara::Driver::Node
def visible_text
@ -226,27 +227,25 @@ private
def set_text(value, clear: nil, **)
if value.to_s.empty? && clear.nil?
native.clear
elsif clear == :backspace
# Clear field by sending the correct number of backspace keys.
backspaces = [:backspace] * self.value.to_s.length
native.send_keys(*(backspaces + [value.to_s]))
elsif clear == :none
native.send_keys(value.to_s)
elsif clear.is_a? Array
native.send_keys(*clear, value.to_s)
else
if clear == :backspace
# Clear field by sending the correct number of backspace keys.
backspaces = [:backspace] * self.value.to_s.length
native.send_keys(*(backspaces + [value.to_s]))
elsif clear == :none
native.send_keys(value.to_s)
elsif clear.is_a? Array
native.send_keys(*clear, value.to_s)
else
# Clear field by JavaScript assignment of the value property.
# Script can change a readonly element which user input cannot, so
# don't execute if readonly.
driver.execute_script "arguments[0].value = ''", self
native.send_keys(value.to_s)
end
# Clear field by JavaScript assignment of the value property.
# Script can change a readonly element which user input cannot, so
# don't execute if readonly.
driver.execute_script "arguments[0].value = ''", self
native.send_keys(value.to_s)
end
end
def scroll_if_needed(&block)
block.call
def scroll_if_needed
yield
rescue ::Selenium::WebDriver::Error::MoveTargetOutOfBoundsError
script = <<-JS
try {
@ -256,7 +255,7 @@ private
}
JS
driver.execute_script(script, self)
block.call
yield
end
def set_file(value)

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
require 'uri'
require 'net/http'
require 'rack'
@ -43,7 +44,7 @@ module Capybara
begin
@app.call(env)
rescue *@server_errors => e
@error = e unless @error
@error ||= e
raise e
ensure
@counter.decrement

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
require 'capybara/session/matchers'
require 'addressable/uri'
@ -38,38 +39,37 @@ module Capybara
class Session
include Capybara::SessionMatchers
NODE_METHODS = [
:all, :first, :attach_file, :text, :check, :choose,
:click_link_or_button, :click_button, :click_link, :field_labeled,
:fill_in, :find, :find_all, :find_button, :find_by_id, :find_field, :find_link,
:has_content?, :has_text?, :has_css?, :has_no_content?, :has_no_text?,
:has_no_css?, :has_no_xpath?, :resolve, :has_xpath?, :select, :uncheck,
:has_link?, :has_no_link?, :has_button?, :has_no_button?, :has_field?,
:has_no_field?, :has_checked_field?, :has_unchecked_field?,
:has_no_table?, :has_table?, :unselect, :has_select?, :has_no_select?,
:has_selector?, :has_no_selector?, :click_on, :has_no_checked_field?,
:has_no_unchecked_field?, :query, :assert_selector, :assert_no_selector,
:assert_all_of_selectors, :assert_none_of_selectors,
:refute_selector, :assert_text, :assert_no_text
]
NODE_METHODS = %i[
all first attach_file text check choose
click_link_or_button click_button click_link field_labeled
fill_in find find_all find_button find_by_id find_field find_link
has_content? has_text? has_css? has_no_content? has_no_text?
has_no_css? has_no_xpath? resolve has_xpath? select uncheck
has_link? has_no_link? has_button? has_no_button? has_field?
has_no_field? has_checked_field? has_unchecked_field?
has_no_table? has_table? unselect has_select? has_no_select?
has_selector? has_no_selector? click_on has_no_checked_field?
has_no_unchecked_field? query assert_selector assert_no_selector
assert_all_of_selectors assert_none_of_selectors
refute_selector assert_text assert_no_text
].freeze
# @api private
DOCUMENT_METHODS = [
:title, :assert_title, :assert_no_title, :has_title?, :has_no_title?
]
SESSION_METHODS = [
:body, :html, :source, :current_url, :current_host, :current_path,
:execute_script, :evaluate_script, :visit, :refresh, :go_back, :go_forward,
:within, :within_element, :within_fieldset, :within_table, :within_frame, :switch_to_frame,
:current_window, :windows, :open_new_window, :switch_to_window, :within_window, :window_opened_by,
:save_page, :save_and_open_page, :save_screenshot,
:save_and_open_screenshot, :reset_session!, :response_headers,
:status_code, :current_scope,
:assert_current_path, :assert_no_current_path, :has_current_path?, :has_no_current_path?
] + DOCUMENT_METHODS
MODAL_METHODS = [
:accept_alert, :accept_confirm, :dismiss_confirm, :accept_prompt,
:dismiss_prompt
]
DOCUMENT_METHODS = %i[
title assert_title assert_no_title has_title? has_no_title?
].freeze
SESSION_METHODS = %i[
body html source current_url current_host current_path
execute_script evaluate_script visit refresh go_back go_forward
within within_element within_fieldset within_table within_frame switch_to_frame
current_window windows open_new_window switch_to_window within_window window_opened_by
save_page save_and_open_page save_screenshot
save_and_open_screenshot reset_session! response_headers
status_code current_scope
assert_current_path assert_no_current_path has_current_path? has_no_current_path?
].freeze + DOCUMENT_METHODS
MODAL_METHODS = %i[
accept_alert accept_confirm dismiss_confirm accept_prompt dismiss_prompt
].freeze
DSL_METHODS = NODE_METHODS + SESSION_METHODS + MODAL_METHODS
attr_reader :mode, :app, :server
@ -84,10 +84,10 @@ module Capybara
raise "A configuration block is only accepted when Capybara.threadsafe == true" unless Capybara.threadsafe
yield config if block_given?
end
if config.run_server and @app and driver.needs_server?
@server = Capybara::Server.new(@app, config.server_port, config.server_host, config.server_errors).boot
@server = if config.run_server and @app and driver.needs_server?
Capybara::Server.new(@app, config.server_port, config.server_host, config.server_errors).boot
else
@server = nil
nil
end
@touched = false
end
@ -266,8 +266,8 @@ module Capybara
visit_uri_parts[:path] = uri_base.path + visit_uri.path
visit_uri = uri_base.merge(visit_uri_parts)
else
visit_uri.port ||= @server.port if @server && config.always_include_port
elsif @server && config.always_include_port
visit_uri.port ||= @server.port
end
end
@ -548,15 +548,16 @@ module Capybara
# It's better to use this method than `windows.last`
# {https://dvcs.w3.org/hg/webdriver/raw-file/default/webdriver-spec.html#h_note_10 as order of windows isn't defined in some drivers}
#
# @param options [Hash]
# @option options [Numeric] :wait (Capybara.default_max_wait_time) maximum wait time
# @return [Capybara::Window] the window that has been opened within a block
# @raise [Capybara::WindowError] if block passed to window hasn't opened window
# or opened more than one window
# @overload window_opened_by(**options, &block)
# @param options [Hash]
# @option options [Numeric] :wait (Capybara.default_max_wait_time) maximum wait time
# @return [Capybara::Window] the window that has been opened within a block
# @raise [Capybara::WindowError] if block passed to window hasn't opened window
# or opened more than one window
#
def window_opened_by(**options, &block)
def window_opened_by(**options)
old_handles = driver.window_handles
block.call
yield
wait_time = Capybara::Queries::BaseQuery.wait(options, config.default_max_wait_time)
document.synchronize(wait_time, errors: [Capybara::WindowError]) do

View File

@ -1,12 +1,13 @@
# frozen_string_literal: true
require 'delegate'
module Capybara
class SessionConfig
OPTIONS = [: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]
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
attr_accessor(*OPTIONS)
@ -67,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::Parser.new.make_regexp)
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)
@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::Parser.new.make_regexp)
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)
@default_host = url
end

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
module Capybara
module SessionMatchers
##

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
module Capybara
VERSION = '3.0.0.dev'
VERSION = '3.0.0.dev'.freeze
end

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
module Capybara
##
# The Window class represents a browser window.