Skip to content

Instantly share code, notes, and snippets.

@halilim
Last active March 28, 2016 14:08
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 halilim/9c45abdcc50074cad860 to your computer and use it in GitHub Desktop.
Save halilim/9c45abdcc50074cad860 to your computer and use it in GitHub Desktop.
Rails RSpec I18n full error message helper for Capybara feature tests. Feels like there should be a better way, ping me if you can find one :) Stack Overflow link: http://stackoverflow.com/questions/34494599/rails-i18n-full-error-messages-in-rspec-capybara-feature-tests
# spec/support/helpers.rb
require 'support/helpers/i18n_helpers'
# ...
RSpec.configure do |config|
config.include Features::I18nHelpers, type: :feature
# ...
end
# spec/support/helpers/i18n_helpers.rb
module Features
module I18nHelpers
# @param [ActiveRecord::Base] model_class
# @param [Symbol, String] attribute
# @param [Symbol, String] message
#
# @return [String]
def full_error(model_class, attribute, message)
@_i18n_dummies ||= {}
@_i18n_dummies[model_class] ||= model_class.new
@_i18n_dummies[model_class].errors.full_message(
attribute,
@_i18n_dummies[model_class].errors.generate_message(attribute, message)
)
end
end
end
# spec/features/post_spec.rb
feature 'Posts' do
scenario 'Creating a new post'
visit new_post_path
click_button 'Submit'
# Expecting an error message 'Title can't be blank'
expect(page).to have_content full_error(Post, :title, :blank)
end
end
@koenpunt
Copy link

When having nested attributes, the error message is prefixed with the model name, and thus the attribute passed to full_message should be prefixed.

So I've updated it to the following:

    # error messages for nested attributes are prefixed with the model name
    attr_name = attribute.to_s.split('.').last
    @_i18n_dummies[model_class].errors.full_message(
      attribute,
      @_i18n_dummies[model_class].errors.generate_message(attr_name, message)
    )

And usage:

expect(page).to have_content full_error(Post, :"post.title", :blank)

@halilim
Copy link
Author

halilim commented Mar 28, 2016

@koenpunt AFAIK since the receiver of #generate_message is @_i18n_dummies[model_class].errors, it's already scoped to the relevant model class. The original code should work if called like full_error(Post, :title, :blank).

full_error(Page, :title, :blank) # => "Başlık doldurulmalı"
full_error(User, :title, :blank) # => "Unvan doldurulmalı"
# (a page title and a user title (position name) are different words in Turkish)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment