helper_markup_accessibility_navigation.js (3292B)
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 /* eslint no-unused-vars: [2, {"vars": "local"}] */ 5 /* import-globals-from head.js */ 6 "use strict"; 7 8 /** 9 * Execute a keyboard event and check that the state is as expected (focused element, aria 10 * attribute etc...). 11 * 12 * @param {InspectorPanel} inspector 13 * Current instance of the inspector being tested. 14 * @param {object} elms 15 * Map of elements that will be used to retrieve live references to children 16 * elements 17 * @param {Element} focused 18 * Element expected to be focused 19 * @param {Element} activedescendant 20 * Element expected to be the aria activedescendant of the root node 21 */ 22 function testNavigationState(inspector, elms, focused, activedescendant) { 23 const doc = inspector.markup.doc; 24 const id = activedescendant.getAttribute("id"); 25 is(doc.activeElement, focused, `Keyboard focus should be set to ${focused}`); 26 is( 27 elms.root.elt.getAttribute("aria-activedescendant"), 28 id, 29 `Active descendant should be set to ${id}` 30 ); 31 } 32 33 /** 34 * Lookup the provided dotted path ("prop1.subprop2.myProp") in the provided object. 35 * 36 * @param {object} obj 37 * Object to expand. 38 * @param {string} path 39 * Dotted path to use to expand the object. 40 * @return {?} anything that is found at the provided path in the object. 41 */ 42 function lookupPath(obj, path) { 43 const segments = path.split("."); 44 return segments.reduce((prev, current) => prev[current], obj); 45 } 46 47 /** 48 * Execute a keyboard event and check that the state is as expected (focused element, aria 49 * attribute etc...). 50 * 51 * @param {InspectorPanel} inspector 52 * Current instance of the inspector being tested. 53 * @param {object} elms 54 * MarkupContainers/Elements that will be used to retrieve references to other 55 * elements based on objects' paths. 56 * @param {object} testData 57 * - {String} desc: description for better logging. 58 * - {String} key: keyboard event's key. 59 * - {Object} options, optional: event data such as shiftKey, etc. 60 * - {String} focused: path to expected focused element in elms map. 61 * - {String} activedescendant: path to expected aria-activedescendant element in 62 * elms map. 63 * - {String} waitFor, optional: markupview event to wait for if keyboard actions 64 * result in async updates. Also accepts the inspector event "inspector-updated". 65 */ 66 async function runAccessibilityNavigationTest( 67 inspector, 68 elms, 69 { desc, key, options, focused, activedescendant, waitFor } 70 ) { 71 info(desc); 72 73 const markup = inspector.markup; 74 const doc = markup.doc; 75 const win = doc.defaultView; 76 77 let updated; 78 if (waitFor) { 79 updated = 80 waitFor === "inspector-updated" 81 ? inspector.once(waitFor) 82 : markup.once(waitFor); 83 } else { 84 updated = Promise.resolve(); 85 } 86 EventUtils.synthesizeKey(key, options, win); 87 await updated; 88 89 const focusedElement = lookupPath(elms, focused); 90 const activeDescendantElement = lookupPath(elms, activedescendant); 91 testNavigationState(inspector, elms, focusedElement, activeDescendantElement); 92 }