Skip to content

Instantly share code, notes, and snippets.

@nruth
Last active August 29, 2015 14:28
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 nruth/736df5a57e2771d94f24 to your computer and use it in GitHub Desktop.
Save nruth/736df5a57e2771d94f24 to your computer and use it in GitHub Desktop.
capybara ensure page changed
<!DOCTYPE html>
<html lang="en">
<head>
<# only include in the test env to avoid uuid generation slowing down every rendered page in production %>
<% if Rails.env.test? %>
<meta name='test-page' content="<%= SecureRandom.uuid %>">
<% end %>
<%# etc, all your usual content %>
</head
</html>
# this works with selenium, but not with the webkit driver
# webkit seems to have nasty race conditions regarding has_css? and page loading, i.e. it returns before the page finishes loading, meaning race conditions in your tests and this not working
# but for selenium (chromedriver) it seems to work nicely, putting you back in the rack-test situation of synchronous test actions (where you need them)
module Capybara::EnsurePageChanged
def ensure_page_changed(&block)
current_page = page.find("meta[name='test-page']", visible: false)['value']
yield block
expect(page).not_to have_css("meta[name='test-page'][value='#{current_page}']", visible: false)
expect(page).to have_css("meta[name='test-page']", visible: false)
end
end
# normally this will pass in rack-test, but be prone to race conditions in other drivers, because the capybara drivers send the delete command but don't wait for something to happen, you have to tell it what to wait for.
# Here we tell it to wait for a new page.
# You could tell it about something on the new page, but in some cases (such as surveys or exams with user-specified page content) it's useful to have a test helper handle this for you without relying on the page content
# and it's always helpful to have a go-to helper with a (fairly) easy to remember name
specify 'delete something' do
expect do
ensure_page_changed do
click_on("Delete")
end
end.to change { Something.count }.by(-1)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment