Code cleanup

This commit is contained in:
Thomas Walpole 2017-11-13 13:04:47 -08:00
parent 3f7b8c066b
commit cb309a8bea
17 changed files with 229 additions and 197 deletions

View File

@ -1,6 +1,9 @@
AllCops:
DisabledByDefault: true
TargetRubyVersion: 2.2.2
Exclude:
- 'spec/**/*'
- 'lib/capybara/spec/**/*'
#################### Lint ################################
Lint/AmbiguousOperator:
@ -70,8 +73,8 @@ Lint/EmptyInterpolation:
Lint/EndAlignment:
Description: 'Align ends correctly.'
Enabled: true
AlignWith: variable
Enabled: false
EnforcedStyleAlignWith: variable
Lint/EndInMethod:
Description: 'END blocks should not be placed inside method definitions.'
@ -82,7 +85,7 @@ Lint/EnsureReturn:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-return-ensure'
Enabled: true
Lint/Eval:
Security/Eval:
Description: 'The use of eval represents a serious security risk.'
Enabled: true
@ -93,15 +96,9 @@ Lint/FormatParameterMismatch:
Lint/HandleExceptions:
Description: "Don't suppress exception."
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#dont-hide-exceptions'
Enabled: true
Enabled: false
Lint/InvalidCharacterLiteral:
Description: >-
Checks for invalid character literals with a non-escaped
whitespace character.
Enabled: true
Lint/LiteralInCondition:
Lint/LiteralAsCondition:
Description: 'Checks of literals used in conditions.'
Enabled: true
@ -114,7 +111,7 @@ Lint/Loop:
Use Kernel#loop with break rather than begin/end/until or
begin/end/while for post-loop tests.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#loop-with-break'
Enabled: true
Enabled: false
Lint/NestedMethodDefinition:
Description: 'Do not use nested method definitions.'
@ -174,6 +171,9 @@ Lint/UnusedMethodArgument:
Description: 'Checks for unused method arguments.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#underscore-unused-vars'
Enabled: true
Exclude:
- 'lib/capybara/driver/base.rb'
- 'lib/capybara/driver/node.rb'
Lint/UnreachableCode:
Description: 'Unreachable code.'
@ -222,7 +222,7 @@ Metrics/BlockNesting:
Metrics/ClassLength:
Description: 'Avoid classes longer than 250 lines of code.'
Enabled: true
Enabled: false
Max: 250
Metrics/CyclomaticComplexity:
@ -368,12 +368,12 @@ Rails/Validation:
################## Style #################################
Style/AccessModifierIndentation:
Layout/AccessModifierIndentation:
Description: Check indentation of private/protected visibility modifiers.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#indent-public-private-protected'
Enabled: false
Style/AccessorMethodName:
Naming/AccessorMethodName:
Description: Check the naming of accessor methods for get_/set_.
Enabled: false
@ -382,20 +382,20 @@ Style/Alias:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#alias-method'
Enabled: false
Style/AlignArray:
Layout/AlignArray:
Description: >-
Align the elements of an array literal if they span more than
one line.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#align-multiline-arrays'
Enabled: false
Style/AlignHash:
Layout/AlignHash:
Description: >-
Align the elements of a hash literal if they span more than
one line.
Enabled: false
Style/AlignParameters:
Layout/AlignParameters:
Description: >-
Align the parameters of a method call if they span more
than one line.
@ -417,7 +417,7 @@ Style/AsciiComments:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#english-comments'
Enabled: false
Style/AsciiIdentifiers:
Naming/AsciiIdentifiers:
Description: 'Use only ascii symbols in identifiers.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#english-identifiers'
Enabled: false
@ -442,7 +442,7 @@ Style/BlockComments:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-block-comments'
Enabled: false
Style/BlockEndNewline:
Layout/BlockEndNewline:
Description: 'Put end statement of multiline block on its own line.'
Enabled: false
@ -463,7 +463,7 @@ Style/CaseEquality:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-case-equality'
Enabled: false
Style/CaseIndentation:
Layout/CaseIndentation:
Description: 'Indentation of when in a case/when/[else/]end.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#indent-when-to-case'
Enabled: false
@ -473,7 +473,7 @@ Style/CharacterLiteral:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-character-literals'
Enabled: false
Style/ClassAndModuleCamelCase:
Naming/ClassAndModuleCamelCase:
Description: 'Use CamelCase for classes and modules.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#camelcase-classes'
Enabled: false
@ -496,7 +496,7 @@ Style/ClassVars:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-class-vars'
Enabled: false
Style/ClosingParenthesisIndentation:
Layout/ClosingParenthesisIndentation:
Description: 'Checks the indentation of hanging closing parentheses.'
Enabled: false
@ -515,11 +515,11 @@ Style/CommentAnnotation:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#annotate-keywords'
Enabled: false
Style/CommentIndentation:
Layout/CommentIndentation:
Description: 'Indentation of comments.'
Enabled: false
Style/ConstantName:
Naming/ConstantName:
Description: 'Constants should use SCREAMING_SNAKE_CASE.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#screaming-snake-case'
Enabled: false
@ -538,7 +538,7 @@ Style/Documentation:
Description: 'Document classes and non-namespace modules.'
Enabled: false
Style/DotPosition:
Layout/DotPosition:
Description: 'Checks the position of the dot in multi-line method calls.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#consistent-multi-line-chains'
Enabled: false
@ -552,7 +552,7 @@ Style/EachWithObject:
Description: 'Prefer `each_with_object` over `inject` or `reduce`.'
Enabled: false
Style/ElseAlignment:
Layout/ElseAlignment:
Description: 'Align elses and elsifs correctly.'
Enabled: false
@ -560,32 +560,32 @@ Style/EmptyElse:
Description: 'Avoid empty else-clauses.'
Enabled: false
Style/EmptyLineBetweenDefs:
Layout/EmptyLineBetweenDefs:
Description: 'Use empty lines between defs.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#empty-lines-between-methods'
Enabled: false
Style/EmptyLines:
Layout/EmptyLines:
Description: "Don't use several empty lines in a row."
Enabled: false
Style/EmptyLinesAroundAccessModifier:
Layout/EmptyLinesAroundAccessModifier:
Description: "Keep blank lines around access modifiers."
Enabled: false
Style/EmptyLinesAroundBlockBody:
Layout/EmptyLinesAroundBlockBody:
Description: "Keeps track of empty lines around block bodies."
Enabled: false
Style/EmptyLinesAroundClassBody:
Layout/EmptyLinesAroundClassBody:
Description: "Keeps track of empty lines around class bodies."
Enabled: false
Style/EmptyLinesAroundModuleBody:
Layout/EmptyLinesAroundModuleBody:
Description: "Keeps track of empty lines around module bodies."
Enabled: false
Style/EmptyLinesAroundMethodBody:
Layout/EmptyLinesAroundMethodBody:
Description: "Keeps track of empty lines around method bodies."
Enabled: false
@ -599,7 +599,7 @@ Style/EndBlock:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-END-blocks'
Enabled: false
Style/EndOfLine:
Layout/EndOfLine:
Description: 'Use Unix-style line endings.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#crlf'
Enabled: false
@ -609,21 +609,21 @@ Style/EvenOdd:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#predicate-methods'
Enabled: false
Style/ExtraSpacing:
Layout/ExtraSpacing:
Description: 'Do not use unnecessary spacing.'
Enabled: false
Style/FileName:
Naming/FileName:
Description: 'Use snake_case for source file names.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#snake-case-files'
Enabled: false
Style/InitialIndentation:
Layout/InitialIndentation:
Description: >-
Checks the indentation of the first non-blank non-comment line in a file.
Enabled: false
Style/FirstParameterIndentation:
Layout/FirstParameterIndentation:
Description: 'Checks the indentation of the first parameter in a method call.'
Enabled: false
@ -672,22 +672,22 @@ Style/IfWithSemicolon:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-semicolon-ifs'
Enabled: false
Style/IndentationConsistency:
Layout/IndentationConsistency:
Description: 'Keep indentation straight.'
Enabled: false
Style/IndentationWidth:
Layout/IndentationWidth:
Description: 'Use 2 spaces for indentation.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-indentation'
Enabled: false
Style/IndentArray:
Layout/IndentArray:
Description: >-
Checks the indentation of the first element in an array
literal.
Enabled: false
Style/IndentHash:
Layout/IndentHash:
Description: 'Checks the indentation of the first key in a hash literal.'
Enabled: false
@ -706,7 +706,7 @@ Style/LambdaCall:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#proc-call'
Enabled: false
Style/LeadingCommentSpace:
Layout/LeadingCommentSpace:
Description: 'Comments should start with a space.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#hash-space'
Enabled: false
@ -717,7 +717,7 @@ Style/LineEndConcatenation:
line end.
Enabled: false
Style/MethodCallParentheses:
Style/MethodCallWithoutArgsParentheses:
Description: 'Do not use parentheses for method calls with no arguments.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-args-no-parens'
Enabled: false
@ -729,7 +729,7 @@ Style/MethodDefParentheses:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#method-parens'
Enabled: false
Style/MethodName:
Naming/MethodName:
Description: 'Use the configured style when naming methods.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#snake-case-symbols-methods-vars'
Enabled: false
@ -744,7 +744,7 @@ Style/MultilineBlockChain:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#single-line-blocks'
Enabled: false
Style/MultilineBlockLayout:
Layout/MultilineBlockLayout:
Description: 'Ensures newlines after multiline block do statements.'
Enabled: false
@ -753,7 +753,7 @@ Style/MultilineIfThen:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-then'
Enabled: false
Style/MultilineOperationIndentation:
Layout/MultilineOperationIndentation:
Description: >-
Checks indentation of binary operations that span more than
one line.
@ -817,7 +817,7 @@ Style/OneLineConditional:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#ternary-operator'
Enabled: false
Style/OpMethod:
Naming/BinaryOperatorParameterName:
Description: 'When defining binary operators, name the argument other.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#other-arg'
Enabled: false
@ -859,7 +859,7 @@ Style/PerlBackrefs:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-perl-regexp-last-matchers'
Enabled: false
Style/PredicateName:
Naming/PredicateName:
Description: 'Check the names of predicate methods.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#bool-methods-qmark'
Enabled: false
@ -899,7 +899,7 @@ Style/RegexpLiteral:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-r'
Enabled: false
Style/RescueEnsureAlignment:
Layout/RescueEnsureAlignment:
Description: 'Align rescues and ensures correctly.'
Enabled: false
@ -935,75 +935,75 @@ Style/SingleLineMethods:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-single-line-methods'
Enabled: false
Style/SpaceBeforeFirstArg:
Layout/SpaceBeforeFirstArg:
Description: >-
Checks that exactly one space is used between a method name
and the first argument for method calls without parentheses.
Enabled: true
Style/SpaceAfterColon:
Layout/SpaceAfterColon:
Description: 'Use spaces after colons.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-operators'
Enabled: false
Style/SpaceAfterComma:
Layout/SpaceAfterComma:
Description: 'Use spaces after commas.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-operators'
Enabled: false
Style/SpaceAroundKeyword:
Layout/SpaceAroundKeyword:
Description: 'Use spaces around keywords.'
Enabled: false
Style/SpaceAfterMethodName:
Layout/SpaceAfterMethodName:
Description: >-
Do not put a space between a method name and the opening
parenthesis in a method definition.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#parens-no-spaces'
Enabled: false
Style/SpaceAfterNot:
Layout/SpaceAfterNot:
Description: Tracks redundant space after the ! operator.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-space-bang'
Enabled: false
Style/SpaceAfterSemicolon:
Layout/SpaceAfterSemicolon:
Description: 'Use spaces after semicolons.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-operators'
Enabled: false
Style/SpaceBeforeBlockBraces:
Layout/SpaceBeforeBlockBraces:
Description: >-
Checks that the left block brace has or doesn't have space
before it.
Enabled: false
Style/SpaceBeforeComma:
Layout/SpaceBeforeComma:
Description: 'No spaces before commas.'
Enabled: false
Style/SpaceBeforeComment:
Layout/SpaceBeforeComment:
Description: >-
Checks for missing space between code and a comment on the
same line.
Enabled: false
Style/SpaceBeforeSemicolon:
Layout/SpaceBeforeSemicolon:
Description: 'No spaces before semicolons.'
Enabled: false
Style/SpaceInsideBlockBraces:
Layout/SpaceInsideBlockBraces:
Description: >-
Checks that block braces have or don't have surrounding space.
For blocks taking parameters, checks that the left brace has
or doesn't have trailing space.
Enabled: false
Style/SpaceAroundBlockParameters:
Layout/SpaceAroundBlockParameters:
Description: 'Checks the spacing inside and after block parameters pipes.'
Enabled: false
Style/SpaceAroundEqualsInParameterDefault:
Layout/SpaceAroundEqualsInParameterDefault:
Description: >-
Checks that the equals signs in parameter default assignments
have or don't have surrounding space depending on
@ -1011,32 +1011,32 @@ Style/SpaceAroundEqualsInParameterDefault:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-around-equals'
Enabled: false
Style/SpaceAroundOperators:
Layout/SpaceAroundOperators:
Description: 'Use a single space around operators.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-operators'
Enabled: false
Style/SpaceInsideBrackets:
Layout/SpaceInsideBrackets:
Description: 'No spaces after [ or before ].'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-spaces-braces'
Enabled: false
Style/SpaceInsideHashLiteralBraces:
Layout/SpaceInsideHashLiteralBraces:
Description: "Use spaces inside hash literal braces - or don't."
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-operators'
Enabled: false
Style/SpaceInsideParens:
Layout/SpaceInsideParens:
Description: 'No spaces after ( or before ).'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-spaces-braces'
Enabled: false
Style/SpaceInsideRangeLiteral:
Layout/SpaceInsideRangeLiteral:
Description: 'No spaces inside range literals.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-space-inside-range-literals'
Enabled: false
Style/SpaceInsideStringInterpolation:
Layout/SpaceInsideStringInterpolation:
Description: 'Checks for padding/surrounding spaces inside string interpolation.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#string-interpolation'
Enabled: false
@ -1070,12 +1070,12 @@ Style/SymbolProc:
Description: 'Use symbols as procs instead of blocks when possible.'
Enabled: false
Style/Tab:
Layout/Tab:
Description: 'No hard tabs.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-indentation'
Enabled: false
Style/TrailingBlankLines:
Layout/TrailingBlankLines:
Description: 'Checks trailing blank lines and final newline.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#newline-eof'
Enabled: false
@ -1090,7 +1090,7 @@ Style/TrailingCommaInLiteral:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas'
Enabled: false
Style/TrailingWhitespace:
Layout/TrailingWhitespace:
Description: 'Avoid trailing whitespace.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-whitespace'
Enabled: false
@ -1129,7 +1129,7 @@ Style/VariableInterpolation:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#curlies-interpolate'
Enabled: false
Style/VariableName:
Naming/VariableName:
Description: 'Use the configured style when naming variables.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#snake-case-symbols-methods-vars'
Enabled: false

View File

@ -37,7 +37,7 @@ Cucumber::Rake::Task.new(:cucumber) do |task|
task.cucumber_opts = ['--format=progress', 'features']
end
task :travis do |t|
task :travis do
if ENV['CAPYBARA_FF']
Rake::Task[:spec_marionette].invoke
elsif ENV['CAPYBARA_LEGACY_FF']

View File

@ -98,6 +98,7 @@ module Capybara
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)
@ -140,7 +141,7 @@ module Capybara
end
alias_method "refute_matches_#{selector_type}", "assert_not_matches_#{selector_type}"
end
# rubocop:enable Lint/UnusedBlockArgument
##
# Assertion that there is xpath

View File

@ -28,7 +28,7 @@ module Capybara
#
# @return [String] The text of the element
#
def text(type=nil)
def text(_type=nil)
native.text
end
@ -139,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

View File

@ -59,27 +59,8 @@ module Capybara
end
def matches_filters?(node)
if options[:text]
regexp = if options[:text].is_a?(Regexp)
options[:text]
else
if exact_text == true
/\A#{Regexp.escape(options[:text].to_s)}\z/
else
Regexp.escape(options[:text].to_s)
end
end
text_visible = visible
text_visible = :all if text_visible == :hidden
return false if not node.text(text_visible).match(regexp)
end
if exact_text.is_a?(String)
regexp = /\A#{Regexp.escape(options[:exact_text])}\z/
text_visible = visible
text_visible = :all if text_visible == :hidden
return false if not node.text(text_visible).match(regexp)
end
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)
case visible
when :visible then return false unless node.visible?
@ -103,7 +84,6 @@ module Capybara
end unless @filter_block.nil?
res
rescue *(node.respond_to?(:session) ? node.session.driver.invalid_element_errors : [])
return false
end
@ -247,6 +227,28 @@ module Capybara
@resolved_node && !(@resolved_node.is_a?(::Capybara::Node::Document) ||
(@resolved_node.is_a?(::Capybara::Node::Simple) && @resolved_node.path == '/'))
end
def matches_text_filter(node, text_option)
regexp = if text_option.is_a?(Regexp)
text_option
else
if exact_text == true
/\A#{Regexp.escape(text_option.to_s)}\z/
else
Regexp.escape(text_option.to_s)
end
end
text_visible = visible
text_visible = :all if text_visible == :hidden
node.text(text_visible).match(regexp)
end
def matches_exact_text_filter(node, exact_text_option)
regexp = /\A#{Regexp.escape(exact_text_option)}\z/
text_visible = visible
text_visible = :all if text_visible == :hidden
node.text(text_visible).match(regexp)
end
end
end
end

