browser_accessibility_walker.js (5525B)
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 5 "use strict"; 6 7 // Checks for the AccessibleWalkerActor 8 9 add_task(async function () { 10 const { target, walker, a11yWalker, parentAccessibility } = 11 await initAccessibilityFrontsForUrl(MAIN_DOMAIN + "doc_accessibility.html"); 12 13 ok(a11yWalker, "The AccessibleWalkerFront was returned"); 14 const rootNode = await walker.getRootNode(); 15 const a11yDoc = await a11yWalker.getAccessibleFor(rootNode); 16 ok(a11yDoc, "The AccessibleFront for root doc is created"); 17 18 const children = await a11yWalker.children(); 19 is( 20 children.length, 21 1, 22 "AccessibleWalker only has 1 child - root doc accessible" 23 ); 24 is( 25 a11yDoc, 26 children[0], 27 "Root accessible must be AccessibleWalker's only child" 28 ); 29 30 const buttonNode = await walker.querySelector(walker.rootNode, "#button"); 31 const accessibleFront = await a11yWalker.getAccessibleFor(buttonNode); 32 33 checkA11yFront(accessibleFront, { 34 name: "Accessible Button", 35 role: "button", 36 }); 37 38 const ancestry = await a11yWalker.getAncestry(accessibleFront); 39 is(ancestry.length, 1, "Button is a direct child of a root document."); 40 is( 41 ancestry[0].accessible, 42 a11yDoc, 43 "Button's only ancestor is a root document" 44 ); 45 is( 46 ancestry[0].children.length, 47 8, 48 "Root doc should have correct number of children" 49 ); 50 ok( 51 ancestry[0].children.includes(accessibleFront), 52 "Button accessible front is in root doc's children" 53 ); 54 55 const browser = gBrowser.selectedBrowser; 56 57 // Ensure name-change event is emitted by walker when cached accessible's name 58 // gets updated (via DOM manipularion). 59 await emitA11yEvent( 60 a11yWalker, 61 "name-change", 62 (front, parent) => { 63 checkA11yFront(front, { name: "Renamed" }, accessibleFront); 64 checkA11yFront(parent, {}, a11yDoc); 65 }, 66 () => 67 SpecialPowers.spawn(browser, [], () => 68 content.document 69 .getElementById("button") 70 .setAttribute("aria-label", "Renamed") 71 ) 72 ); 73 74 // Ensure reorder event is emitted by walker when DOM tree changes. 75 let docChildren = await a11yDoc.children(); 76 is(docChildren.length, 8, "Root doc should have correct number of children"); 77 78 await emitA11yEvent( 79 a11yWalker, 80 "reorder", 81 front => checkA11yFront(front, {}, a11yDoc), 82 () => 83 SpecialPowers.spawn(browser, [], () => { 84 const input = content.document.createElement("input"); 85 input.type = "text"; 86 input.title = "This is a tooltip"; 87 input.value = "New input"; 88 content.document.body.appendChild(input); 89 }) 90 ); 91 92 docChildren = await a11yDoc.children(); 93 is(docChildren.length, 9, "Root doc should have correct number of children"); 94 95 let shown = await a11yWalker.highlightAccessible(docChildren[0]); 96 ok(shown, "AccessibleHighlighter highlighted the node"); 97 98 shown = await a11yWalker.highlightAccessible(a11yDoc); 99 ok(shown, "AccessibleHighlighter highlights the document correctly."); 100 await a11yWalker.unhighlight(); 101 102 info("Checking AccessibleWalker picker functionality"); 103 ok(a11yWalker.pick, "AccessibleWalker pick method exists"); 104 ok(a11yWalker.pickAndFocus, "AccessibleWalker pickAndFocus method exists"); 105 ok(a11yWalker.cancelPick, "AccessibleWalker cancelPick method exists"); 106 107 let onPickerEvent = a11yWalker.once("picker-accessible-hovered"); 108 await a11yWalker.pick(); 109 await BrowserTestUtils.synthesizeMouseAtCenter( 110 "#h1", 111 { type: "mousemove" }, 112 browser 113 ); 114 let acc = await onPickerEvent; 115 checkA11yFront(acc, { name: "Accessibility Test" }, docChildren[0]); 116 117 onPickerEvent = a11yWalker.once("picker-accessible-previewed"); 118 await BrowserTestUtils.synthesizeMouseAtCenter( 119 "#h1", 120 { shiftKey: true }, 121 browser 122 ); 123 acc = await onPickerEvent; 124 checkA11yFront(acc, { name: "Accessibility Test" }, docChildren[0]); 125 126 onPickerEvent = a11yWalker.once("picker-accessible-canceled"); 127 await BrowserTestUtils.synthesizeKey( 128 "VK_ESCAPE", 129 { type: "keydown" }, 130 browser 131 ); 132 await onPickerEvent; 133 134 onPickerEvent = a11yWalker.once("picker-accessible-hovered"); 135 await a11yWalker.pick(); 136 await BrowserTestUtils.synthesizeMouseAtCenter( 137 "#h1", 138 { type: "mousemove" }, 139 browser 140 ); 141 await onPickerEvent; 142 143 onPickerEvent = a11yWalker.once("picker-accessible-picked"); 144 await BrowserTestUtils.synthesizeMouseAtCenter("#h1", {}, browser); 145 acc = await onPickerEvent; 146 checkA11yFront(acc, { name: "Accessibility Test" }, docChildren[0]); 147 148 await a11yWalker.cancelPick(); 149 150 info("Checking tabbing order highlighter"); 151 let { elm, index } = await a11yWalker.showTabbingOrder(rootNode, 0); 152 isnot(!!elm, "No current element when at the end of the tab order"); 153 is(index, 3, "Current index is correct"); 154 await a11yWalker.hideTabbingOrder(); 155 156 ({ elm, index } = await a11yWalker.showTabbingOrder(buttonNode, 0)); 157 isnot(!!elm, "No current element when at the end of the tab order"); 158 is(index, 2, "Current index is correct"); 159 await a11yWalker.hideTabbingOrder(); 160 161 info( 162 "When targets follow the WindowGlobal lifecycle and handle only one document, " + 163 "only check that the panel refreshes correctly and emit its 'reloaded' event" 164 ); 165 await reloadBrowser(); 166 167 await waitForA11yShutdown(parentAccessibility); 168 await target.destroy(); 169 gBrowser.removeCurrentTab(); 170 });