prix-fixe

Expand History Expand History
Collapse History Collapse History

Internationalize application’s text

When the UserSharesAMessageTest internationalizes the test step to click on an <a> element that contains the text Share a Note with I18n.translate("notes.index.new"), the following error is raised:

Error:
UserSharesAMessageTest#test_visiting_the_index:
Capybara::ElementNotFound: Unable to find link or button "translation missing: en.notes.index.new"
    test/system/user_shares_a_message_test.rb:8:in `block in <class:UserSharesAMessageTest>'

The key, notes.index.new was selected intentionally. The notes portion corresponds to the notes controller’s internationalization namespace. The index portion corresponds to the NotesController‘s index action. The new portion is arbitrary, but represents the text that will be rendered into an <a> element linking to the notes#new route.

Capybara raises this error stating that the text "translation missing: en.notes.index.new" is not present on the server-generated page. The en portion prefixing the rest of the internationalization key is derived from the request’s current locale (i.e. English). This error is not particularly helpful in driving our next code change: rendering "translation missing: en.notes.index.new" on the page is not a desired behavior.

The text "translation missing: en.notes.index.new" comes from Rails’ flexible, forgiving default translation behavior while in development and test environments.

This commit changes that default behavior.

First, it replaces the test’s call to I18n.translate with calls to ActionView::Helpers::TranslationHelper#translate.

Next, by un-commenting the lines in config/environments/test.rb (and config/environments/development.rb for test/development parity) and ensuring that our test suite internationalizes text with the same translate that ActionView uses, a newer and more helpful error message is raised:

Error:
UserSharesAMessageTest#test_visiting_the_index:
I18n::MissingTranslationData: translation missing: en.notes.index.new
    test/system/user_shares_a_message_test.rb:8:in `block in <class:UserSharesAMessageTest>'

When that key is declared within the config/locales/en.yml file, the test passes.

Finally, this commit replaces the Share a Note text that is hard-coded in the notes/index.html.erb template with a call to translate.

By rendering <%= translate(".new") %> in the notes#index view template, Rails will resolve the .new internationalization key relative the current “context”, which is a request to notes#index.

The context is translated into an internationalization scope: notes.index. This internationalization scope is prepended to the relative .new key, which is then prepended with the current locale of en.

This process generates a fully-qualified internationalization key of en.notes.index.new, which corresponds to the translation we declared in our test.