When your application raises an error during development, Rails and Webrat will provide you with useful information like the error's type and stacktrace.
But now you created that shiny, custom error page by overriding
rescue_action_in_public. You would like to write a Cucumber feature that tests whether your new error page localizes into 10 languages and displays all the information it should.
Unfortunately it requires some serious Judo to make your error page visible to selected scenarios, while keeping Rails' helpful default behavior for your other tests. Here is how you do it.
First, we will tame Webrat. Webrat raises an exception when you visit a page that shows an error. So we're going to write a step that visits a page, but ignores errors:
When /^I ignore errors while visiting (.+)$/ do |page_name| begin visit path_to(page_name) rescue end end
Now we need to get Rails to render the error page for selected scenarios. Unfortunately we will have to flip a lot of switches to accomplish this.
Put the following into your
support/env.rb. With this code we can make Rails treat selected requests as remote ones, (local requests never see error pages), regardless of what
consider_all_requests_local is set to:
ActionController::Base.class_eval do protected cattr_accessor :local_request_override def local_request_with_override? local_request_override.nil? ? local_request_without_override? : local_request_override end alias_method_chain :local_request?, :override end
Finally we need a step that flips all the magic switches for the current scenario and reverts to the previous error handling afterwards:
Given /^error pages will be rendered$/ do @old_allow_rescue = ActionController::Base.allow_rescue @old_consider_all_requests_local = ActionController::Base.consider_all_requests_local @old_local_request_override = ActionController::Base.local_request_override ActionController::Base.local_request_override = false ActionController::Base.allow_rescue = true ActionController::Base.consider_all_requests_local = false end After do @old_allow_rescue.nil? or ActionController::Base.allow_rescue = @old_allow_rescue @old_consider_all_requests_local.nil? or ActionController::Base.consider_all_requests_local = @old_consider_all_requests_local @old_local_request_override.nil? or ActionController::Base.local_request_override = @old_local_request_override end
Now you can write your
Feature: custom error pages In order to not scare my users when things go wrong As the site owner I want to display friendly error pages Scenario: A country cannot be found Given error pages will be rendered And I ignore errors while visiting the country "Narnia" Then I should see "Oops, we couldn't find Narnia!"
I recommend you extend your feature to cover some more cases and also make it check if proper HTTP status codes are returned.
Was this post helpful to you? Then let us know!