View File

@ -30,43 +30,11 @@ class Capybara::RackTest::Form < Capybara::RackTest::Node
native.xpath(form_elements_xpath).map do |field|
case field.name
when 'input'
if %w(radio checkbox).include? field['type']
if field['checked']
node=Capybara::RackTest::Node.new(self.driver, field)
merge_param!(params, field['name'].to_s, node.value.to_s)
end
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'
if multipart?
file = \
if (value = field['value']).to_s.empty?
NilUploadedFile.new
else
mime_info = MiniMime.lookup_by_filename(value)
Rack::Test::UploadedFile.new(value, (mime_info && mime_info.content_type).to_s)
end
merge_param!(params, field['name'].to_s, file)
else
merge_param!(params, field['name'].to_s, File.basename(field['value'].to_s))
end
else
merge_param!(params, field['name'].to_s, field['value'].to_s)
end
add_input_param(field, params)
when 'select'
if field['multiple'] == 'multiple'
options = field.xpath(".//option[@selected]")
options.each do |option|
merge_param!(params, field['name'].to_s, (option['value'] || option.text).to_s)
end
else
option = field.xpath(".//option[@selected]").first
option ||= field.xpath('.//option').first
merge_param!(params, field['name'].to_s, (option['value'] || option.text).to_s) if option
end
add_select_param(field, params)
when 'textarea'
merge_param!(params, field['name'].to_s, field['_capybara_raw_value'].to_s.gsub(/\n/, "\r\n"))
add_textarea_param(field, params)
end
end
merge_param!(params, button[:name], button[:value] || "") if button[:name]
@ -111,4 +79,48 @@ private
ParamsHash.new
end
end
def add_input_param(field, params)
if %w(radio checkbox).include? field['type']
if field['checked']
node=Capybara::RackTest::Node.new(self.driver, field)
merge_param!(params, field['name'].to_s, node.value.to_s)
end
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'
if multipart?
file = \
if (value = field['value']).to_s.empty?
NilUploadedFile.new
else
mime_info = MiniMime.lookup_by_filename(value)
Rack::Test::UploadedFile.new(value, (mime_info && mime_info.content_type).to_s)
end
merge_param!(params, field['name'].to_s, file)
else
merge_param!(params, field['name'].to_s, File.basename(field['value'].to_s))
end
else
merge_param!(params, field['name'].to_s, field['value'].to_s)
end
end
def add_select_param(field, params)
if field['multiple'] == 'multiple'
options = field.xpath(".//option[@selected]")
options.each do |option|
merge_param!(params, field['name'].to_s, (option['value'] || option.text).to_s)
end
else
option = field.xpath(".//option[@selected]").first
option ||= field.xpath('.//option').first
merge_param!(params, field['name'].to_s, (option['value'] || option.text).to_s) if option
end
end
def add_textarea_param(field, params)
merge_param!(params, field['name'].to_s, field['_capybara_raw_value'].to_s.gsub(/\n/, "\r\n"))
end
end

View File

@ -62,6 +62,7 @@ module Capybara
!any?
end
# rubocop:disable Metrics/MethodLength
def matches_count?
# Only check filters for as many elements as necessary to determine result
if @query.options[:count]
@ -102,6 +103,7 @@ module Capybara
return true
end
# rubocop:enable Metrics/MethodLength
def failure_message
message = @query.failure_message

View File

@ -9,7 +9,7 @@ Capybara::Selector::FilterSet.add(:_field) do
expression_filter(:name) { |xpath, val| xpath[XPath.attr(:name).equals(val)] }
expression_filter(:placeholder) { |xpath, val| xpath[XPath.attr(:placeholder).equals(val)] }
describe do |checked: nil, unchecked: nil, disabled: nil, multiple: nil, **options|
describe do |checked: nil, unchecked: nil, disabled: nil, multiple: nil, **_options|
desc, states = String.new, []
states << 'checked' if checked || (unchecked == false)
states << 'not checked' if unchecked || (checked == false)
@ -109,7 +109,7 @@ end
# @filter [String, Array<String>] :class Matches the class(es) provided
#
Capybara.add_selector(:fieldset) do
xpath(:legend) do |locator, legend: nil, **options|
xpath(:legend) do |locator, legend: nil, **_options|
xpath = XPath.descendant(:fieldset)
xpath = xpath[XPath.attr(:id).equals(locator.to_s).or XPath.child(:legend)[XPath.string.n.is(locator.to_s)]] unless locator.nil?
xpath = xpath[XPath.child(:legend)[XPath.string.n.is(legend)]] if legend
@ -130,7 +130,8 @@ end
# @filter [String, Regexp,nil] :href Matches the normalized href of the link, if nil will find <a> elements with no href attribute
#
Capybara.add_selector(:link) do
xpath(:title, :alt) do |locator, href: true, enable_aria_label: false, alt: nil, title: nil, **options|
# 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?
xpath[~XPath.attr(:href)]
@ -229,7 +230,7 @@ Capybara.add_selector(:link_or_button) do
filter(:disabled, :boolean, default: false, skip_if: :all) { |node, value| node.tag_name == "a" or not(value ^ node.disabled?) }
describe { |disabled: nil, **options| " that is disabled" if disabled == true }
describe { |disabled: nil, **_options| " that is disabled" if disabled == true }
end
##
@ -514,7 +515,7 @@ Capybara.add_selector(:table) do
xpath
end
describe do |caption: nil, **options|
describe do |caption: nil, **_options|
desc = String.new
desc << " with caption #{caption}" if caption
desc
@ -538,7 +539,7 @@ Capybara.add_selector(:frame) do
xpath
end
describe do |name: nil, **options|
describe do |name: nil, **_options|
desc = String.new
desc << " with name #{name}" if name
desc

