Commit 68a1ba6a authored by Dan Davison's avatar Dan Davison

Merge branch 'docs-qa-dynamic-element-validation' into 'master'

Documentation for dynamic element validation

See merge request gitlab-org/gitlab-ce!29169
parents 2007ee31 e6149561
# Dynamic Element Validation
We devised a solution to solve common test automation problems such as the dreaded `NoSuchElementException`.
Other problems that dynamic element validations solve are...
- When we perform an action with the mouse, we expect something to occur.
- When our test is navigating to (or from) a page, we ensure that we are on the page we expect before
test continuation.
## How it works
We interpret user actions on the page to have some sort of effect. These actions are
- [Navigation](#navigation)
- [Clicks](#clicks)
### Navigation
When a page is navigated to, there are elements that will always appear on the page unconditionally.
Dynamic element validation is instituted when using
```ruby
Runtime::Browser.visit(:gitlab, Some::Page)
```
### Clicks
When we perform a click within our tests, we expect something to occur. That something could be a component to now
appear on the webpage, or the test to navigate away from the page entirely.
Dynamic element validation is instituted when using
```ruby
click_element :my_element, Some::Page
```
### Required Elements
#### Definition
First it is important to define what a "required element" is.
Simply put, a required element is a visible HTML element that appears on a UI component without any user input.
"Visible" can be defined as
- Not having any CSS preventing its display. E.g.: `display: none` or `width: 0px; height: 0px;`
- Being able to be interacted with by the user
"UI component" can be defined as
- Anything the user sees
- A button, a text field
- A layer that sits atop the page
#### Application
Requiring elements is very easy. By adding `required: true` as a parameter to an `element`, you've now made it
a requirement that the element appear on the page upon navigation.
## Examples
Given ...
```ruby
class MyPage < Page::Base
view 'app/views/view.html.haml' do
element :my_element, required: true
element :another_element, required: true
element :conditional_element
end
def open_layer
click_element :my_element, Layer::MyLayer
end
end
class Layer < Page::Component
view 'app/views/mylayer/layer.html.haml' do
element :message_content, required: true
end
end
```
### Navigating
Given the [source](#examples) ...
```ruby
Runtime::Browser.visit(:gitlab, Page::MyPage)
execute_stuff
```
will invoke GitLab QA to scan `MyPage` for `my_element` and `another_element` to be on the page before continuing to
`execute_stuff`
### Clicking
Given the [source](#examples) ...
```ruby
def open_layer
click_element :my_element, Layer::MyLayer
end
```
will invoke GitLab QA to ensure that `message_content` appears on
the Layer upon clicking `my_element`.
This will imply that the Layer is indeed rendered before we continue our test.
...@@ -83,14 +83,16 @@ module Page ...@@ -83,14 +83,16 @@ module Page
# ... # ...
end end
end
end end
``` ```
The `view` DSL method declares the filename of the view where an ### Defining Elements
`element` is implemented.
The `view` DSL method will correspond to the rails View, partial, or vue component that renders the elements.
The `element` DSL method in turn declares an element for which a corresponding The `element` DSL method in turn declares an element for which a corresponding
`qa-element-name-dasherized` CSS class need to be added to the view file. `qa-element-name-dasherized` CSS class will need to be added to the view file.
You can also define a value (String or Regexp) to match to the actual view You can also define a value (String or Regexp) to match to the actual view
code but **this is deprecated** in favor of the above method for two reasons: code but **this is deprecated** in favor of the above method for two reasons:
...@@ -115,6 +117,37 @@ view 'app/views/my/view.html.haml' do ...@@ -115,6 +117,37 @@ view 'app/views/my/view.html.haml' do
end end
``` ```
### Adding Elements to a View
Given the following elements...
```ruby
view 'app/views/my/view.html.haml' do
element :login_field
element :password_field
element :sign_in_button
end
```
To add these elements to the view, you must change the rails View, partial, or vue component by adding a `qa-element-descriptor` class
for each element defined.
In our case, `qa-login-field`, `qa-password-field` and `qa-sign-in-button`
**app/views/my/view.html.haml**
```haml
= f.text_field :login, class: "form-control top qa-login-field", autofocus: "autofocus", autocapitalize: "off", autocorrect: "off", required: true, title: "This field is required."
= f.password_field :password, class: "form-control bottom qa-password-field", required: true, title: "This field is required."
= f.submit "Sign in", class: "btn btn-success qa-sign-in-button"
```
Things to note:
- The CSS class must be `kebab-cased` (separated with hyphens "`-`")
- If the element appears on the page unconditionally, add `required: true` to the element. See
[Dynamic element validation](dynamic_element_validation.md)
## Running the test locally ## Running the test locally
During development, you can run the `qa:selectors` test by running During development, you can run the `qa:selectors` test by running
......
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