debian-mirror-gitlab/doc/development/testing_guide/end_to_end/style_guide.md

164 lines
4.8 KiB
Markdown
Raw Normal View History

2019-09-04 21:01:54 +05:30
# Style guide for writing end-to-end tests
This document describes the conventions used at GitLab for writing End-to-end (E2E) tests using the GitLab QA project.
## `click_` versus `go_to_`
### When to use `click_`?
When clicking in a single link to navigate, use `click_`.
E.g.:
```ruby
def click_ci_cd_pipelines
within_sidebar do
click_element :link_pipelines
end
end
```
From a testing perspective, if we want to check that clicking a link, or a button (a single interaction) is working as intended, we would want the test to read as:
- Click a certain element
- Verify the action took place
### When to use `go_to_`?
When interacting with multiple elements to go to a page, use `go_to_`.
E.g.:
```ruby
def go_to_operations_environments
hover_operations do
within_submenu do
click_element(:operations_environments_link)
end
end
end
```
`go_to_` fits the definition of interacting with multiple elements very well given it's more of a meta-navigation action that includes multiple interactions.
Notice that in the above example, before clicking the `:operations_environments_link`, another element is hovered over.
> We can create these methods as helpers to abstract multi-step navigation.
2019-10-12 21:52:04 +05:30
## Element naming convention
2019-09-04 21:01:54 +05:30
When adding new elements to a page, it's important that we have a uniform element naming convention.
2020-06-23 00:09:42 +05:30
We follow a simple formula roughly based on Hungarian notation.
2019-09-04 21:01:54 +05:30
*Formula*: `element :<descriptor>_<type>`
- `descriptor`: The natural-language description of what the element is. On the login page, this could be `username`, or `password`.
2020-03-13 15:44:24 +05:30
- `type`: A generic control on the page that can be seen by a user.
2019-09-04 21:01:54 +05:30
- `_button`
- `_checkbox`
2020-03-13 15:44:24 +05:30
- `_container`: an element that includes other elements, but doesn't present visible content itself. E.g., an element that has a third-party editor inside it, but which isn't the editor itself and so doesn't include the editor's content.
- `_content`: any element that contains text, images, or any other content displayed to the user.
- `_dropdown`
- `_field`: a text input element.
- `_link`
- `_modal`: a popup modal dialog, e.g., a confirmation prompt.
- `_placeholder`: a temporary element that appears while content is loading. For example, the elements that are displayed instead of discussions while the discussions are being fetched.
2019-09-04 21:01:54 +05:30
- `_radio`
2020-03-13 15:44:24 +05:30
- `_tab`
2020-05-24 23:13:21 +05:30
- `_menu_item`
2019-09-30 21:07:59 +05:30
2020-03-13 15:44:24 +05:30
*Note: If none of the listed types are suitable, please open a merge request to add an appropriate type to the list.*
2019-09-30 21:07:59 +05:30
2019-10-12 21:52:04 +05:30
### Examples
2019-09-04 21:01:54 +05:30
**Good**
```ruby
view '...' do
2019-09-30 21:07:59 +05:30
element :edit_button
2019-09-04 21:01:54 +05:30
element :notes_tab
element :squash_checkbox
element :username_field
element :issue_title_content
end
```
**Bad**
```ruby
2019-09-30 21:07:59 +05:30
view '...' do
2019-09-04 21:01:54 +05:30
# `_confirmation` should be `_field`. what sort of confirmation? a checkbox confirmation? no real way to disambiguate.
# an appropriate replacement would be `element :password_confirmation_field`
element :password_confirmation
2019-09-30 21:07:59 +05:30
# `clone_options` is too vague. If it's a dropdown menu, it should be `clone_dropdown`.
2019-09-04 21:01:54 +05:30
# If it's a checkbox, it should be `clone_checkbox`
element :clone_options
2019-09-30 21:07:59 +05:30
2019-09-04 21:01:54 +05:30
# how is this url being displayed? is it a textbox? a simple span?
2019-09-30 21:07:59 +05:30
# If it is content on the page, it should be `ssh_clone_url_content`
2019-09-04 21:01:54 +05:30
element :ssh_clone_url
end
```
2019-10-12 21:52:04 +05:30
## Block argument naming
2019-12-04 20:38:33 +05:30
To have a standard on what we call pages and resources when using the `.perform` method,
we use the name of the page object in [snake_case](https://en.wikipedia.org/wiki/Snake_case)
(all lowercase, with words separated by an underscore). See good and bad examples below.
While we prefer to follow the standard in most cases, it is also acceptable to
2020-06-23 00:09:42 +05:30
use common abbreviations (e.g., `mr`) or other alternatives, as long as
2019-12-04 20:38:33 +05:30
the name is not ambiguous. This can include appending `_page` if it helps to
avoid confusion or make the code more readable. For example, if a page object is
named `New`, it could be confusing to name the block argument `new` because that
is used to instantiate objects, so `new_page` would be acceptable.
We chose not to simply use `page` because that would shadow the
Capybara DSL, potentially leading to confusion and bugs.
2019-10-12 21:52:04 +05:30
### Examples
**Good**
```ruby
2020-06-23 00:09:42 +05:30
Page::Project::Members.perform do |members|
2019-10-12 21:52:04 +05:30
members.do_something
end
```
```ruby
Resource::MergeRequest.fabricate! do |merge_request|
merge_request.do_something_else
end
```
2019-12-04 20:38:33 +05:30
```ruby
Resource::MergeRequest.fabricate! do |mr|
mr.do_something_else
end
```
2019-10-12 21:52:04 +05:30
```ruby
2019-12-04 20:38:33 +05:30
Page::Project::New.peform do |new_page|
new_page.do_something
end
```
2019-10-12 21:52:04 +05:30
2019-12-04 20:38:33 +05:30
**Bad**
```ruby
2020-06-23 00:09:42 +05:30
Page::Project::Members.perform do |project_settings_members_page|
2019-10-12 21:52:04 +05:30
project_settings_members_page.do_something
end
```
```ruby
2019-12-04 20:38:33 +05:30
Page::Project::New.peform do |page|
page.do_something
2019-10-12 21:52:04 +05:30
end
```
2019-12-04 20:38:33 +05:30
> Besides the advantage of having a standard in place, by following this standard we also write shorter lines of code.