View File

@ -233,7 +233,7 @@ module Capybara
custom_filters[name] = filter_class.new(name, block, options)
end
def locate_field(xpath, locator, enable_aria_label: false, **options)
def locate_field(xpath, locator, enable_aria_label: false, **_options)
locate_xpath = xpath #need to save original xpath for the label wrap
if locator
locator = locator.to_s

View File

@ -117,20 +117,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
# can trigger an endless series of unload modals
begin
@browser.manage.delete_all_cookies
if options[:clear_session_storage]
if @browser.respond_to? :session_storage
@browser.session_storage.clear
else
warn "sessionStorage clear requested but is not available for this driver"
end
end
if options[:clear_local_storage]
if @browser.respond_to? :local_storage
@browser.local_storage.clear
else
warn "localStorage clear requested but is not available for this driver"
end
end
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
@ -322,6 +309,23 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
options[:browser].to_s
end
def clear_storage
if options[:clear_session_storage]
if @browser.respond_to? :session_storage
@browser.session_storage.clear
else
warn "sessionStorage clear requested but is not available for this driver"
end
end
if options[:clear_local_storage]
if @browser.respond_to? :local_storage
@browser.local_storage.clear
else
warn "localStorage clear requested but is not available for this driver"
end
end
end
def modal_error
if defined?(Selenium::WebDriver::Error::NoSuchAlertError)
Selenium::WebDriver::Error::NoSuchAlertError
@ -330,6 +334,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
end
end
# rubocop:disable Metrics/MethodLength
def insert_modal_handlers(accept, response_text)
prompt_response = if accept
if response_text.nil?
@ -383,6 +388,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
JS
execute_script script
end
# rubocop:enable Metrics/MethodLength
def within_given_window(handle)
original_handle = self.current_window_handle

