diff --git a/lib/capybara.rb b/lib/capybara.rb index 785e2401..91c7b396 100644 --- a/lib/capybara.rb +++ b/lib/capybara.rb @@ -16,7 +16,7 @@ module Capybara class << self attr_accessor :asset_root, :app_host, :run_server, :default_host, :always_include_port - attr_accessor :server_host, :server_port, :exact, :match, :exact_options + attr_accessor :server_host, :server_port, :exact, :match, :exact_options, :visible_text_only attr_accessor :default_selector, :default_wait_time, :ignore_hidden_elements attr_accessor :save_and_open_page_path, :automatic_reload, :raise_server_errors attr_writer :default_driver, :current_driver, :javascript_driver, :session_name @@ -347,6 +347,7 @@ Capybara.configure do |config| config.match = :smart config.exact = false config.raise_server_errors = true + config.visible_text_only = false end Capybara.register_driver :rack_test do |app| diff --git a/lib/capybara/driver/node.rb b/lib/capybara/driver/node.rb index fb89930a..88ae641d 100644 --- a/lib/capybara/driver/node.rb +++ b/lib/capybara/driver/node.rb @@ -8,7 +8,11 @@ module Capybara @native = native end - def text + def all_text + raise NotImplementedError + end + + def visible_text raise NotImplementedError end @@ -64,7 +68,7 @@ module Capybara def path raise NotSupportedByDriverError end - + def trigger(event) raise NotSupportedByDriverError end diff --git a/lib/capybara/node/element.rb b/lib/capybara/node/element.rb index c63ab366..34ec0a0d 100644 --- a/lib/capybara/node/element.rb +++ b/lib/capybara/node/element.rb @@ -42,10 +42,26 @@ module Capybara ## # - # @return [String] The text of the element + # Retrieve the text of the element. If `Capybara.ignore_hidden_elements` + # is `true`, which it is by default, then this will return only text + # which is visible. The exact semantics of this may differ between + # drivers, but generally any text within elements with `display:none` is + # ignored. This behaviour can be overridden by passing `:all` to this + # method. # - def text - synchronize { base.text } + # @param [:all, :visible] Whether to return only visible or all text + # + # @return [String] The text of the element + # + def text(type=nil) + type ||= :all unless Capybara.ignore_hidden_elements or Capybara.visible_text_only + synchronize do + if type == :all + base.all_text + else + base.visible_text + end + end end ## diff --git a/lib/capybara/rack_test/node.rb b/lib/capybara/rack_test/node.rb index cc7f7888..a91deec4 100644 --- a/lib/capybara/rack_test/node.rb +++ b/lib/capybara/rack_test/node.rb @@ -1,5 +1,9 @@ class Capybara::RackTest::Node < Capybara::Driver::Node - def text + def all_text + Capybara::Helpers.normalize_whitespace(native.text) + end + + def visible_text Capybara::Helpers.normalize_whitespace(unnormalized_text) end diff --git a/lib/capybara/spec/session/text_spec.rb b/lib/capybara/spec/session/text_spec.rb index f8d6e0e4..3342d64a 100644 --- a/lib/capybara/spec/session/text_spec.rb +++ b/lib/capybara/spec/session/text_spec.rb @@ -4,6 +4,37 @@ Capybara::SpecHelper.spec '#text' do @session.text.should == 'Bar' end + it "ignores invisible text by default" do + @session.visit('/with_html') + @session.find(:id, "hidden-text").text.should == 'Some of this text is' + end + + it "shows invisible text if `:all` given" do + @session.visit('/with_html') + @session.find(:id, "hidden-text").text(:all).should == 'Some of this text is hidden!' + end + + it "ignores invisible text if `:visible` given" do + Capybara.ignore_hidden_elements = false + @session.visit('/with_html') + @session.find(:id, "hidden-text").text(:visible).should == 'Some of this text is' + end + + it "ignores invisible text if `Capybara.ignore_hidden_elements = true`" do + @session.visit('/with_html') + @session.find(:id, "hidden-text").text.should == 'Some of this text is' + Capybara.ignore_hidden_elements = false + @session.find(:id, "hidden-text").text.should == 'Some of this text is hidden!' + end + + it "ignores invisible text if `Capybara.visible_text_only = true`" do + @session.visit('/with_html') + Capybara.visible_text_only = true + @session.find(:id, "hidden-text").text.should == 'Some of this text is' + Capybara.ignore_hidden_elements = false + @session.find(:id, "hidden-text").text.should == 'Some of this text is' + end + context "with css as default selector" do before { Capybara.default_selector = :css } it "should print the text of the page" do diff --git a/lib/capybara/spec/spec_helper.rb b/lib/capybara/spec/spec_helper.rb index dd47b54f..3621435c 100644 --- a/lib/capybara/spec/spec_helper.rb +++ b/lib/capybara/spec/spec_helper.rb @@ -23,6 +23,7 @@ module Capybara Capybara.exact = false Capybara.exact_options = false Capybara.raise_server_errors = true + Capybara.visible_text_only = false Capybara.match = :smart end diff --git a/lib/capybara/spec/views/with_html.erb b/lib/capybara/spec/views/with_html.erb index babb19a9..c63229e0 100644 --- a/lib/capybara/spec/views/with_html.erb +++ b/lib/capybara/spec/views/with_html.erb @@ -61,6 +61,10 @@ banana hidden link +
+ Some of this text is hidden! +
+