Commit e6149561 authored by ddavison's avatar ddavison

Documentation for dynamic element validation

First iteration on the documentation for how
dynamic element validation works within the
GitLab QA framework and how to utilize it
parent e6a88b02
# 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.
...@@ -82,15 +82,17 @@ module Page ...@@ -82,15 +82,17 @@ module Page
end end
# ... # ...
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