View File

@ -52,12 +52,7 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
when 'checkbox'
click if value ^ native.attribute('checked').to_s.eql?("true")
when 'file'
path_names = value.to_s.empty? ? [] : value
if driver.chrome?
native.send_keys(Array(path_names).join("\n"))
else
native.send_keys(*path_names)
end
set_file(value)
else
set_text(value, options)
end
@ -65,27 +60,7 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
set_text(value, options)
else
if content_editable?
#ensure we are focused on the element
click
script = <<-JS
var range = document.createRange();
var sel = window.getSelection();
arguments[0].focus();
range.selectNodeContents(arguments[0]);
sel.removeAllRanges();
sel.addRange(range);
JS
driver.execute_script script, self
if (driver.chrome?) || (driver.firefox? && !driver.marionette?)
# chromedriver raises a can't focus element for child elements if we use native.send_keys
# we've already focused it so just use action api
driver.browser.action.send_keys(value.to_s).perform
else
# action api is really slow here just use native.send_keys
native.send_keys(value.to_s)
end
set_content_editable(value)
end
end
end
@ -199,7 +174,7 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
path.unshift self
result = []
while node = path.shift
while (node = path.shift)
parent = path.first
if parent
@ -259,4 +234,37 @@ private
driver.execute_script(script, self)
block.call
end
def set_file(value)
path_names = value.to_s.empty? ? [] : value
if driver.chrome?
native.send_keys(Array(path_names).join("\n"))
else
native.send_keys(*path_names)
end
end
def set_content_editable(value)
#ensure we are focused on the element
click
script = <<-JS
var range = document.createRange();
var sel = window.getSelection();
arguments[0].focus();
range.selectNodeContents(arguments[0]);
sel.removeAllRanges();
sel.addRange(range);
JS
driver.execute_script script, self
if (driver.chrome?) || (driver.firefox? && !driver.marionette?)
# chromedriver raises a can't focus element for child elements if we use native.send_keys
# we've already focused it so just use action api
driver.browser.action.send_keys(value.to_s).perform
else
# action api is really slow here just use native.send_keys
native.send_keys(value.to_s)
end
end
end

