Commit e9f5987a authored by Lin Jen-Shin's avatar Lin Jen-Shin

Update test guidelines for externalized contents

parent b202c100
...@@ -171,6 +171,45 @@ If you need to translate strings in the Vue component's JavaScript, you can impo ...@@ -171,6 +171,45 @@ If you need to translate strings in the Vue component's JavaScript, you can impo
To test Vue translations, learn about [manually testing translations from the UI](#manually-test-translations-from-the-ui). To test Vue translations, learn about [manually testing translations from the UI](#manually-test-translations-from-the-ui).
### Test files
Test expectations against externalized contents should not be hard coded,
because we may need to run the tests with non-default locale, and tests with
hard coded contents will fail.
This means any expectations against externalized contents should call the
same externalizing method to match the translation.
Bad:
```ruby
click_button 'Submit review'
expect(rendered).to have_content('Thank you for your feedback!')
```
Good:
```ruby
click_button _('Submit review')
expect(rendered).to have_content(_('Thank you for your feedback!'))
```
This includes JavaScript tests:
Bad:
```javascript
expect(findUpdateIgnoreStatusButton().text()).toBe('Ignore');
```
Good:
```javascript
expect(findUpdateIgnoreStatusButton().text()).toBe(__('Ignore'));
```
#### Recommendations #### Recommendations
If strings are reused throughout a component, it can be useful to define these strings as variables. We recommend defining an `i18n` property on the component's `$options` object. If there is a mixture of many-use and single-use strings in the component, consider using this approach to create a local [Single Source of Truth](https://about.gitlab.com/handbook/values/#single-source-of-truth) for externalized strings. If strings are reused throughout a component, it can be useful to define these strings as variables. We recommend defining an `i18n` property on the component's `$options` object. If there is a mixture of many-use and single-use strings in the component, consider using this approach to create a local [Single Source of Truth](https://about.gitlab.com/handbook/values/#single-source-of-truth) for externalized strings.
......
...@@ -367,26 +367,34 @@ If needed, you can scope interactions within a specific area of the page by usin ...@@ -367,26 +367,34 @@ If needed, you can scope interactions within a specific area of the page by usin
As you will likely be scoping to an element such as a `div`, which typically does not have a label, As you will likely be scoping to an element such as a `div`, which typically does not have a label,
you may use a `data-testid` selector in this case. you may use a `data-testid` selector in this case.
##### Externalized contents
Test expectations against externalized contents should call the same
externalizing method to match the translation. For example, you should use the `_`
method in Ruby and `__` method in JavaScript.
See [Internationalization for GitLab - Test files](../i18n/externalization.md#test-files) for details.
##### Actions ##### Actions
Where possible, use more specific [actions](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Actions), such as the ones below. Where possible, use more specific [actions](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Actions), such as the ones below.
```ruby ```ruby
# good # good
click_button 'Submit review' click_button _('Submit review')
click_link 'UI testing docs' click_link _('UI testing docs')
fill_in 'Search projects', with: 'gitlab' # fill in text input with text fill_in _('Search projects'), with: 'gitlab' # fill in text input with text
select 'Last updated', from: 'Sort by' # select an option from a select input select _('Last updated'), from: 'Sort by' # select an option from a select input
check 'Checkbox label' check _('Checkbox label')
uncheck 'Checkbox label' uncheck _('Checkbox label')
choose 'Radio input label' choose _('Radio input label')
attach_file('Attach a file', '/path/to/file.png') attach_file(_('Attach a file'), '/path/to/file.png')
# bad - interactive elements must have accessible names, so # bad - interactive elements must have accessible names, so
# we should be able to use one of the specific actions above # we should be able to use one of the specific actions above
...@@ -403,17 +411,17 @@ Where possible, use more specific [finders](https://rubydoc.info/github/teamcapy ...@@ -403,17 +411,17 @@ Where possible, use more specific [finders](https://rubydoc.info/github/teamcapy
```ruby ```ruby
# good # good
find_button 'Submit review' find_button _('Submit review')
find_button 'Submit review', disabled: true find_button _('Submit review'), disabled: true
find_link 'UI testing docs' find_link _('UI testing docs')
find_link 'UI testing docs', href: docs_url find_link _('UI testing docs'), href: docs_url
find_field 'Search projects' find_field _('Search projects')
find_field 'Search projects', with: 'gitlab' # find the input field with text find_field _('Search projects'), with: 'gitlab' # find the input field with text
find_field 'Search projects', disabled: true find_field _('Search projects'), disabled: true
find_field 'Checkbox label', checked: true find_field _('Checkbox label'), checked: true
find_field 'Checkbox label', unchecked: true find_field _('Checkbox label'), unchecked: true
# acceptable when finding a element that is not a button, link, or field # acceptable when finding a element that is not a button, link, or field
find('[data-testid="element"]') find('[data-testid="element"]')
...@@ -425,31 +433,31 @@ Where possible, use more specific [matchers](https://rubydoc.info/github/teamcap ...@@ -425,31 +433,31 @@ Where possible, use more specific [matchers](https://rubydoc.info/github/teamcap
```ruby ```ruby
# good # good
expect(page).to have_button 'Submit review' expect(page).to have_button _('Submit review')
expect(page).to have_button 'Submit review', disabled: true expect(page).to have_button _('Submit review'), disabled: true
expect(page).to have_button 'Notifications', class: 'is-checked' # assert the "Notifications" GlToggle is checked expect(page).to have_button _('Notifications'), class: 'is-checked' # assert the "Notifications" GlToggle is checked
expect(page).to have_link 'UI testing docs' expect(page).to have_link _('UI testing docs')
expect(page).to have_link 'UI testing docs', href: docs_url # assert the link has an href expect(page).to have_link _('UI testing docs'), href: docs_url # assert the link has an href
expect(page).to have_field 'Search projects' expect(page).to have_field _('Search projects')
expect(page).to have_field 'Search projects', disabled: true expect(page).to have_field _('Search projects'), disabled: true
expect(page).to have_field 'Search projects', with: 'gitlab' # assert the input field has text expect(page).to have_field _('Search projects'), with: 'gitlab' # assert the input field has text
expect(page).to have_checked_field 'Checkbox label' expect(page).to have_checked_field _('Checkbox label')
expect(page).to have_unchecked_field 'Radio input label' expect(page).to have_unchecked_field _('Radio input label')
expect(page).to have_select 'Sort by' expect(page).to have_select _('Sort by')
expect(page).to have_select 'Sort by', selected: 'Last updated' # assert the option is selected expect(page).to have_select _('Sort by'), selected: 'Last updated' # assert the option is selected
expect(page).to have_select 'Sort by', options: ['Last updated', 'Created date', 'Due date'] # assert an exact list of options expect(page).to have_select _('Sort by'), options: ['Last updated', 'Created date', 'Due date'] # assert an exact list of options
expect(page).to have_select 'Sort by', with_options: ['Created date', 'Due date'] # assert a partial list of options expect(page).to have_select _('Sort by'), with_options: ['Created date', 'Due date'] # assert a partial list of options
expect(page).to have_text 'Some paragraph text.' expect(page).to have_text _('Some paragraph text.')
expect(page).to have_text 'Some paragraph text.', exact: true # assert exact match expect(page).to have_text _('Some paragraph text.'), exact: true # assert exact match
expect(page).to have_current_path 'gitlab/gitlab-test/-/issues' expect(page).to have_current_path 'gitlab/gitlab-test/-/issues'
expect(page).to have_title 'Not Found' expect(page).to have_title _('Not Found')
# acceptable when a more specific matcher above is not possible # acceptable when a more specific matcher above is not possible
expect(page).to have_css 'h2', text: 'Issue title' expect(page).to have_css 'h2', text: 'Issue title'
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment