tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

browser_markup_accessibility_navigation.js (7892B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 /* import-globals-from helper_markup_accessibility_navigation.js */
      5 
      6 "use strict";
      7 
      8 // Test keyboard navigation accessibility of inspector's markup view.
      9 
     10 loadHelperScript("helper_markup_accessibility_navigation.js");
     11 
     12 /**
     13 * Test data has the format of:
     14 * {
     15 *   desc              {String}   description for better logging
     16 *   key               {String}   key event's key
     17 *   options           {?Object}  optional event data such as shiftKey, etc
     18 *   focused           {String}   path to expected focused element relative to
     19 *                                its container
     20 *   activedescendant  {String}   path to expected aria-activedescendant element
     21 *                                relative to its container
     22 *   waitFor           {String}   optional event to wait for if keyboard actions
     23 *                                result in asynchronous updates
     24 * }
     25 */
     26 const TESTS = [
     27  {
     28    desc: "Collapse body container",
     29    focused: "root.elt",
     30    activedescendant: "body.tagLine",
     31    key: "VK_LEFT",
     32    options: {},
     33    waitFor: "collapsed",
     34  },
     35  {
     36    desc: "Expand body container",
     37    focused: "root.elt",
     38    activedescendant: "body.tagLine",
     39    key: "VK_RIGHT",
     40    options: {},
     41    waitFor: "expanded",
     42  },
     43  {
     44    desc: "Select header container",
     45    focused: "root.elt",
     46    activedescendant: "header.tagLine",
     47    key: "VK_DOWN",
     48    options: {},
     49    waitFor: "inspector-updated",
     50  },
     51  {
     52    desc: "Expand header container",
     53    focused: "root.elt",
     54    activedescendant: "header.tagLine",
     55    key: "VK_RIGHT",
     56    options: {},
     57    waitFor: "expanded",
     58  },
     59  {
     60    desc: "Select text container",
     61    focused: "root.elt",
     62    activedescendant: "container-0.tagLine",
     63    key: "VK_DOWN",
     64    options: {},
     65    waitFor: "inspector-updated",
     66  },
     67  {
     68    desc: "Select header container again",
     69    focused: "root.elt",
     70    activedescendant: "header.tagLine",
     71    key: "VK_UP",
     72    options: {},
     73    waitFor: "inspector-updated",
     74  },
     75  {
     76    desc: "Collapse header container",
     77    focused: "root.elt",
     78    activedescendant: "header.tagLine",
     79    key: "VK_LEFT",
     80    options: {},
     81    waitFor: "collapsed",
     82  },
     83  {
     84    desc: "Focus on header container tag",
     85    focused: "header.focusableElms.0",
     86    activedescendant: "header.tagLine",
     87    key: "VK_RETURN",
     88    options: {},
     89  },
     90  {
     91    desc: "Remove focus from header container tag",
     92    focused: "root.elt",
     93    activedescendant: "header.tagLine",
     94    key: "VK_ESCAPE",
     95    options: {},
     96  },
     97  {
     98    desc: "Focus on header container tag again",
     99    focused: "header.focusableElms.0",
    100    activedescendant: "header.tagLine",
    101    key: "VK_SPACE",
    102    options: {},
    103  },
    104  {
    105    desc: "Focus on header id attribute",
    106    focused: "header.focusableElms.1",
    107    activedescendant: "header.tagLine",
    108    key: "VK_TAB",
    109    options: {},
    110  },
    111  {
    112    desc: "Focus on header class attribute",
    113    focused: "header.focusableElms.2",
    114    activedescendant: "header.tagLine",
    115    key: "VK_TAB",
    116    options: {},
    117  },
    118  {
    119    desc: "Focus on header new attribute",
    120    focused: "header.focusableElms.3",
    121    activedescendant: "header.tagLine",
    122    key: "VK_TAB",
    123    options: {},
    124  },
    125  {
    126    desc: "Circle back and focus on header tag again",
    127    focused: "header.focusableElms.0",
    128    activedescendant: "header.tagLine",
    129    key: "VK_TAB",
    130    options: {},
    131  },
    132  {
    133    desc: "Circle back and focus on header new attribute again",
    134    focused: "header.focusableElms.3",
    135    activedescendant: "header.tagLine",
    136    key: "VK_TAB",
    137    options: { shiftKey: true },
    138  },
    139  {
    140    desc: "Tab back and focus on header class attribute",
    141    focused: "header.focusableElms.2",
    142    activedescendant: "header.tagLine",
    143    key: "VK_TAB",
    144    options: { shiftKey: true },
    145  },
    146  {
    147    desc: "Tab back and focus on header id attribute",
    148    focused: "header.focusableElms.1",
    149    activedescendant: "header.tagLine",
    150    key: "VK_TAB",
    151    options: { shiftKey: true },
    152  },
    153  {
    154    desc: "Tab back and focus on header tag",
    155    focused: "header.focusableElms.0",
    156    activedescendant: "header.tagLine",
    157    key: "VK_TAB",
    158    options: { shiftKey: true },
    159  },
    160  {
    161    desc: "Expand header container, ensure that focus is still on header tag",
    162    focused: "header.focusableElms.0",
    163    activedescendant: "header.tagLine",
    164    key: "VK_RIGHT",
    165    options: {},
    166    waitFor: "expanded",
    167  },
    168  {
    169    desc: "Activate header tag editor",
    170    focused: "header.editor.tag.inplaceEditor.input",
    171    activedescendant: "header.tagLine",
    172    key: "VK_RETURN",
    173    options: {},
    174  },
    175  {
    176    desc: "Activate header id attribute editor",
    177    focused: "header.editor.attrList.children.0.children.1.inplaceEditor.input",
    178    activedescendant: "header.tagLine",
    179    key: "VK_TAB",
    180    options: {},
    181  },
    182  {
    183    desc: "Deselect text in header id attribute editor",
    184    focused: "header.editor.attrList.children.0.children.1.inplaceEditor.input",
    185    activedescendant: "header.tagLine",
    186    key: "VK_TAB",
    187    options: {},
    188  },
    189  {
    190    desc: "Activate header class attribute editor",
    191    focused: "header.editor.attrList.children.1.children.1.inplaceEditor.input",
    192    activedescendant: "header.tagLine",
    193    key: "VK_TAB",
    194    options: {},
    195  },
    196  {
    197    desc: "Deselect text in header class attribute editor",
    198    focused: "header.editor.attrList.children.1.children.1.inplaceEditor.input",
    199    activedescendant: "header.tagLine",
    200    key: "VK_TAB",
    201    options: {},
    202  },
    203  {
    204    desc: "Activate header new attribute editor",
    205    focused: "header.editor.newAttr.inplaceEditor.input",
    206    activedescendant: "header.tagLine",
    207    key: "VK_TAB",
    208    options: {},
    209  },
    210  {
    211    desc: "Circle back and activate header tag editor again",
    212    focused: "header.editor.tag.inplaceEditor.input",
    213    activedescendant: "header.tagLine",
    214    key: "VK_TAB",
    215    options: {},
    216  },
    217  {
    218    desc: "Circle back and activate header new attribute editor again",
    219    focused: "header.editor.newAttr.inplaceEditor.input",
    220    activedescendant: "header.tagLine",
    221    key: "VK_TAB",
    222    options: { shiftKey: true },
    223  },
    224  {
    225    desc: "Exit edit mode and keep focus on header new attribute",
    226    focused: "header.focusableElms.3",
    227    activedescendant: "header.tagLine",
    228    key: "VK_ESCAPE",
    229    options: {},
    230  },
    231  {
    232    desc: "Move the selection to body and reset focus to container tree",
    233    focused: "docBody",
    234    activedescendant: "body.tagLine",
    235    key: "VK_UP",
    236    options: {},
    237    waitFor: "inspector-updated",
    238  },
    239 ];
    240 
    241 let containerID = 0;
    242 let elms = {};
    243 
    244 add_task(async function () {
    245  const { inspector } = await openInspectorForURL(`data:text/html;charset=utf-8,
    246    <h1 id="some-id" class="some-class">foo<span>Child span<span></h1>`);
    247 
    248  // Record containers that are created after inspector is initialized to be
    249  // useful in testing.
    250  inspector.on("container-created", memorizeContainer);
    251  registerCleanupFunction(() => {
    252    inspector.off("container-created", memorizeContainer);
    253  });
    254 
    255  elms.docBody = inspector.markup.doc.body;
    256  elms.root = inspector.markup.getContainer(inspector.markup._rootNode);
    257  elms.header = await getContainerForSelector("h1", inspector);
    258  elms.body = await getContainerForSelector("body", inspector);
    259 
    260  // Initial focus is on root element and active descendant should be set on
    261  // body tag line.
    262  testNavigationState(inspector, elms, elms.docBody, elms.body.tagLine);
    263 
    264  // Focus on the tree element.
    265  elms.root.elt.focus();
    266 
    267  for (const testData of TESTS) {
    268    await runAccessibilityNavigationTest(inspector, elms, testData);
    269  }
    270 
    271  elms = null;
    272 });
    273 
    274 // Record all containers that are created dynamically into elms object.
    275 function memorizeContainer(container) {
    276  elms[`container-${containerID++}`] = container;
    277 }