View File

@ -259,7 +259,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
@ -753,7 +753,9 @@ module Capybara
# @param [Hash] options a customizable set of options
#
def save_and_open_screenshot(path = nil, **options)
# rubocop:disable Lint/Debugger
path = save_screenshot(path, options)
# rubocop:enable Lint/Debugger
open_file(path)
end

View File

@ -88,7 +88,7 @@ module Capybara
class ReadOnlySessionConfig < SimpleDelegator
SessionConfig::OPTIONS.each do |m|
define_method "#{m}=" do |val|
define_method "#{m}=" do |_|
raise "Per session settings are only supported when Capybara.threadsafe == true"
end
end

View File

@ -71,7 +71,7 @@ Capybara::SpecHelper.spec "#attach_file" do
expect(@session.body).to include("1 | ")#number of files
end
it "should not break when using HTML5 multiple file input uploading multiple files" do
it "should not break when using HTML5 multiple file input uploading multiple files" do
pending "Selenium is buggy on this, see http://code.google.com/p/selenium/issues/detail?id=2239" if @session.respond_to?(:mode) && @session.mode.to_s =~ /^selenium_(firefox|marionette)/
@session.attach_file "Multiple Documents", [@test_file_path, @another_test_file_path]
@session.click_button('Upload Multiple')

View File

@ -300,7 +300,7 @@ Capybara::SpecHelper.spec '#click_button' do
end
end
context "with id given on a button defined by <button> tag" do
context "with id given on a button defined by <button> tag" do
it "should submit the associated form" do
@session.click_button('click_me_123')
expect(extract_results(@session)['first_name']).to eq('John')
@ -315,7 +315,7 @@ Capybara::SpecHelper.spec '#click_button' do
end
end
context "with value given on a button defined by <button> tag" do
context "with value given on a button defined by <button> tag" do
it "should submit the associated form" do
@session.click_button('click_me')
expect(extract_results(@session)['first_name']).to eq('John')

View File

@ -65,7 +65,7 @@ Capybara::SpecHelper.spec '#has_current_path?' do
it "should default to full url if value is a url" do
url = @session.current_url
expect(url).to match /with_js$/
expect(url).to match(/with_js$/)
expect(@session).to have_current_path(url)
expect(@session).not_to have_current_path("http://www.not_example.com/with_js")
end

View File

@ -38,8 +38,8 @@ Capybara::SpecHelper.spec '#within_window', requires: [:windows] do
it "returns value from the block" do
window = (@session.windows - [@window]).first
value = @session.within_window window do
43252003274489856000
end
43252003274489856000
end
expect(value).to eq(43252003274489856000)
end
@ -139,9 +139,7 @@ Capybara::SpecHelper.spec '#within_window', requires: [:windows] do
end
it "returns value from the block" do
value = @session.within_window(->{ @session.title == 'Title of popup two'}) do
42
end
value = @session.within_window(->{ @session.title == 'Title of popup two'}) { 42 }
expect(value).to eq(42)
end