diff --git a/lib/capybara/node/matchers.rb b/lib/capybara/node/matchers.rb index d1dee99c..4fa36b05 100644 --- a/lib/capybara/node/matchers.rb +++ b/lib/capybara/node/matchers.rb @@ -196,6 +196,42 @@ module Capybara has_no_xpath?(XPath::HTML.content(content)) end + ## + # + # Checks if the page or current node has the given text content, + # ignoring any HTML tags and normalizing whitespace. + # + # Unlike has_content this only matches text displayed on the page + # and specifically excludes text contained within script nodes. + # + # @param [String] content The text to check for + # @return [Boolean] Whether it exists + # + def has_text?(content) + literal = XPath::Expression::StringLiteral.new(content).to_xpath + expression = "./descendant-or-self::*[text()[contains(normalize-space(.), #{literal})] and not(ancestor-or-self::script)]" + + has_xpath?(expression) + end + + ## + # + # Checks if the page or current node does not have the given text + # content, ignoring any HTML tags and normalizing whitespace. + # + # Unlike has_content this only matches text displayed on the page + # and specifically excludes text contained within script nodes. + # + # @param [String] content The text to check for + # @return [Boolean] Whether it exists + # + def has_no_text?(content) + literal = XPath::Expression::StringLiteral.new(content).to_xpath + expression = "./descendant-or-self::*[text()[contains(normalize-space(.), #{literal})] and not(ancestor-or-self::script)]" + + has_no_xpath?(expression) + end + ## # # Checks if the page or current node has a link with the given diff --git a/lib/capybara/rspec/matchers.rb b/lib/capybara/rspec/matchers.rb index 33689573..dc19130b 100644 --- a/lib/capybara/rspec/matchers.rb +++ b/lib/capybara/rspec/matchers.rb @@ -122,6 +122,12 @@ module Capybara %(expected there to be content #{matcher.locator.inspect} in #{page.text.inspect}) end end + + def have_text(text) + HaveMatcher.new(:text, text.to_s) do |page, matcher| + %(expected there to be text #{matcher.locator.inspect} in #{page.text.inspect}) + end + end def have_link(locator, options={}) HaveMatcher.new(:link, locator, options) diff --git a/lib/capybara/session.rb b/lib/capybara/session.rb index e7833931..fd503395 100644 --- a/lib/capybara/session.rb +++ b/lib/capybara/session.rb @@ -30,7 +30,8 @@ module Capybara :all, :first, :attach_file, :text, :check, :choose, :click_link_or_button, :click_button, :click_link, :field_labeled, :fill_in, :find, :find_button, :find_by_id, :find_field, :find_link, - :has_content?, :has_css?, :has_no_content?, :has_no_css?, :has_no_xpath?, + :has_content?, :has_text?, :has_css?, :has_no_content?, :has_no_text?, + :has_no_css?, :has_no_xpath?, :has_xpath?, :select, :uncheck, :has_link?, :has_no_link?, :has_button?, :has_no_button?, :has_field?, :has_no_field?, :has_checked_field?, :has_unchecked_field?, :has_no_table?, :has_table?, :unselect, diff --git a/lib/capybara/spec/session.rb b/lib/capybara/spec/session.rb index 6edc3997..b36da286 100644 --- a/lib/capybara/spec/session.rb +++ b/lib/capybara/spec/session.rb @@ -98,6 +98,7 @@ shared_examples_for "session" do it_should_behave_like "find_by_id" it_should_behave_like "find" it_should_behave_like "has_content" + it_should_behave_like "has_text" it_should_behave_like "has_css" it_should_behave_like "has_css" it_should_behave_like "has_selector" diff --git a/lib/capybara/spec/session/has_text_spec.rb b/lib/capybara/spec/session/has_text_spec.rb new file mode 100644 index 00000000..45da700d --- /dev/null +++ b/lib/capybara/spec/session/has_text_spec.rb @@ -0,0 +1,15 @@ +shared_examples_for 'has_text' do + describe '#has_text?' do + it 'works' do + @session.visit('/with_html') + @session.should have_text('Lorem') + end + end + + describe '#has_no_text?' do + it 'works' do + @session.visit('/with_html') + @session.should have_no_text('Merol') + end + end +end