From 9dc93a4519d9d5d7be48ff274127136236a3adb3 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Tue, 20 Apr 2021 23:50:22 +0000 Subject: Add latest changes from gitlab-org/gitlab@13-11-stable-ee --- doc/development/testing_guide/best_practices.md | 134 +++++++++++++++++++++++- 1 file changed, 131 insertions(+), 3 deletions(-) (limited to 'doc/development/testing_guide/best_practices.md') diff --git a/doc/development/testing_guide/best_practices.md b/doc/development/testing_guide/best_practices.md index ee8401e08d4..828e9925d46 100644 --- a/doc/development/testing_guide/best_practices.md +++ b/doc/development/testing_guide/best_practices.md @@ -86,7 +86,7 @@ a parent context. Examples of these are: - `:clean_gitlab_redis_cache` which provides a clean Redis cache to the examples. - `:request_store` which provides a request store to the examples. -Obviously we should reduce test dependencies, and avoiding +We should reduce test dependencies, and avoiding capabilities also reduces the amount of set-up needed. `:js` is particularly important to avoid. This must only be used if the feature @@ -350,12 +350,140 @@ writing one](testing_levels.md#consider-not-writing-a-system-test)! - It's ok to look for DOM elements, but don't abuse it, because it makes the tests more brittle -#### Debugging Capybara +#### UI testing -Sometimes you may need to debug Capybara tests by observing browser behavior. +When testing the UI, write tests that simulate what a user sees and how they interact with the UI. +This means preferring Capybara's semantic methods and avoiding querying by IDs, classes, or attributes. + +The benefits of testing in this way are that: + +- It ensures all interactive elements have an [accessible name](../fe_guide/accessibility.md#provide-accessible-names-for-screen-readers). +- It is more readable, as it uses more natural language. +- It is less brittle, as it avoids querying by IDs, classes, and attributes, which are not visible to the user. + +We strongly recommend that you query by the element's text label instead of by ID, class name, or `data-testid`. + +If needed, you can scope interactions within a specific area of the page by using `within`. +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. + +##### Actions + +Where possible, use more specific [actions](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Actions), such as the ones below. + +```ruby +# good +click_button 'Submit review' + +click_link 'UI testing docs' + +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 + +check 'Checkbox label' +uncheck 'Checkbox label' + +choose 'Radio input label' + +attach_file('Attach a file', '/path/to/file.png') + +# bad - interactive elements must have accessible names, so +# we should be able to use one of the specific actions above +find('.group-name', text: group.name).click +find('.js-show-diff-settings').click +find('[data-testid="submit-review"]').click +find('input[type="checkbox"]').click +find('.search').native.send_keys('gitlab') +``` + +##### Finders + +Where possible, use more specific [finders](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Finders), such as the ones below. + +```ruby +# good +find_button 'Submit review' +find_button 'Submit review', disabled: true + +find_link 'UI testing docs' +find_link 'UI testing docs', href: docs_url + +find_field 'Search projects' +find_field 'Search projects', with: 'gitlab' # find the input field with text +find_field 'Search projects', disabled: true +find_field 'Checkbox label', checked: true +find_field 'Checkbox label', unchecked: true + +# acceptable when finding a element that is not a button, link, or field +find('[data-testid="element"]') +``` + +##### Matchers + +Where possible, use more specific [matchers](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara/RSpecMatchers), such as the ones below. + +```ruby +# good +expect(page).to have_button 'Submit review' +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_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_field 'Search projects' +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_checked_field 'Checkbox label' +expect(page).to have_unchecked_field 'Radio input label' + +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', 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_text 'Some paragraph text.' +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_title 'Not Found' + +# acceptable when a more specific matcher above is not possible +expect(page).to have_css 'h2', text: 'Issue title' +expect(page).to have_css 'p', text: 'Issue description', exact: true +expect(page).to have_css '[data-testid="weight"]', text: 2 +expect(page).to have_css '.atwho-view ul', visible: true +``` + +##### Other useful methods + +After you retrieve an element using a [finder method](#finders), you can invoke a number of +[element methods](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Element) +on it, such as `hover`. + +Capybara tests also have a number of [session methods](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Session) available, such as `accept_confirm`. + +Some other useful methods are shown below: + +```ruby +refresh # refresh the page + +send_keys([:shift, 'i']) # press Shift+I keys to go to the Issues dashboard page + +current_window.resize_to(1000, 1000) # resize the window + +scroll_to(find_field('Comment')) # scroll to an element +``` + +You can also find a number of GitLab custom helpers in the `spec/support/helpers/` directory. #### Live debug +Sometimes you may need to debug Capybara tests by observing browser behavior. + You can pause Capybara and view the website on the browser by using the `live_debug` method in your spec. The current page is automatically opened in your default browser. -- cgit v1.2.1