diff --git a/lib/capybara/node/simple.rb b/lib/capybara/node/simple.rb index d55b410f..4640aefb 100644 --- a/lib/capybara/node/simple.rb +++ b/lib/capybara/node/simple.rb @@ -94,10 +94,17 @@ module Capybara # Whether or not the element is visible. Does not support CSS, so # the result may be inaccurate. # + # @param [Boolean] check_ancestors Whether to inherit visibility from ancestors # @return [Boolean] Whether the element is visible # - def visible? - native.xpath("./ancestor-or-self::*[contains(@style, 'display:none') or contains(@style, 'display: none') or @hidden or name()='script' or name()='head']").size == 0 + def visible?(check_ancestors = true) + if check_ancestors + #check size because oldest supported nokogiri doesnt support xpath boolean() function + native.xpath("./ancestor-or-self::*[contains(@style, 'display:none') or contains(@style, 'display: none') or @hidden or name()='script' or name()='head']").size() == 0 + else + #no need for an xpath if only checking the current element + !(native.has_attribute?('hidden') || (native[:style] =~ /display:\s?none/) || %w(script head).include?(tag_name)) + end end ## diff --git a/lib/capybara/rack_test/node.rb b/lib/capybara/rack_test/node.rb index 37ea24aa..8908405c 100644 --- a/lib/capybara/rack_test/node.rb +++ b/lib/capybara/rack_test/node.rb @@ -99,14 +99,14 @@ class Capybara::RackTest::Node < Capybara::Driver::Node protected - def unnormalized_text - if !visible? + def unnormalized_text(check_ancestor_visibility = true) + if !string_node.visible?(check_ancestor_visibility) '' elsif native.text? native.text elsif native.element? native.children.map do |child| - Capybara::RackTest::Node.new(driver, child).unnormalized_text + Capybara::RackTest::Node.new(driver, child).unnormalized_text(false) end.join else '' diff --git a/lib/capybara/spec/session/text_spec.rb b/lib/capybara/spec/session/text_spec.rb index 88abb67e..7008f5c7 100644 --- a/lib/capybara/spec/session/text_spec.rb +++ b/lib/capybara/spec/session/text_spec.rb @@ -34,6 +34,11 @@ Capybara::SpecHelper.spec '#text' do Capybara.ignore_hidden_elements = false expect(@session.find(:id, "hidden-text").text).to eq('Some of this text is') end + + it "ignores invisible text if ancestor is invisible" do + @session.visit('/with_html') + expect(@session.find(:id, "hidden_via_ancestor", visible: false).text).to eq('') + end context "with css as default selector" do before { Capybara.default_selector = :css }