From b1f4709c6ec3fe09c0453d594e05afef3e9c4da2 Mon Sep 17 00:00:00 2001 From: Thomas Walpole Date: Wed, 16 May 2018 12:47:08 -0700 Subject: [PATCH] General code cleanup --- lib/capybara/node/actions.rb | 13 +++--- lib/capybara/node/base.rb | 2 +- lib/capybara/node/element.rb | 8 +--- lib/capybara/node/matchers.rb | 19 ++++---- lib/capybara/node/simple.rb | 6 ++- lib/capybara/queries/selector_query.rb | 65 +++++++++++++------------- lib/capybara/queries/text_query.rb | 13 ++++-- lib/capybara/rack_test/browser.rb | 16 ++++--- lib/capybara/rack_test/form.rb | 32 ++++++------- lib/capybara/rack_test/node.rb | 17 +++---- lib/capybara/result.rb | 2 +- lib/capybara/selector.rb | 29 ++++++------ lib/capybara/selenium/node.rb | 24 ++++------ lib/capybara/session.rb | 2 +- spec/result_spec.rb | 6 +++ 15 files changed, 125 insertions(+), 129 deletions(-) diff --git a/lib/capybara/node/actions.rb b/lib/capybara/node/actions.rb index 210a8d1d..211e2c84 100644 --- a/lib/capybara/node/actions.rb +++ b/lib/capybara/node/actions.rb @@ -256,9 +256,9 @@ module Capybara def select_datalist_option(input, value) datalist_options = session.evaluate_script(DATALIST_OPTIONS_SCRIPT, input) if (option = datalist_options.find { |o| o['value'] == value || o['label'] == value }) - input.set(option["value"]) + input.set(option['value']) else - raise ::Capybara::ElementNotFound, "Unable to find datalist option \"#{value}\"" + raise ::Capybara::ElementNotFound, %(Unable to find datalist option "#{value}") end rescue ::Capybara::NotSupportedByDriverError # Implement for drivers that don't support JS @@ -298,8 +298,7 @@ module Capybara raise unless allow_label_click && catch_error?(e) begin el ||= find(selector, locator, options.merge(visible: :all)) - res = find(:label, for: el, visible: true).click unless el.checked? == checked - res + find(:label, for: el, visible: true).click unless el.checked? == checked rescue StandardError # swallow extra errors - raise original raise e end @@ -307,7 +306,7 @@ module Capybara end end - UPDATE_STYLE_SCRIPT = <<-'JS' + UPDATE_STYLE_SCRIPT = <<~'JS' var el = arguments[0]; el.capybara_style_cache = el.style.cssText; var css = arguments[1]; @@ -318,7 +317,7 @@ module Capybara } JS - RESET_STYLE_SCRIPT = <<-'JS' + RESET_STYLE_SCRIPT = <<~'JS' var el = arguments[0]; if (el.hasOwnProperty('capybara_style_cache')) { el.style.cssText = el.capybara_style_cache; @@ -326,7 +325,7 @@ module Capybara } JS - DATALIST_OPTIONS_SCRIPT = <<-'JS' + DATALIST_OPTIONS_SCRIPT = <<~'JS' Array.prototype.slice.call((arguments[0].list||{}).options || []). filter(function(el){ return !el.disabled }). map(function(el){ return { "value": el.value, "label": el.label} }) diff --git a/lib/capybara/node/base.rb b/lib/capybara/node/base.rb index 82365185..0ea4b2c1 100644 --- a/lib/capybara/node/base.rb +++ b/lib/capybara/node/base.rb @@ -86,7 +86,7 @@ module Capybara raise e unless driver.wait? && catch_error?(e, errors) raise e if (Capybara::Helpers.monotonic_time - start_time) >= seconds sleep(0.05) - raise Capybara::FrozenInTime, "time appears to be frozen, Capybara does not work with libraries which freeze time, consider using time travelling instead" if Capybara::Helpers.monotonic_time == start_time + raise Capybara::FrozenInTime, "Time appears to be frozen. Capybara does not work with libraries which freeze time, consider using time travelling instead" if Capybara::Helpers.monotonic_time == start_time reload if session_options.automatic_reload retry ensure diff --git a/lib/capybara/node/element.rb b/lib/capybara/node/element.rb index a52905b2..dee38467 100644 --- a/lib/capybara/node/element.rb +++ b/lib/capybara/node/element.rb @@ -55,13 +55,7 @@ module Capybara # def text(type = nil) type ||= :all unless session_options.ignore_hidden_elements || session_options.visible_text_only - synchronize do - if type == :all - base.all_text - else - base.visible_text - end - end + synchronize { type == :all ? base.all_text : base.visible_text } end ## diff --git a/lib/capybara/node/matchers.rb b/lib/capybara/node/matchers.rb index c2f9111c..e09f5a20 100644 --- a/lib/capybara/node/matchers.rb +++ b/lib/capybara/node/matchers.rb @@ -91,7 +91,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.any? || query.expects_none?) raise Capybara::ExpectationNotMet, result.failure_message end end @@ -114,7 +114,7 @@ module Capybara # def assert_all_of_selectors(*args, wait: nil, **options, &optional_filter_block) wait = session_options.default_max_wait_time if wait.nil? - selector = args.first.is_a?(Symbol) ? args.shift : session_options.default_selector + selector = extract_selector(args) synchronize(wait) do args.each do |locator| assert_selector(selector, locator, options, &optional_filter_block) @@ -139,7 +139,7 @@ module Capybara # def assert_none_of_selectors(*args, wait: nil, **options, &optional_filter_block) wait = session_options.default_max_wait_time if wait.nil? - selector = args.first.is_a?(Symbol) ? args.shift : session_options.default_selector + selector = extract_selector(args) synchronize(wait) do args.each do |locator| assert_no_selector(selector, locator, options, &optional_filter_block) @@ -659,12 +659,15 @@ module Capybara private + def extract_selector(args) + args.first.is_a?(Symbol) ? args.shift : session_options.default_selector + end + def _verify_selector_result(query_args, optional_filter_block) query_args = _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) - yield result, query + yield query.resolve_for(self), query end true end @@ -673,8 +676,7 @@ module Capybara query_args = _set_query_session_options(*query_args) query = Capybara::Queries::MatchQuery.new(*query_args, &optional_filter_block) synchronize(query.wait) do - result = query.resolve_for(query_scope) - yield result + yield query.resolve_for(query_scope) end true end @@ -683,8 +685,7 @@ module Capybara query_args = _set_query_session_options(*query_args) query = Capybara::Queries::TextQuery.new(*query_args) synchronize(query.wait) do - count = query.resolve_for(self) - yield(count, query) + yield query.resolve_for(self), query end true end diff --git a/lib/capybara/node/simple.rb b/lib/capybara/node/simple.rb index 1d043b00..73e86473 100644 --- a/lib/capybara/node/simple.rb +++ b/lib/capybara/node/simple.rb @@ -78,7 +78,7 @@ module Capybara if tag_name == 'textarea' native['_capybara_raw_value'] elsif tag_name == 'select' - if native['multiple'] == 'multiple' + if multiple? native.xpath(".//option[@selected='selected']").map { |option| option[:value] || option.content } else option = native.xpath(".//option[@selected='selected']").first || native.xpath(".//option").first @@ -139,6 +139,10 @@ module Capybara native.has_attribute?('selected') end + def multiple? + native.has_attribute?('multiple') + end + def synchronize(_seconds = nil) yield # simple nodes don't need to wait end diff --git a/lib/capybara/queries/selector_query.rb b/lib/capybara/queries/selector_query.rb index 88100dd1..93cc554a 100644 --- a/lib/capybara/queries/selector_query.rb +++ b/lib/capybara/queries/selector_query.rb @@ -36,7 +36,7 @@ module Capybara @description << "non-visible " if visible == :hidden @description << "#{label} #{locator.inspect}" @description << " with#{' exact' if exact_text == true} text #{options[:text].inspect}" if options[:text] - @description << " with exact text #{options[:exact_text]}" if options[:exact_text].is_a?(String) + @description << " with exact text #{exact_text}" if exact_text.is_a?(String) @description << " with id #{options[:id]}" if options[:id] @description << " with classes [#{Array(options[:class]).join(',')}]" if options[:class] @description << selector.description(options) @@ -172,28 +172,23 @@ module Capybara end def filtered_xpath(expr) - if options.key?(:id) || options.key?(:class) - expr = "(#{expr})" - 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(:&) - expr = "#{expr}[#{class_xpath}]" - end + 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(:&) + expr = "(#{expr})[#{class_xpath}]" end expr end def filtered_css(expr) - 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.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 + css_selectors = expr.split(',').map(&:rstrip) + expr = css_selectors.map do |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(", ") expr end @@ -219,25 +214,29 @@ module Capybara end def describe_within? - @resolved_node && !(@resolved_node.is_a?(::Capybara::Node::Document) || - (@resolved_node.is_a?(::Capybara::Node::Simple) && @resolved_node.path == '/')) + @resolved_node && !document?(@resolved_node) && !simple_root?(@resolved_node) end - 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 - Regexp.escape(text_option.to_s) - end - text_visible = visible - text_visible = :all if text_visible == :hidden - node.text(text_visible).match(regexp) + def document?(node) + node.is_a?(::Capybara::Node::Document) end - def matches_exact_text_filter(node, exact_text_option) - regexp = /\A#{Regexp.escape(exact_text_option)}\z/ + def simple_root?(node) + node.is_a?(::Capybara::Node::Simple) && node.path == '/' + end + + def matches_text_filter(node, value) + return matches_exact_text_filter(node, value) if exact_text == true + regexp = value.is_a?(Regexp) ? value : Regexp.escape(value.to_s) + matches_text_regexp(node, regexp) + end + + def matches_exact_text_filter(node, value) + regexp = value.is_a?(Regexp) ? value : /\A#{Regexp.escape(value.to_s)}\z/ + matches_text_regexp(node, regexp) + end + + def matches_text_regexp(node, regexp) text_visible = visible text_visible = :all if text_visible == :hidden node.text(text_visible).match(regexp) diff --git a/lib/capybara/queries/text_query.rb b/lib/capybara/queries/text_query.rb index 81de9d2e..a0c39016 100644 --- a/lib/capybara/queries/text_query.rb +++ b/lib/capybara/queries/text_query.rb @@ -57,7 +57,7 @@ module Capybara message << " in #{@actual_text.inspect}" details_message = [] - details_message << case_insensitive_message if @node && !@expected_text.is_a?(Regexp) + details_message << case_insensitive_message if @node && check_case_insensitive? details_message << invisible_message if @node && check_visible_text? && report_on_invisible details_message.compact! @@ -75,12 +75,11 @@ module Capybara def invisible_message invisible_text = text(@node, :all) invisible_count = invisible_text.scan(@search_regexp).size - if invisible_count != @count - "it was found #{invisible_count} #{Capybara::Helpers.declension('time', 'times', invisible_count)} including non-visible text" - end + return if invisible_count == @count + "it was found #{invisible_count} #{Capybara::Helpers.declension('time', 'times', invisible_count)} including non-visible text" rescue StandardError # An error getting the non-visible text (if element goes out of scope) should not affect the response - "" + nil end def valid_keys @@ -91,6 +90,10 @@ module Capybara @type == :visible end + def check_case_insensitive? + !@expected_text.is_a?(Regexp) + end + def text(node, query_type) node.text(query_type) end diff --git a/lib/capybara/rack_test/browser.rb b/lib/capybara/rack_test/browser.rb index 15d591ce..f2c3ad68 100644 --- a/lib/capybara/rack_test/browser.rb +++ b/lib/capybara/rack_test/browser.rb @@ -34,7 +34,7 @@ class Capybara::RackTest::Browser end def follow(method, path, **attributes) - return if path.gsub(/^#{Regexp.escape(request_path)}/, '').start_with?('#') || path.downcase.start_with?('javascript:') + return if fragment_or_script?(path) process_and_follow_redirects(method, path, attributes, 'HTTP_REFERER' => current_url) end @@ -63,9 +63,7 @@ class Capybara::RackTest::Browser new_uri.host ||= @current_host new_uri.port ||= @current_port unless new_uri.default_port == @current_port - @current_scheme = new_uri.scheme - @current_host = new_uri.host - @current_port = new_uri.port + @current_scheme, @current_host, @current_port = new_uri.select(:scheme, :host, :port) reset_cache! send(method, new_uri.to_s, attributes, env.merge(options[:headers] || {})) @@ -79,9 +77,7 @@ class Capybara::RackTest::Browser def reset_host! uri = URI.parse(driver.session_options.app_host || driver.session_options.default_host) - @current_scheme = uri.scheme - @current_host = uri.host - @current_port = uri.port + @current_scheme, @current_host, @current_port = uri.select(:scheme, :host, :port) end def reset_cache! @@ -122,4 +118,10 @@ protected rescue Rack::Test::Error "/" end + +private + + def fragment_or_script?(path) + path.gsub(/^#{Regexp.escape(request_path)}/, '').start_with?('#') || path.downcase.start_with?('javascript:') + end end diff --git a/lib/capybara/rack_test/form.rb b/lib/capybara/rack_test/form.rb index be9fa771..8b81b4ff 100644 --- a/lib/capybara/rack_test/form.rb +++ b/lib/capybara/rack_test/form.rb @@ -30,12 +30,9 @@ class Capybara::RackTest::Form < Capybara::RackTest::Node native.xpath(form_elements_xpath).map do |field| case field.name - when 'input' - add_input_param(field, params) - when 'select' - add_select_param(field, params) - when 'textarea' - add_textarea_param(field, params) + when 'input' then add_input_param(field, params) + when 'select' then add_select_param(field, params) + when 'textarea' then add_textarea_param(field, params) end end merge_param!(params, button[:name], button[:value] || "") if button[:name] @@ -44,8 +41,8 @@ class Capybara::RackTest::Form < Capybara::RackTest::Node end def submit(button) - action = (button && button['formaction']) || native['action'] - method = (button && button['formmethod']) || request_method + action = button&.[]('formaction') || native['action'] + method = button&.[]('formmethod') || request_method driver.submit(method, action.to_s, params(button)) end @@ -66,6 +63,7 @@ private end def merge_param!(params, key, value) + key = key.to_s if Rack::Utils.respond_to?(:default_query_parser) Rack::Utils.default_query_parser.normalize_params(params, key, value, Rack::Utils.param_depth_limit) else @@ -85,7 +83,7 @@ private if %w[radio checkbox].include? field['type'] if field['checked'] node = Capybara::RackTest::Node.new(driver, field) - merge_param!(params, field['name'].to_s, node.value.to_s) + merge_param!(params, field['name'], node.value.to_s) end elsif %w[submit image].include? field['type'] # TODO: identify the click button here (in document order, rather @@ -96,29 +94,29 @@ private NilUploadedFile.new else mime_info = MiniMime.lookup_by_filename(value) - Rack::Test::UploadedFile.new(value, (mime_info && mime_info.content_type).to_s) + Rack::Test::UploadedFile.new(value, mime_info&.content_type&.to_s) end - merge_param!(params, field['name'].to_s, file) + merge_param!(params, field['name'], file) else - merge_param!(params, field['name'].to_s, File.basename(field['value'].to_s)) + merge_param!(params, field['name'], File.basename(field['value'].to_s)) end else - merge_param!(params, field['name'].to_s, field['value'].to_s) + merge_param!(params, field['name'], field['value'].to_s) end end def add_select_param(field, params) - if field['multiple'] == 'multiple' + if field.has_attribute?('multiple') field.xpath(".//option[@selected]").each do |option| - merge_param!(params, field['name'].to_s, (option['value'] || option.text).to_s) + merge_param!(params, field['name'], (option['value'] || option.text).to_s) end else option = field.xpath('.//option[@selected]').first || field.xpath('.//option').first - merge_param!(params, field['name'].to_s, (option['value'] || option.text).to_s) if option + merge_param!(params, field['name'], (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")) + merge_param!(params, field['name'], field['_capybara_raw_value'].to_s.gsub(/\n/, "\r\n")) end end diff --git a/lib/capybara/rack_test/node.rb b/lib/capybara/rack_test/node.rb index 53e8ac26..b68c586f 100644 --- a/lib/capybara/rack_test/node.rb +++ b/lib/capybara/rack_test/node.rb @@ -228,26 +228,27 @@ private protected def checkbox_or_radio?(field = self) - field && (field.checkbox? || field.radio?) + field&.checkbox? || field&.radio? end def checkbox? input_field? && type == 'checkbox' end - def input_field? - tag_name == 'input' - end - def radio? input_field? && type == 'radio' end + def text_or_password? + input_field? && (type == 'text' || type == 'password') + end + + def input_field? + tag_name == 'input' + end + def textarea? tag_name == "textarea" end - def text_or_password? - input_field? && (type == 'text' || type == 'password') - end end diff --git a/lib/capybara/result.rb b/lib/capybara/result.rb index 4bec148d..0da7f6f4 100644 --- a/lib/capybara/result.rb +++ b/lib/capybara/result.rb @@ -109,7 +109,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 @result_cache.size <=> min end diff --git a/lib/capybara/selector.rb b/lib/capybara/selector.rb index ecec4c02..13cacd37 100644 --- a/lib/capybara/selector.rb +++ b/lib/capybara/selector.rb @@ -154,9 +154,9 @@ Capybara.add_selector(:link) do matchers = [XPath.attr(:id) == locator, XPath.string.n.is(locator), XPath.attr(:title).is(locator), - XPath.descendant(:img)[XPath.attr(:alt).is(locator)]].reduce(:|) - matchers |= XPath.attr(:'aria-label').is(locator) if enable_aria_label - xpath = xpath[matchers] + XPath.descendant(:img)[XPath.attr(:alt).is(locator)]] + matchers << XPath.attr(:'aria-label').is(locator) if enable_aria_label + xpath = xpath[matchers.reduce(:|)] end xpath = xpath[find_by_attr(:title, title)] @@ -188,7 +188,7 @@ end # @filter [String] :value Matches the value of an input button # Capybara.add_selector(:button) do - xpath(:value, :title, :type) do |locator, **options| + xpath(:value, :title, :type) do |locator, enable_aria_label: false, **options| input_btn_xpath = XPath.descendant(:input)[XPath.attr(:type).one_of('submit', 'reset', 'image', 'button')] btn_xpath = XPath.descendant(:button) image_btn_xpath = XPath.descendant(:input)[XPath.attr(:type) == 'image'] @@ -196,14 +196,14 @@ Capybara.add_selector(:button) do unless locator.nil? locator = locator.to_s locator_matches = XPath.attr(:id).equals(locator) | XPath.attr(:value).is(locator) | XPath.attr(:title).is(locator) - locator_matches |= XPath.attr(:'aria-label').is(locator) if options[:enable_aria_label] + locator_matches |= XPath.attr(:'aria-label').is(locator) if enable_aria_label input_btn_xpath = input_btn_xpath[locator_matches] btn_xpath = btn_xpath[locator_matches | XPath.string.n.is(locator) | XPath.descendant(:img)[XPath.attr(:alt).is(locator)]] alt_matches = XPath.attr(:alt).is(locator) - alt_matches |= XPath.attr(:'aria-label').is(locator) if options[:enable_aria_label] + alt_matches |= XPath.attr(:'aria-label').is(locator) if enable_aria_label image_btn_xpath = image_btn_xpath[alt_matches] end @@ -384,10 +384,9 @@ Capybara.add_selector(:select) do end expression_filter(:with_options) do |expr, options| - options.each do |option| - expr = expr[Capybara::Selector.all[:option].call(option)] + options.inject(expr) do |xpath, option| + xpath[Capybara::Selector.all[:option].call(option)] end - expr end filter(:selected) do |node, selected| @@ -427,10 +426,9 @@ Capybara.add_selector(:datalist_input) do end expression_filter(:with_options) do |expr, options| - options.each do |option| - expr = expr[XPath.attr(:list) == XPath.anywhere(:datalist)[Capybara::Selector.all[:datalist_option].call(option)].attr(:id)] + options.inject(expr) do |xpath, option| + xpath[XPath.attr(:list) == XPath.anywhere(:datalist)[Capybara::Selector.all[:datalist_option].call(option)].attr(:id)] end - expr end describe do |options: nil, with_options: nil, **opts| @@ -544,8 +542,7 @@ 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 - true + true # Non element values were handled through the expression filter end end @@ -566,10 +563,10 @@ end # @filter [String, Array] :class Matches the class(es) provided # Capybara.add_selector(:table) do - xpath(:caption) do |locator, options| + xpath(:caption) do |locator, caption: nil, **_options| xpath = XPath.descendant(:table) xpath = xpath[(XPath.attr(:id) == locator.to_s) | XPath.descendant(:caption).is(locator.to_s)] unless locator.nil? - xpath = xpath[XPath.descendant(:caption) == options[:caption]] if options[:caption] + xpath = xpath[XPath.descendant(:caption) == caption] if caption xpath end diff --git a/lib/capybara/selenium/node.rb b/lib/capybara/selenium/node.rb index 3e5b3543..2444119e 100644 --- a/lib/capybara/selenium/node.rb +++ b/lib/capybara/selenium/node.rb @@ -77,16 +77,12 @@ class Capybara::Selenium::Node < Capybara::Driver::Node end def click(keys = [], options = {}) - if keys.empty? && !(options[:x] && options[:y]) + if keys.empty? && !has_coords?(options) native.click else scroll_if_needed do action_with_modifiers(keys, options) do |a| - if options[:x] && options[:y] - a.click - else - a.click(native) - end + has_coords?(options) ? a.click : a.click(native) end end end @@ -101,11 +97,7 @@ class Capybara::Selenium::Node < Capybara::Driver::Node def right_click(keys = [], options = {}) scroll_if_needed do action_with_modifiers(keys, options) do |a| - if options[:x] && options[:y] - a.context_click - else - a.context_click(native) - end + has_coords?(options) ? a.context_click : a.context_click(native) end end end @@ -113,11 +105,7 @@ class Capybara::Selenium::Node < Capybara::Driver::Node def double_click(keys = [], options = {}) scroll_if_needed do action_with_modifiers(keys, options) do |a| - if options[:x] && options[:y] - a.double_click - else - a.double_click(native) - end + has_coords?(options) ? a.double_click : a.double_click(native) end end end @@ -194,6 +182,10 @@ class Capybara::Selenium::Node < Capybara::Driver::Node private + def has_coords?(options) + options[:x] && options[:y] + end + def boolean_attr(val) val && (val != "false") end diff --git a/lib/capybara/session.rb b/lib/capybara/session.rb index 9b352b0d..25956b34 100644 --- a/lib/capybara/session.rb +++ b/lib/capybara/session.rb @@ -193,7 +193,7 @@ module Capybara return nil if uri&.scheme == "about" path = uri&.path - path if !path&.empty? + path unless path&.empty? end ## diff --git a/spec/result_spec.rb b/spec/result_spec.rb index 8cebceb1..ab88fa33 100644 --- a/spec/result_spec.rb +++ b/spec/result_spec.rb @@ -138,6 +138,12 @@ RSpec.describe Capybara::Result do expect(result.instance_variable_get('@result_cache').size).to be 4 end + it "should only need to evaluate one result for any?" do + skip 'JRuby has an issue with lazy enumerator evaluation' if RUBY_PLATFORM == 'java' + result.any? + expect(result.instance_variable_get('@result_cache').size).to be 1 + end + it "should evaluate all elements when #to_a called" do # All cached when converted to array result.to_a