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 error_pages.feature
:
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!