]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: replace E2E test `moveClick` with `clickCheckbox`
authorPatrick Seidensal <pseidensal@suse.com>
Wed, 14 Aug 2019 09:59:45 +0000 (11:59 +0200)
committerPatrick Seidensal <pseidensal@suse.com>
Wed, 28 Aug 2019 07:38:48 +0000 (09:38 +0200)
Ceph Dashboard replaces the original checkbox with a fancy replacement
using the pseudo selector "::before" inside the <label> tag. When the
fancy replacement checkbox is clicked, it actually triggers a click on
the label of the checkbox. `clickCheckbox` does the same.

Removed `moveClick` as it was used to perform an action that the user
would not be able to perform, namely clicking on the checkbox instead of
the checkboxes' label. It was also used for cases where it was not
necessary to be used for, hence the replacement `clickCheckbox` has been
introduced. It checks if the argument passed to it is of type `checkbox`
or `label`. If it is of type `label`, the label will be clicked. If it
is of type `checkbox`, the corresponding `label` is determined and
clicked. This replaces the old implementation with a solution that has
an easy to understand purpose. It also prevents every false application.

This method is designed to be used on all checkboxes of Ceph Dashboard.

Fixes: https://tracker.ceph.com/issues/40693
Signed-off-by: Patrick Seidensal <pseidensal@suse.com>
src/pybind/mgr/dashboard/HACKING.rst
src/pybind/mgr/dashboard/frontend/e2e/page-helper.po.ts

index cc71345e4dd0ef6ab462d986ac9d6b73995331ac..c26b9522fe0dc32b27888d1f73471d064e3d382f 100644 (file)
@@ -136,8 +136,8 @@ There are a few ways how you can try to resolve this:
   again in order to reinstall them
 - Clear the cache of jest by running ``npx jest --clearCache``
 
-Running End-to-End Tests
-~~~~~~~~~~~~~~~~~~~~~~~~
+Running End-to-End (E2E) Tests
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 We use `Protractor <http://www.protractortest.org/>`__ to run our frontend E2E
 tests.
@@ -184,13 +184,29 @@ Note::
 Writing End-to-End Tests
 ~~~~~~~~~~~~~~~~~~~~~~~~
 
+To be used methods
+..................
+
+For clicking checkboxes, the ``clickCheckbox`` method is supposed to be used.
+Due an adaption of the ``<input type="checkbox">`` tag, the original checkbox
+is hidden and unclickable. Instead, a fancier replacement is shown. When the
+developer tries to use `ElementFinder::click()` on such a checkbox, it will
+raise an error. The ``clickCheckbox`` method prevents that by clicking the
+label of the checkbox, like a regular user would do.
+
 The PagerHelper class
 .....................
 
 The ``PageHelper`` class is supposed to be used for general purpose code that
-can be used on various pages or suites. Examples are
-``getTableCellByContent()``, ``getTabsCount()`` or ``checkCheckbox()``. Every
-method that could be useful on several pages belongs there. Also, methods
+can be used on various pages or suites.
+
+Examples are
+
+- ``getTableCellByContent()`` - returns a table cell by its content
+- ``getTabsCount()`` - returns the amount of tabs
+- ``clickCheckbox()`` - clicks a checkbox
+
+Every method that could be useful on several pages belongs there. Also, methods
 which enhance the derived classes of the PageHelper belong there. A good
 example for such a case is the ``restrictTo()`` decorator. It ensures that a
 method implemented in a subclass of PageHelper is called on the correct page.
index 2572fb323a05ceb24cc45f5b55f8c0a5a354a700..ed893bb1358e2611b16b388ea02dfaf4cbfcdb08 100644 (file)
@@ -79,14 +79,38 @@ export abstract class PageHelper {
    * Used for instances where a modal container would receive the click rather
    * than the desired element.
    *
-   * https://stackoverflow.com/questions/26211751/protractor-chrome-driver-element-is-not-clickable-at-point
+   * Our <input type="checkbox"> tag is not visible. Instead of the real
+   * checkbox, a replacement is shown which is supposed to have an adapted
+   * style. The replacement checkbox shown is part of the label and is rendered
+   * in the "::before" pseudo element of the label, hence the label is always
+   * clicked when the user clicks the replacement checkbox.
+   *
+   * This method finds corresponding label to the given checkbox and clicks it
+   * instead of the (fake) checkbox, like it is the case with real users.
+   *
+   * Alternatively, the checkbox' label can be passed.
+   *
+   * @param elem The checkbox or corresponding label
    */
-  moveClick(object) {
-    return browser
-      .actions()
-      .mouseMove(object)
-      .click()
-      .perform();
+  async clickCheckbox(elem: ElementFinder): Promise<void> {
+    const tagName = await elem.getTagName();
+    let label: ElementFinder = null; // Both types are clickable
+
+    if (tagName === 'input') {
+      if ((await elem.getAttribute('type')) === 'checkbox') {
+        label = elem.element(by.xpath('..')).$(`label[for="${await elem.getAttribute('id')}"]`);
+      } else {
+        return Promise.reject('element <input> must be of type checkbox');
+      }
+    } else if (tagName === 'label') {
+      label = elem;
+    } else {
+      return Promise.reject(
+        `element <${tagName}> is not of the correct type. You need to pass a checkbox or label`
+      );
+    }
+
+    return label.click();
   }
 
   /**