test_valuechange.html (10804B)
1 <html> 2 3 <head> 4 <title>Accessible value change events testing</title> 5 6 <link rel="stylesheet" type="text/css" 7 href="chrome://mochikit/content/tests/SimpleTest/test.css" /> 8 9 <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> 10 <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> 11 12 <script type="application/javascript" 13 src="../common.js"></script> 14 <script type="application/javascript" 15 src="../events.js"></script> 16 17 <script type="application/javascript" 18 src="../value.js"></script> 19 20 <script type="application/javascript"> 21 /** 22 * Do tests. 23 */ 24 var gQueue = null; 25 26 // Value change invoker 27 function changeARIAValue(aNodeOrID, aValuenow, aValuetext) { 28 this.DOMNode = getNode(aNodeOrID); 29 this.eventSeq = [ new invokerChecker(aValuetext ? 30 EVENT_TEXT_VALUE_CHANGE : 31 EVENT_VALUE_CHANGE, this.DOMNode), 32 ]; 33 34 this.invoke = function changeARIAValue_invoke() { 35 // Note: this should not fire an EVENT_VALUE_CHANGE when aria-valuetext 36 // is not empty 37 if (aValuenow != undefined) 38 this.DOMNode.setAttribute("aria-valuenow", aValuenow); 39 40 // Note: this should always fire an EVENT_VALUE_CHANGE 41 if (aValuetext != undefined) 42 this.DOMNode.setAttribute("aria-valuetext", aValuetext); 43 }; 44 45 this.check = function changeARIAValue_check() { 46 var acc = getAccessible(aNodeOrID, [nsIAccessibleValue]); 47 if (!acc) 48 return; 49 50 // Note: always test against valuetext first because the existence of 51 // aria-valuetext takes precedence over aria-valuenow in gecko. 52 is(acc.value, (aValuetext != undefined) ? aValuetext : aValuenow, 53 "Wrong value of " + prettyName(aNodeOrID)); 54 }; 55 56 this.getID = function changeARIAValue_getID() { 57 return prettyName(aNodeOrID) + " value changed"; 58 }; 59 } 60 61 function changeValue(aID, aValue) { 62 this.DOMNode = getNode(aID); 63 this.eventSeq = [new invokerChecker(EVENT_TEXT_VALUE_CHANGE, 64 this.DOMNode), 65 ]; 66 67 this.invoke = function changeValue_invoke() { 68 this.DOMNode.value = aValue; 69 }; 70 71 this.check = function changeValue_check() { 72 var acc = getAccessible(this.DOMNode); 73 is(acc.value, aValue, "Wrong value for " + prettyName(aID)); 74 }; 75 76 this.getID = function changeValue_getID() { 77 return prettyName(aID) + " value changed"; 78 }; 79 } 80 81 function changeProgressValue(aID, aValue) { 82 this.DOMNode = getNode(aID); 83 this.eventSeq = [new invokerChecker(EVENT_VALUE_CHANGE, this.DOMNode)]; 84 85 this.invoke = function changeProgressValue_invoke() { 86 this.DOMNode.value = aValue; 87 }; 88 89 this.check = function changeProgressValue_check() { 90 var acc = getAccessible(this.DOMNode); 91 is(acc.value, aValue + "%", "Wrong value for " + prettyName(aID)); 92 }; 93 94 this.getID = function changeProgressValue_getID() { 95 return prettyName(aID) + " value changed"; 96 }; 97 } 98 99 function changeRangeValueWithMouse(aID) { 100 this.DOMNode = getNode(aID); 101 this.eventSeq = [new invokerChecker(EVENT_VALUE_CHANGE, this.DOMNode)]; 102 103 this.invoke = function changeRangeValue_invoke() { 104 synthesizeMouse(getNode(aID), 5, 5, { }); 105 }; 106 107 this.finalCheck = function changeRangeValue_finalCheck() { 108 var acc = getAccessible(this.DOMNode); 109 is(acc.value, "0", "Wrong value for " + prettyName(aID)); 110 }; 111 112 this.getID = function changeRangeValue_getID() { 113 return prettyName(aID) + " range value changed"; 114 }; 115 } 116 117 function changeRangeValueWithA11yAPI(aID) { 118 this.DOMNode = getNode(aID); 119 let inputChecker = new invokerChecker("input", this.DOMNode); 120 inputChecker.eventTarget = "element"; 121 122 let changeChecker = new invokerChecker("change", this.DOMNode); 123 changeChecker.eventTarget = "element"; 124 125 this.eventSeq = [ 126 inputChecker, 127 changeChecker, 128 new invokerChecker(EVENT_VALUE_CHANGE, this.DOMNode), 129 ]; 130 131 this.invoke = function changeRangeValue_invoke() { 132 this.DOMNode.focus(); 133 let acc = getAccessible(this.DOMNode, [nsIAccessibleValue]); 134 acc.currentValue = 0; 135 this.DOMNode.blur(); 136 }; 137 138 this.finalCheck = function changeRangeValue_finalCheck() { 139 var acc = getAccessible(this.DOMNode); 140 is(acc.value, "0", "Wrong value for " + prettyName(aID)); 141 }; 142 143 this.getID = function changeRangeValue_getID() { 144 return prettyName(aID) + " range value changed"; 145 }; 146 } 147 148 function changeSelectValue(aID, aKey, aValue) { 149 this.eventSeq = 150 [ new invokerChecker(EVENT_TEXT_VALUE_CHANGE, getAccessible(aID)) ]; 151 152 this.invoke = function changeSelectValue_invoke() { 153 getAccessible(aID).takeFocus(); 154 synthesizeKey(aKey, {}, window); 155 }; 156 157 this.finalCheck = function changeSelectValue_finalCheck() { 158 is(getAccessible(aID).value, aValue, "Wrong value for " + prettyName(aID)); 159 }; 160 161 this.getID = function changeSelectValue_getID() { 162 return `${prettyName(aID)} closed select value change on '${aKey}'' key press`; 163 }; 164 } 165 166 // enableLogging("DOMEvents"); 167 // gA11yEventDumpToConsole = true; 168 function doTests() { 169 170 // Test initial values 171 testValue("slider_vn", "5", 5, 0, 1000, 0); 172 testValue("slider_vnvt", "plain", 0, 0, 5, 0); 173 testValue("slider_vt", "hi", 1.5, 0, 3, 0); 174 testValue("scrollbar", "5", 5, 0, 1000, 0); 175 testValue("splitter", "5", 5, 0, 1000, 0); 176 testValue("progress", "22%", 22, 0, 100, 0); 177 testValue("range", "6", 6, 0, 10, 1); 178 testValue("range2", "6", 6, 0, 10, 1); 179 180 // Test that elements which should not expose values do not 181 let separatorVal = getAccessible("separator", [nsIAccessibleValue], null, DONOTFAIL_IF_NO_INTERFACE); 182 ok(!separatorVal, "value interface is not exposed for separator"); 183 let separatorAcc = getAccessible("separator"); 184 ok(!separatorAcc.value, "Value text is not exposed for separator"); 185 186 // Test value change events 187 gQueue = new eventQueue(); 188 189 gQueue.push(new changeARIAValue("slider_vn", "6", undefined)); 190 gQueue.push(new changeARIAValue("slider_vt", undefined, "hey!")); 191 gQueue.push(new changeARIAValue("slider_vnvt", "3", "sweet")); 192 gQueue.push(new changeARIAValue("scrollbar", "6", undefined)); 193 gQueue.push(new changeARIAValue("splitter", "6", undefined)); 194 195 gQueue.push(new changeValue("combobox", "hello")); 196 197 gQueue.push(new changeProgressValue("progress", "50")); 198 gQueue.push(new changeRangeValueWithMouse("range")); 199 gQueue.push(new changeRangeValueWithA11yAPI("range2")); 200 201 gQueue.push(new changeSelectValue("select", "VK_DOWN", "2nd")); 202 gQueue.push(new changeSelectValue("select", "3", "3rd")); 203 204 let iframeSelect = getAccessible("selectIframe").firstChild.firstChild; 205 gQueue.push(new changeSelectValue(iframeSelect, "VK_DOWN", "2")); 206 207 let shadowSelect = getAccessible("selectShadow").firstChild; 208 gQueue.push(new changeSelectValue(shadowSelect, "VK_DOWN", "2")); 209 gQueue.push(new changeValue("number", "2")); 210 211 gQueue.invoke(); // Will call SimpleTest.finish(); 212 } 213 214 SimpleTest.waitForExplicitFinish(); 215 addA11yLoadEvent(doTests); 216 </script> 217 </head> 218 219 <body> 220 221 <a target="_blank" 222 href="https://bugzilla.mozilla.org/show_bug.cgi?id=478032" 223 title=" Fire delayed value changed event for aria-valuetext changes"> 224 Mozilla Bug 478032 225 </a> 226 <a target="_blank" 227 href="https://bugzilla.mozilla.org/show_bug.cgi?id=529289" 228 title="We dont expose new aria role 'scrollbar' and property aria-orientation"> 229 Mozilla Bug 529289 230 </a> 231 <a target="_blank" 232 href="https://bugzilla.mozilla.org/show_bug.cgi?id=559764" 233 title="Make HTML5 input@type=range element accessible"> 234 Mozilla Bug 559764 235 </a> 236 <a target="_blank" 237 href="https://bugzilla.mozilla.org/show_bug.cgi?id=703202" 238 title="ARIA comboboxes don't fire value change events"> 239 Mozilla Bug 703202 240 </a> 241 <a target="_blank" 242 href="https://bugzilla.mozilla.org/show_bug.cgi?id=761901" 243 title=" HTML5 progress accessible should fire value change event"> 244 Mozilla Bug 761901 245 </a> 246 247 248 <p id="display"></p> 249 <div id="content" style="display: none"></div> 250 <pre id="test"> 251 </pre> 252 <div id="eventdump"></div> 253 254 <!-- ARIA sliders --> 255 <div id="slider_vn" role="slider" aria-valuenow="5" 256 aria-valuemin="0" aria-valuemax="1000">slider</div> 257 258 <div id="slider_vt" role="slider" aria-valuetext="hi" 259 aria-valuemin="0" aria-valuemax="3">greeting slider</div> 260 261 <div id="slider_vnvt" role="slider" aria-valuenow="0" aria-valuetext="plain" 262 aria-valuemin="0" aria-valuemax="5">sweetness slider</div> 263 264 <!-- ARIA scrollbar --> 265 <div id="scrollbar" role="scrollbar" aria-valuenow="5" 266 aria-valuemin="0" aria-valuemax="1000">slider</div> 267 268 <!-- ARIA separator which is focusable (i.e. a splitter) --> 269 <div id="splitter" role="separator" tabindex="0" aria-valuenow="5" 270 aria-valuemin="0" aria-valuemax="1000">splitter</div> 271 272 <!-- ARIA separator which is not focusable and should not expose values --> 273 <div id="separator" role="separator" aria-valuenow="5" 274 aria-valuemin="0" aria-valuemax="1000">splitter</div> 275 276 <!-- ARIA combobox --> 277 <input id="combobox" role="combobox" aria-autocomplete="inline"> 278 279 <!-- progress bar --> 280 <progress id="progress" value="22" max="100"></progress> 281 282 <!-- input@type="range" --> 283 <input type="range" id="range" min="0" max="10" value="6"> 284 285 <!-- input@type="range" --> 286 <input type="range" id="range2" min="0" max="10" value="6"> 287 288 <select id="select"> 289 <option>1st</option> 290 <option>2nd</option> 291 <option>3rd</option> 292 </select> 293 294 <iframe id="selectIframe" 295 src="data:text/html,<select id='iframeSelect'><option>1</option><option>2</option></select>"> 296 </iframe> 297 298 <div id="selectShadow"></div> 299 <script> 300 let host = document.getElementById("selectShadow"); 301 let shadow = host.attachShadow({mode: "open"}); 302 let select = document.createElement("select"); 303 select.id = "shadowSelect"; 304 let option = document.createElement("option"); 305 option.textContent = "1"; 306 select.appendChild(option); 307 option = document.createElement("option"); 308 option.textContent = "2"; 309 select.appendChild(option); 310 shadow.appendChild(select); 311 </script> 312 313 <input type="number" id="number" value="1"> 314 </body> 315 </html>