From e61495610da91411fec4a8895e22a6d7c490dcc6 Mon Sep 17 00:00:00 2001 From: ddavison Date: Tue, 4 Jun 2019 16:42:37 -0700 Subject: 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 --- .../end_to_end/dynamic_element_validation.md | 113 +++++++++++++++++++++ .../testing_guide/end_to_end/page_objects.md | 39 ++++++- 2 files changed, 149 insertions(+), 3 deletions(-) create mode 100644 doc/development/testing_guide/end_to_end/dynamic_element_validation.md diff --git a/doc/development/testing_guide/end_to_end/dynamic_element_validation.md b/doc/development/testing_guide/end_to_end/dynamic_element_validation.md new file mode 100644 index 00000000000..f7b3ca8bc89 --- /dev/null +++ b/doc/development/testing_guide/end_to_end/dynamic_element_validation.md @@ -0,0 +1,113 @@ +# 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. diff --git a/doc/development/testing_guide/end_to_end/page_objects.md b/doc/development/testing_guide/end_to_end/page_objects.md index d0de33892c4..73e1fd862c1 100644 --- a/doc/development/testing_guide/end_to_end/page_objects.md +++ b/doc/development/testing_guide/end_to_end/page_objects.md @@ -82,15 +82,17 @@ module Page end # ... + end end end ``` -The `view` DSL method declares the filename of the view where an -`element` is implemented. +### Defining Elements + +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 -`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 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 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 During development, you can run the `qa:selectors` test by running -- cgit v1.2.1