browser_accessibility_node_events.js (5742B)
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 AccessibleActor events 8 9 add_task(async function () { 10 const { target, walker, a11yWalker, parentAccessibility } = 11 await initAccessibilityFrontsForUrl(MAIN_DOMAIN + "doc_accessibility.html"); 12 const modifiers = 13 Services.appinfo.OS === "Darwin" ? "\u2303\u2325" : "Alt+Shift+"; 14 15 const rootNode = await walker.getRootNode(); 16 const a11yDoc = await a11yWalker.getAccessibleFor(rootNode); 17 const buttonNode = await walker.querySelector(walker.rootNode, "#button"); 18 const accessibleFront = await a11yWalker.getAccessibleFor(buttonNode); 19 const sliderNode = await walker.querySelector(walker.rootNode, "#slider"); 20 const accessibleSliderFront = await a11yWalker.getAccessibleFor(sliderNode); 21 const browser = gBrowser.selectedBrowser; 22 23 checkA11yFront(accessibleFront, { 24 name: "Accessible Button", 25 role: "button", 26 childCount: 1, 27 }); 28 29 await accessibleFront.hydrate(); 30 31 checkA11yFront(accessibleFront, { 32 name: "Accessible Button", 33 role: "button", 34 value: "", 35 description: "Accessibility Test", 36 keyboardShortcut: modifiers + "b", 37 childCount: 1, 38 domNodeType: 1, 39 indexInParent: 1, 40 states: ["focusable", "opaque", "enabled", "sensitive"], 41 actions: ["Press"], 42 attributes: { 43 "margin-top": "0px", 44 display: "inline-block", 45 "text-align": "center", 46 "text-indent": "0px", 47 "margin-left": "0px", 48 tag: "button", 49 "margin-right": "0px", 50 id: "button", 51 formatting: "block", 52 "margin-bottom": "0px", 53 }, 54 }); 55 56 info("Name change event"); 57 await emitA11yEvent( 58 accessibleFront, 59 "name-change", 60 (name, parent) => { 61 checkA11yFront(accessibleFront, { name: "Renamed" }); 62 checkA11yFront(parent, {}, a11yDoc); 63 }, 64 () => 65 SpecialPowers.spawn(browser, [], () => 66 content.document 67 .getElementById("button") 68 .setAttribute("aria-label", "Renamed") 69 ) 70 ); 71 72 info("Description change event"); 73 await emitA11yEvent( 74 accessibleFront, 75 "description-change", 76 () => checkA11yFront(accessibleFront, { description: "" }), 77 () => 78 SpecialPowers.spawn(browser, [], () => 79 content.document 80 .getElementById("button") 81 .removeAttribute("aria-describedby") 82 ) 83 ); 84 85 info("State change event"); 86 const expectedStates = ["unavailable", "opaque"]; 87 await emitA11yEvent( 88 accessibleFront, 89 "states-change", 90 newStates => { 91 checkA11yFront(accessibleFront, { states: expectedStates }); 92 SimpleTest.isDeeply(newStates, expectedStates, "States are updated"); 93 }, 94 () => 95 SpecialPowers.spawn(browser, [], () => 96 content.document.getElementById("button").setAttribute("disabled", true) 97 ) 98 ); 99 100 info("Attributes change event"); 101 await emitA11yEvent( 102 accessibleFront, 103 "attributes-change", 104 newAttrs => { 105 checkA11yFront(accessibleFront, { 106 attributes: { 107 "container-live": "polite", 108 display: "inline-block", 109 "explicit-name": "true", 110 id: "button", 111 formatting: "block", 112 live: "polite", 113 "margin-bottom": "0px", 114 "margin-left": "0px", 115 "margin-right": "0px", 116 "margin-top": "0px", 117 tag: "button", 118 "text-align": "center", 119 "text-indent": "0px", 120 }, 121 }); 122 is(newAttrs.live, "polite", "Attributes are updated"); 123 }, 124 () => 125 SpecialPowers.spawn(browser, [], () => 126 content.document 127 .getElementById("button") 128 .setAttribute("aria-live", "polite") 129 ) 130 ); 131 132 info("Value change event"); 133 await accessibleSliderFront.hydrate(); 134 checkA11yFront(accessibleSliderFront, { value: "5" }); 135 await emitA11yEvent( 136 accessibleSliderFront, 137 "value-change", 138 () => checkA11yFront(accessibleSliderFront, { value: "6" }), 139 () => 140 SpecialPowers.spawn(browser, [], () => 141 content.document 142 .getElementById("slider") 143 .setAttribute("aria-valuenow", "6") 144 ) 145 ); 146 147 info("Reorder event"); 148 is(accessibleSliderFront.childCount, 1, "Slider has only 1 child"); 149 const [firstChild] = await accessibleSliderFront.children(); 150 await firstChild.hydrate(); 151 is( 152 firstChild.indexInParent, 153 0, 154 "Slider's first child has correct index in parent" 155 ); 156 await emitA11yEvent( 157 accessibleSliderFront, 158 "reorder", 159 childCount => { 160 is(childCount, 2, "Child count is updated"); 161 is(accessibleSliderFront.childCount, 2, "Child count is updated"); 162 is( 163 firstChild.indexInParent, 164 1, 165 "Slider's first child has an updated index in parent" 166 ); 167 }, 168 () => 169 SpecialPowers.spawn(browser, [], () => { 170 const doc = content.document; 171 const slider = doc.getElementById("slider"); 172 const button = doc.createElement("button"); 173 button.innerText = "Slider button"; 174 content.document 175 .getElementById("slider") 176 .insertBefore(button, slider.firstChild); 177 }) 178 ); 179 180 await emitA11yEvent( 181 firstChild, 182 "index-in-parent-change", 183 indexInParent => 184 is( 185 indexInParent, 186 0, 187 "Slider's first child has an updated index in parent" 188 ), 189 () => 190 SpecialPowers.spawn(browser, [], () => 191 content.document.getElementById("slider").firstChild.remove() 192 ) 193 ); 194 195 await waitForA11yShutdown(parentAccessibility); 196 await target.destroy(); 197 gBrowser.removeCurrentTab(); 198 });