accessible/tests/mochitest/states.js

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

     1 ////////////////////////////////////////////////////////////////////////////////
     2 // Helper functions for accessible states testing.
     3 //
     4 // requires:
     5 //   common.js
     6 //   role.js
     7 //
     8 ////////////////////////////////////////////////////////////////////////////////
    10 ////////////////////////////////////////////////////////////////////////////////
    11 // State constants
    13 // const STATE_BUSY is defined in common.js
    14 const STATE_CHECKED = nsIAccessibleStates.STATE_CHECKED;
    15 const STATE_CHECKABLE = nsIAccessibleStates.STATE_CHECKABLE;
    16 const STATE_COLLAPSED = nsIAccessibleStates.STATE_COLLAPSED;
    17 const STATE_DEFAULT = nsIAccessibleStates.STATE_DEFAULT;
    18 const STATE_EXPANDED = nsIAccessibleStates.STATE_EXPANDED;
    19 const STATE_EXTSELECTABLE = nsIAccessibleStates.STATE_EXTSELECTABLE;
    20 const STATE_FLOATING = nsIAccessibleStates.STATE_FLOATING;
    21 const STATE_FOCUSABLE = nsIAccessibleStates.STATE_FOCUSABLE;
    22 const STATE_FOCUSED = nsIAccessibleStates.STATE_FOCUSED;
    23 const STATE_HASPOPUP = nsIAccessibleStates.STATE_HASPOPUP;
    24 const STATE_INVALID = nsIAccessibleStates.STATE_INVALID;
    25 const STATE_INVISIBLE = nsIAccessibleStates.STATE_INVISIBLE;
    26 const STATE_LINKED = nsIAccessibleStates.STATE_LINKED;
    27 const STATE_MIXED = nsIAccessibleStates.STATE_MIXED;
    28 const STATE_MULTISELECTABLE = nsIAccessibleStates.STATE_MULTISELECTABLE;
    29 const STATE_OFFSCREEN = nsIAccessibleStates.STATE_OFFSCREEN;
    30 const STATE_PRESSED = nsIAccessibleStates.STATE_PRESSED;
    31 const STATE_PROTECTED = nsIAccessibleStates.STATE_PROTECTED;
    32 const STATE_READONLY = nsIAccessibleStates.STATE_READONLY;
    33 const STATE_REQUIRED = nsIAccessibleStates.STATE_REQUIRED;
    34 const STATE_SELECTABLE = nsIAccessibleStates.STATE_SELECTABLE;
    35 const STATE_SELECTED = nsIAccessibleStates.STATE_SELECTED;
    36 const STATE_TRAVERSED = nsIAccessibleStates.STATE_TRAVERSED;
    37 const STATE_UNAVAILABLE = nsIAccessibleStates.STATE_UNAVAILABLE;
    39 const EXT_STATE_ACTIVE = nsIAccessibleStates.EXT_STATE_ACTIVE;
    40 const EXT_STATE_DEFUNCT = nsIAccessibleStates.EXT_STATE_DEFUNCT;
    41 const EXT_STATE_EDITABLE = nsIAccessibleStates.EXT_STATE_EDITABLE;
    42 const EXT_STATE_ENABLED = nsIAccessibleStates.EXT_STATE_ENABLED;
    43 const EXT_STATE_EXPANDABLE = nsIAccessibleStates.EXT_STATE_EXPANDABLE;
    44 const EXT_STATE_HORIZONTAL = nsIAccessibleStates.EXT_STATE_HORIZONTAL;
    45 const EXT_STATE_MULTI_LINE = nsIAccessibleStates.EXT_STATE_MULTI_LINE;
    46 const EXT_STATE_PINNED = nsIAccessibleStates.EXT_STATE_PINNED;
    47 const EXT_STATE_SENSITIVE = nsIAccessibleStates.EXT_STATE_SENSITIVE;
    48 const EXT_STATE_SINGLE_LINE = nsIAccessibleStates.EXT_STATE_SINGLE_LINE;
    49 const EXT_STATE_STALE = nsIAccessibleStates.EXT_STATE_STALE;
    50 const EXT_STATE_SUPPORTS_AUTOCOMPLETION =
    51   nsIAccessibleStates.EXT_STATE_SUPPORTS_AUTOCOMPLETION;
    52 const EXT_STATE_VERTICAL = nsIAccessibleStates.EXT_STATE_VERTICAL;
    54 const kOrdinalState = 0;
    55 const kExtraState = 1;
    57 ////////////////////////////////////////////////////////////////////////////////
    58 // Test functions
    60 /**
    61  * Tests the states and extra states of the given accessible.
    62  * Also tests for unwanted states and extra states.
    63  * In addition, the function performs a few plausibility checks derived from the
    64  * sstates and extra states passed in.
    65  *
    66  * @param aAccOrElmOrID      The accessible, DOM element or ID to be tested.
    67  * @param aState             The state bits that are wanted.
    68  * @param aExtraState        The extra state bits that are wanted.
    69  * @param aAbsentState       State bits that are not wanted.
    70  * @param aAbsentExtraState  Extra state bits that are not wanted.
    71  * @param aTestName          The test name.
    72  */
    73 function testStates(aAccOrElmOrID, aState, aExtraState, aAbsentState,
    74                     aAbsentExtraState, aTestName)
    75 {
    76   var [state, extraState] = getStates(aAccOrElmOrID);
    77   var role = getRole(aAccOrElmOrID);
    78   var id = prettyName(aAccOrElmOrID) + (aTestName ? " [" + aTestName + "]": "");
    80   // Primary test.
    81   if (aState) {
    82     isState(state & aState, aState, false,
    83             "wrong state bits for " + id + "!");
    84   }
    86   if (aExtraState)
    87     isState(extraState & aExtraState, aExtraState, true,
    88             "wrong extra state bits for " + id + "!");
    90   if (aAbsentState)
    91     isState(state & aAbsentState, 0, false,
    92             "state bits should not be present in ID " + id + "!");
    94   if (aAbsentExtraState)
    95     isState(extraState & aAbsentExtraState, 0, true,
    96             "extraState bits should not be present in ID " + id + "!");
    98   // Additional test.
   100   // focused/focusable
   101   if (state & STATE_FOCUSED)
   102     isState(state & STATE_FOCUSABLE, STATE_FOCUSABLE, false,
   103             "Focussed " + id + " must be focusable!");
   105   if (aAbsentState && (aAbsentState & STATE_FOCUSABLE)) {
   106     isState(state & STATE_FOCUSED, 0, false,
   107               "Not focusable " + id + " must be not focused!");
   108   }
   110   // multiline/singleline
   111   if (extraState & EXT_STATE_MULTI_LINE)
   112     isState(extraState & EXT_STATE_SINGLE_LINE, 0, true,
   113             "Multiline " + id + " cannot be singleline!");
   115   if (extraState & EXT_STATE_SINGLE_LINE)
   116     isState(extraState & EXT_STATE_MULTI_LINE, 0, true,
   117             "Singleline " + id + " cannot be multiline!");
   119   // expanded/collapsed/expandable
   120   if (state & STATE_COLLAPSED || state & STATE_EXPANDED)
   121     isState(extraState & EXT_STATE_EXPANDABLE, EXT_STATE_EXPANDABLE, true,
   122             "Collapsed or expanded " + id + " must be expandable!");
   124   if (state & STATE_COLLAPSED)
   125     isState(state & STATE_EXPANDED, 0, false,
   126             "Collapsed " + id + " cannot be expanded!");
   128   if (state & STATE_EXPANDED)
   129     isState(state & STATE_COLLAPSED, 0, false,
   130             "Expanded " + id + " cannot be collapsed!");
   132   if (aAbsentState && (extraState & EXT_STATE_EXPANDABLE)) {
   133     if (aAbsentState & STATE_EXPANDED) {
   134       isState(state & STATE_COLLAPSED, STATE_COLLAPSED, false,
   135               "Not expanded " + id + " must be collapsed!");
   136     } else if (aAbsentState & STATE_COLLAPSED) {
   137       isState(state & STATE_EXPANDED, STATE_EXPANDED, false,
   138               "Not collapsed " + id + " must be expanded!");
   139     }
   140   }
   142   // checked/mixed/checkable
   143   if (state & STATE_CHECKED || state & STATE_MIXED &&
   144       role != ROLE_TOGGLE_BUTTON && role != ROLE_PROGRESSBAR)
   145     isState(state & STATE_CHECKABLE, STATE_CHECKABLE, false,
   146             "Checked or mixed element must be checkable!");
   148   if (state & STATE_CHECKED)
   149     isState(state & STATE_MIXED, 0, false,
   150             "Checked element cannot be state mixed!");
   152   if (state & STATE_MIXED)
   153     isState(state & STATE_CHECKED, 0, false,
   154             "Mixed element cannot be state checked!");
   156   // selected/selectable
   157   if (state & STATE_SELECTED) {
   158     isState(state & STATE_SELECTABLE, STATE_SELECTABLE, false,
   159             "Selected element must be selectable!");
   160   }
   161 }
   163 /**
   164  * Tests an acessible and its sub tree for the passed in state bits.
   165  * Used to make sure that states are propagated to descendants, for example the
   166  * STATE_UNAVAILABLE from a container to its children.
   167  *
   168  * @param aAccOrElmOrID  The accessible, DOM element or ID to be tested.
   169  * @param aState         The state bits that are wanted.
   170  * @param aExtraState    The extra state bits that are wanted.
   171  * @param aAbsentState   State bits that are not wanted.
   172  */
   173 function testStatesInSubtree(aAccOrElmOrID, aState, aExtraState, aAbsentState)
   174 {
   175   // test accessible and its subtree for propagated states.
   176   var acc = getAccessible(aAccOrElmOrID);
   177   if (!acc)
   178     return;
   180   if (getRole(acc) != ROLE_TEXT_LEAF)
   181     // Right now, text leafs don't get tested because the states are not being
   182     // propagated.
   183     testStates(acc, aState, aExtraState, aAbsentState);
   185   // Iterate over its children to see if the state got propagated.
   186   var children = null;
   187   try {
   188     children = acc.children;
   189   } catch(e) {}
   190   ok(children, "Could not get children for " + aAccOrElmOrID +"!");
   192   if (children) {
   193     for (var i = 0; i < children.length; i++) {
   194       var childAcc = children.queryElementAt(i, nsIAccessible);
   195       testStatesInSubtree(childAcc, aState, aExtraState, aAbsentState);
   196     }
   197   }
   198 }
   200 function getStringStates(aAccOrElmOrID)
   201 {
   202   var [state, extraState] = getStates(aAccOrElmOrID);
   203   return statesToString(state, extraState);
   204 }
   206 function getStates(aAccOrElmOrID)
   207 {
   208   var acc = getAccessible(aAccOrElmOrID);
   209   if (!acc)
   210     return [0, 0];
   212   var state = {}, extraState = {};
   213   acc.getState(state, extraState);
   215   return [state.value, extraState.value];
   216 }
   218 /**
   219  * Return true if the accessible has given states.
   220  */
   221 function hasState(aAccOrElmOrID, aState, aExtraState)
   222 {
   223   var [state, exstate] = getStates(aAccOrElmOrID);
   224   return (aState ? state & aState : true) &&
   225     (aExtraState ? exstate & aExtraState : true);
   226 }
   228 ////////////////////////////////////////////////////////////////////////////////
   229 // Private implementation details
   231 /**
   232  * Analogy of SimpleTest.is function used to compare states.
   233  */
   234 function isState(aState1, aState2, aIsExtraStates, aMsg)
   235 {
   236   if (aState1 == aState2) {
   237     ok(true, aMsg);
   238     return;
   239   }
   241   var got = "0";
   242   if (aState1) {
   243     got = statesToString(aIsExtraStates ? 0 : aState1,
   244                          aIsExtraStates ? aState1 : 0);
   245   }
   247   var expected = "0";
   248   if (aState2) {
   249     expected = statesToString(aIsExtraStates ? 0 : aState2,
   250                               aIsExtraStates ? aState2 : 0);
   251   }
   253   ok(false, aMsg + "got '" + got + "', expected '" + expected + "'");
   254 }

mercurial