Skip to content

Instantly share code, notes, and snippets.

@beccasaurus
Created June 19, 2012 15:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save beccasaurus/2954949 to your computer and use it in GitHub Desktop.
Save beccasaurus/2954949 to your computer and use it in GitHub Desktop.
Double checking that Capybara's RSpec matchers work as advertised

Capybara's README used to make a point of saying that you should use page.should have_no_content and have_no_selector when asserting the lack of some element/content (because these methods wait for the elements to disappear, if the selected Capybara driver supports waiting).

Now, Capybara's RSpec matchers have been improved so (per the documentation) saying page.should_not have_content is now functionally equivalent to saying page.should have_no_content (because it will call page.has_no_content? instead of reversing the result of page.has_content? which is not the same because of waiting).

Anywho, Capybara's code looks clear but here's a spec just to double check! 😃

Output of running the test

Capybara RSpec Matcher
TEST: page.should_not have_content (should be the same as page.has_no_content?)
	Capybara::Node::Document#has_no_content?(["Content that will go away after a few seconds"], &nil)
	Capybara::Node::Document#has_no_selector?([:xpath, ./descendant-or-self::*[contains(normalize-space(.), 'Content that will go away after a few seconds')], {}], &nil)
  page.should_not have_content (should be the same as page.has_no_content?)
TEST: page.should have_content (should be the same as page.has_content?)
	Capybara::Node::Document#has_content?(["Content that will APPEAR after a few seconds"], &nil)
	Capybara::Node::Document#has_selector?([:xpath, ./descendant-or-self::*[contains(normalize-space(.), 'Content that will APPEAR after a few seconds')], {}], &nil)
  page.should have_content (should be the same as page.has_content?)
TEST: page.should_not have_selector (should be the same as page.has_no_selector?)
	Capybara::Node::Document#has_no_selector?(["#selector-that-will-go-away-after-a-few-seconds"], &nil)
  page.should_not have_selector (should be the same as page.has_no_selector?)
TEST: page.should have_selector (should be the same as page.has_selector?)
	Capybara::Node::Document#has_selector?(["#selector-that-will-APPEAR-after-a-few-seconds"], &nil)
  page.should have_selector (should be the same as page.has_selector?)

Finished in 9.39 seconds
4 examples, 0 failures
source :rubygems
# Locking these to the exact versions used in a project I'm working on (experimenting)
gem "rspec", "2.10.0"
gem "capybara", "1.1.2"
gem "selenium-webdriver", "2.22.2"
<!DOCTYPE html>
<html>
<head>
<title>Capybara RSpec Matcher Test</title>
<script>
function load() {
// After the page loads, let's wait 2 seconds then
// add some content to the DOM and remove other content.
setTimeout(function(){
var elementToRemove = document.getElementById("selector-that-will-go-away-after-a-few-seconds");
var elementToAdd = document.createElement("div");
elementToAdd.id = "selector-that-will-APPEAR-after-a-few-seconds";
elementToAdd.innerText = "Content that will APPEAR after a few seconds";
elementToAdd.textContent = "Content that will APPEAR after a few seconds";
document.body.removeChild(elementToRemove);
document.body.appendChild(elementToAdd);
}, 2000);
}
</script>
</head>
<body onload="load();">
<div id="selector-that-will-go-away-after-a-few-seconds">
Content that will go away after a few seconds
</div>
</body>
</html>
require "rubygems"
require "capybara/rspec"
require "rack"
# Monkeypatching to add useful tracing
#
# NOTE: this ONLY adds tracing. The tests run the same without this monkeypatch.
#
module Capybara::Node::Matchers
alias original_has_content? has_content?
alias original_has_no_content? has_no_content?
alias original_has_selector? has_selector?
alias original_has_no_selector? has_no_selector?
def trace_me(method_name, *args, &block)
puts "\t#{self.class.name}##{method_name}(#{args.inspect}, &#{block.inspect})"
send "original_#{method_name}", *args, &block
end
def has_content?( *args, &block) trace_me(:has_content?, *args, &block) end
def has_no_content?( *args, &block) trace_me(:has_no_content?, *args, &block) end
def has_selector?( *args, &block) trace_me(:has_selector?, *args, &block) end
def has_no_selector?(*args, &block) trace_me(:has_no_selector?, *args, &block) end
end
Capybara.app = Rack::Directory.new File.dirname(__FILE__)
Capybara.default_wait_time = 5
describe "Capybara RSpec Matcher", :type => "request", :js => true do
before do
visit "/page.html"
puts "TEST: #{example.description}" # Trace current example (to make Capybara traces useful)
end
it "page.should_not have_content (should be the same as page.has_no_content?)" do
page.should_not have_content "Content that will go away after a few seconds"
end
it "page.should have_content (should be the same as page.has_content?)" do
page.should have_content "Content that will APPEAR after a few seconds"
end
it "page.should_not have_selector (should be the same as page.has_no_selector?)" do
page.should_not have_selector "#selector-that-will-go-away-after-a-few-seconds"
end
it "page.should have_selector (should be the same as page.has_selector?)" do
page.should have_selector "#selector-that-will-APPEAR-after-a-few-seconds"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment