Refactoring
This commit is contained in:
parent
634db23f6b
commit
2158339097
|
@ -6,6 +6,9 @@ checks:
|
||||||
file-lines:
|
file-lines:
|
||||||
config:
|
config:
|
||||||
threshold: 500
|
threshold: 500
|
||||||
|
method-complexity:
|
||||||
|
config:
|
||||||
|
threshold: 10
|
||||||
engines:
|
engines:
|
||||||
bundler-audit:
|
bundler-audit:
|
||||||
enabled: false
|
enabled: false
|
||||||
|
@ -17,6 +20,7 @@ engines:
|
||||||
- "lib/capybara/selector.rb"
|
- "lib/capybara/selector.rb"
|
||||||
- "lib/capybara/minitest.rb"
|
- "lib/capybara/minitest.rb"
|
||||||
- "lib/capybara/selector/definition/"
|
- "lib/capybara/selector/definition/"
|
||||||
|
- "lib/capybara/rspec/matchers/"
|
||||||
config:
|
config:
|
||||||
languages:
|
languages:
|
||||||
ruby:
|
ruby:
|
||||||
|
|
|
@ -17,11 +17,7 @@ module Capybara
|
||||||
conditions = if name == :class
|
conditions = if name == :class
|
||||||
class_conditions(value)
|
class_conditions(value)
|
||||||
elsif value.is_a? Regexp
|
elsif value.is_a? Regexp
|
||||||
Selector::RegexpDisassembler.new(value).alternated_substrings.map do |strs|
|
regexp_conditions(name, value)
|
||||||
strs.map do |str|
|
|
||||||
"[#{name}*='#{str}'#{' i' if value.casefold?}]"
|
|
||||||
end.join
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
[attribute_conditions(name => value)]
|
[attribute_conditions(name => value)]
|
||||||
end
|
end
|
||||||
|
@ -36,6 +32,14 @@ module Capybara
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def regexp_conditions(name, value)
|
||||||
|
Selector::RegexpDisassembler.new(value).alternated_substrings.map do |strs|
|
||||||
|
strs.map do |str|
|
||||||
|
"[#{name}*='#{str}'#{' i' if value.casefold?}]"
|
||||||
|
end.join
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def attribute_conditions(attributes)
|
def attribute_conditions(attributes)
|
||||||
attributes.map do |attribute, value|
|
attributes.map do |attribute, value|
|
||||||
case value
|
case value
|
||||||
|
@ -70,7 +74,7 @@ module Capybara
|
||||||
end.join
|
end.join
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
cls = Array(classes).group_by { |cl| cl.start_with?('!') && !cl.start_with?('!!!') }
|
cls = Array(classes).group_by { |cl| cl.match?(/^!(?!!!)/) }
|
||||||
[(cls[false].to_a.map { |cl| ".#{Capybara::Selector::CSS.escape(cl.sub(/^!!/, ''))}" } +
|
[(cls[false].to_a.map { |cl| ".#{Capybara::Selector::CSS.escape(cl.sub(/^!!/, ''))}" } +
|
||||||
cls[true].to_a.map { |cl| ":not(.#{Capybara::Selector::CSS.escape(cl.slice(1..-1))})" }).join]
|
cls[true].to_a.map { |cl| ":not(.#{Capybara::Selector::CSS.escape(cl.slice(1..-1))})" }).join]
|
||||||
end
|
end
|
||||||
|
|
|
@ -48,7 +48,7 @@ module Capybara
|
||||||
attribute_conditions(class: classes)
|
attribute_conditions(class: classes)
|
||||||
else
|
else
|
||||||
Array(classes).map do |klass|
|
Array(classes).map do |klass|
|
||||||
if klass.start_with?('!') && !klass.start_with?('!!!')
|
if klass.match?(/^!(?!!!)/)
|
||||||
!XPath.attr(:class).contains_word(klass.slice(1..-1))
|
!XPath.attr(:class).contains_word(klass.slice(1..-1))
|
||||||
else
|
else
|
||||||
XPath.attr(:class).contains_word(klass.sub(/^!!/, ''))
|
XPath.attr(:class).contains_word(klass.sub(/^!!/, ''))
|
||||||
|
|
|
@ -300,13 +300,10 @@ private
|
||||||
end
|
end
|
||||||
|
|
||||||
def unhandled_alert_errors
|
def unhandled_alert_errors
|
||||||
@unhandled_alert_errors ||= [Selenium::WebDriver::Error::UnexpectedAlertOpenError].tap do |errors|
|
@unhandled_alert_errors ||= with_legacy_error(
|
||||||
unless selenium_4?
|
[Selenium::WebDriver::Error::UnexpectedAlertOpenError],
|
||||||
::Selenium::WebDriver.logger.suppress_deprecations do
|
'UnhandledAlertError'
|
||||||
errors << Selenium::WebDriver::Error::UnhandledAlertError
|
)
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_all_cookies
|
def delete_all_cookies
|
||||||
|
@ -387,10 +384,14 @@ private
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_modal_errors
|
def find_modal_errors
|
||||||
@find_modal_errors ||= [Selenium::WebDriver::Error::TimeoutError].tap do |errors|
|
@find_modal_errors ||= with_legacy_error([Selenium::WebDriver::Error::TimeoutError], 'TimeOutError')
|
||||||
|
end
|
||||||
|
|
||||||
|
def with_legacy_error(errors, legacy_error)
|
||||||
|
errors.tap do |errs|
|
||||||
unless selenium_4?
|
unless selenium_4?
|
||||||
::Selenium::WebDriver.logger.suppress_deprecations do
|
::Selenium::WebDriver.logger.suppress_deprecations do
|
||||||
errors << Selenium::WebDriver::Error::TimeOutError
|
errs << Selenium::WebDriver::Error.const_get(legacy_error)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -18,27 +18,28 @@ module Capybara
|
||||||
hints = []
|
hints = []
|
||||||
|
|
||||||
if (els.size > 2) && !ENV['DISABLE_CAPYBARA_SELENIUM_OPTIMIZATIONS']
|
if (els.size > 2) && !ENV['DISABLE_CAPYBARA_SELENIUM_OPTIMIZATIONS']
|
||||||
begin
|
els = filter_by_text(els, texts) unless texts.empty?
|
||||||
els = filter_by_text(els, texts) unless texts.empty?
|
hints = gather_hints(els, uses_visibility: uses_visibility, styles: styles)
|
||||||
hints_js, functions = build_hints_js(uses_visibility, styles)
|
|
||||||
|
|
||||||
unless functions.empty?
|
|
||||||
hints = es_context.execute_script(hints_js, els).map! do |results|
|
|
||||||
hint = {}
|
|
||||||
hint[:style] = results.pop if functions.include?(:style_func)
|
|
||||||
hint[:visible] = results.pop if functions.include?(:vis_func)
|
|
||||||
hint
|
|
||||||
end
|
|
||||||
end
|
|
||||||
rescue ::Selenium::WebDriver::Error::StaleElementReferenceError,
|
|
||||||
::Capybara::NotSupportedByDriverError
|
|
||||||
# warn 'Unexpected Stale Element Error - skipping optimization'
|
|
||||||
hints = []
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
els.map.with_index { |el, idx| build_node(el, hints[idx] || {}) }
|
els.map.with_index { |el, idx| build_node(el, hints[idx] || {}) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def gather_hints(elements, uses_visibility:, styles:)
|
||||||
|
hints_js, functions = build_hints_js(uses_visibility, styles)
|
||||||
|
return [] unless functions.any?
|
||||||
|
|
||||||
|
es_context.execute_script(hints_js, elements).map! do |results|
|
||||||
|
hint = {}
|
||||||
|
hint[:style] = results.pop if functions.include?(:style_func)
|
||||||
|
hint[:visible] = results.pop if functions.include?(:vis_func)
|
||||||
|
hint
|
||||||
|
end
|
||||||
|
rescue ::Selenium::WebDriver::Error::StaleElementReferenceError,
|
||||||
|
::Capybara::NotSupportedByDriverError
|
||||||
|
# warn 'Unexpected Stale Element Error - skipping optimization'
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
|
||||||
def filter_by_text(elements, texts)
|
def filter_by_text(elements, texts)
|
||||||
es_context.execute_script <<~JS, elements, texts
|
es_context.execute_script <<~JS, elements, texts
|
||||||
var texts = arguments[1];
|
var texts = arguments[1];
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class Capybara::Selenium::Node
|
||||||
|
#
|
||||||
|
# @api private
|
||||||
|
#
|
||||||
|
class ModifierKeysStack
|
||||||
|
def initialize
|
||||||
|
@stack = []
|
||||||
|
end
|
||||||
|
|
||||||
|
def include?(key)
|
||||||
|
@stack.flatten.include?(key)
|
||||||
|
end
|
||||||
|
|
||||||
|
def press(key)
|
||||||
|
@stack.last.push(key)
|
||||||
|
end
|
||||||
|
|
||||||
|
def push
|
||||||
|
@stack.push []
|
||||||
|
end
|
||||||
|
|
||||||
|
def pop
|
||||||
|
@stack.pop
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -114,27 +114,4 @@ private
|
||||||
def browser_version
|
def browser_version
|
||||||
driver.browser.capabilities[:browser_version].to_f
|
driver.browser.capabilities[:browser_version].to_f
|
||||||
end
|
end
|
||||||
|
|
||||||
class ModifierKeysStack
|
|
||||||
def initialize
|
|
||||||
@stack = []
|
|
||||||
end
|
|
||||||
|
|
||||||
def include?(key)
|
|
||||||
@stack.flatten.include?(key)
|
|
||||||
end
|
|
||||||
|
|
||||||
def press(key)
|
|
||||||
@stack.last.push(key)
|
|
||||||
end
|
|
||||||
|
|
||||||
def push
|
|
||||||
@stack.push []
|
|
||||||
end
|
|
||||||
|
|
||||||
def pop
|
|
||||||
@stack.pop
|
|
||||||
end
|
|
||||||
end
|
|
||||||
private_constant :ModifierKeysStack
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
# require 'capybara/selenium/extensions/html5_drag'
|
# require 'capybara/selenium/extensions/html5_drag'
|
||||||
|
require 'capybara/selenium/extensions/modifier_keys_stack'
|
||||||
|
|
||||||
class Capybara::Selenium::SafariNode < Capybara::Selenium::Node
|
class Capybara::Selenium::SafariNode < Capybara::Selenium::Node
|
||||||
# include Html5Drag
|
# include Html5Drag
|
||||||
|
@ -118,27 +119,4 @@ private
|
||||||
shift left_shift right_shift
|
shift left_shift right_shift
|
||||||
meta left_meta right_meta
|
meta left_meta right_meta
|
||||||
command].freeze
|
command].freeze
|
||||||
|
|
||||||
class ModifierKeysStack
|
|
||||||
def initialize
|
|
||||||
@stack = []
|
|
||||||
end
|
|
||||||
|
|
||||||
def include?(key)
|
|
||||||
@stack.flatten.include?(key)
|
|
||||||
end
|
|
||||||
|
|
||||||
def press(key)
|
|
||||||
@stack.last.push(key)
|
|
||||||
end
|
|
||||||
|
|
||||||
def push
|
|
||||||
@stack.push []
|
|
||||||
end
|
|
||||||
|
|
||||||
def pop
|
|
||||||
@stack.pop
|
|
||||||
end
|
|
||||||
end
|
|
||||||
private_constant :ModifierKeysStack
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -138,6 +138,9 @@ banana</textarea>
|
||||||
Ancestor
|
Ancestor
|
||||||
<div id="child">Child</div>
|
<div id="child">Child</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="ancestor1_sibiling">
|
||||||
|
ASibling
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button id="ancestor_button" type="submit" disabled>
|
<button id="ancestor_button" type="submit" disabled>
|
||||||
<img id="button_img" width="20" height="20" alt="button img"/>
|
<img id="button_img" width="20" height="20" alt="button img"/>
|
||||||
|
|
Loading…
Reference in New Issue