Skip to content

Instantly share code, notes, and snippets.

@robotdana
Forked from beccasaurus/Gemfile
Last active August 10, 2022 05:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robotdana/2910124030368437ccdd3ad2e46e7d4b to your computer and use it in GitHub Desktop.
Save robotdana/2910124030368437ccdd3ad2e46e7d4b 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 'https://rubygems.org'
gem "rspec"
gem "capybara"
gem "selenium-webdriver"
gem "webdrivers"
gem 'puma'
GEM
remote: https://rubygems.org/
specs:
addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
capybara (3.37.1)
addressable
matrix
mini_mime (>= 0.1.3)
nokogiri (~> 1.8)
rack (>= 1.6.0)
rack-test (>= 0.6.3)
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
childprocess (4.1.0)
diff-lcs (1.5.0)
matrix (0.4.2)
mini_mime (1.1.2)
nio4r (2.5.8)
nokogiri (1.13.8-arm64-darwin)
racc (~> 1.4)
public_suffix (4.0.7)
puma (5.6.4)
nio4r (~> 2.0)
racc (1.6.0)
rack (2.2.4)
rack-test (2.0.2)
rack (>= 1.3)
regexp_parser (2.5.0)
rexml (3.2.5)
rspec (3.11.0)
rspec-core (~> 3.11.0)
rspec-expectations (~> 3.11.0)
rspec-mocks (~> 3.11.0)
rspec-core (3.11.0)
rspec-support (~> 3.11.0)
rspec-expectations (3.11.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.11.0)
rspec-mocks (3.11.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.11.0)
rspec-support (3.11.0)
rubyzip (2.3.2)
selenium-webdriver (4.4.0)
childprocess (>= 0.5, < 5.0)
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0)
webdrivers (5.0.0)
nokogiri (~> 1.6)
rubyzip (>= 1.3.0)
selenium-webdriver (~> 4.0)
websocket (1.2.9)
xpath (3.2.0)
nokogiri (~> 1.8)
PLATFORMS
arm64-darwin-21
DEPENDENCIES
capybara
puma
rspec
selenium-webdriver
webdrivers
BUNDLED WITH
2.3.19
<!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 'bundler/setup'
require "capybara/rspec"
require "selenium-webdriver"
require 'webdrivers'
Capybara.app = Rack::Directory.new File.dirname(__FILE__)
Capybara.default_max_wait_time = 5
Capybara.disable_animation = true
Capybara.register_driver :chrome do |app|
options = Selenium::WebDriver::Chrome::Options.new
Capybara::Selenium::Driver.new app, browser: :chrome, capabilities: [options]
end
Capybara.javascript_driver = :chrome
RSpec.configure do |config|
config.include Capybara::DSL
end
RSpec.describe "Capybara RSpec Matcher", type: :system, js: true do
before do |example|
visit "/page.html"
end
it "page.should_not have_content (should be the same as page.has_no_content?)" do
expect(page).to_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
expect(page).to 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
expect(page).to_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
expect(page).to have_selector "#selector-that-will-APPEAR-after-a-few-seconds"
end
it "fails after 5s: page.should_not have_content (should be the same as page.has_no_content?)" do
expect(page).to_not have_content "Content that will"
end
it "fails after 5s: page.should have_content (should be the same as page.has_content?)" do
expect(page).to have_content "Content that will never appear"
end
it "fails after 5s: page.should_not have_selector (should be the same as page.has_no_selector?)" do
expect(page).to_not have_selector "div[id]"
end
it "fails after 5s: page.should have_selector (should be the same as page.has_selector?)" do
expect(page).to have_selector "#selector-that-will-never-APPEAR"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment