browser_description_general.js (7779B)
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 /* import-globals-from ../../mochitest/name.js */ 8 loadScripts({ name: "name.js", dir: MOCHITESTS_DIR }); 9 10 /** 11 * Test data has the format of: 12 * { 13 * desc {String} description for better logging 14 * expected {String} expected description value for a given accessible 15 * attrs {?Array} an optional list of attributes to update 16 * waitFor {?Array} an optional list of accessible events to wait for when 17 * attributes are updated 18 * } 19 */ 20 const tests = [ 21 { 22 desc: "No description when there are no @alt, @title and @aria-describedby", 23 expected: "", 24 }, 25 { 26 desc: "Description from @aria-describedby attribute", 27 attrs: [ 28 { 29 attr: "aria-describedby", 30 value: "description", 31 }, 32 ], 33 waitFor: [[EVENT_DESCRIPTION_CHANGE, "image"]], 34 expected: "aria description", 35 }, 36 { 37 desc: 38 "No description from @aria-describedby since it is the same as the " + 39 "@alt attribute which is used as the name", 40 attrs: [ 41 { 42 attr: "alt", 43 value: "aria description", 44 }, 45 ], 46 waitFor: [[EVENT_NAME_CHANGE, "image"]], 47 expected: "", 48 }, 49 { 50 desc: 51 "Description from @aria-describedby attribute when @alt and " + 52 "@aria-describedby are not the same", 53 attrs: [ 54 { 55 attr: "aria-describedby", 56 value: "description2", 57 }, 58 ], 59 waitFor: [[EVENT_DESCRIPTION_CHANGE, "image"]], 60 expected: "another description", 61 }, 62 { 63 desc: "No description change when @alt is dropped but @aria-describedby remains", 64 attrs: [ 65 { 66 attr: "alt", 67 }, 68 ], 69 waitFor: [[EVENT_NAME_CHANGE, "image"]], 70 expected: "another description", 71 }, 72 { 73 desc: 74 "Description from @aria-describedby attribute when @title (used for " + 75 "name) and @aria-describedby are not the same", 76 attrs: [ 77 { 78 attr: "title", 79 value: "title", 80 }, 81 ], 82 waitFor: [[EVENT_NAME_CHANGE, "image"]], 83 expected: "another description", 84 }, 85 { 86 desc: 87 "No description from @aria-describedby since it is the same as the " + 88 "@title attribute which is used as the name", 89 attrs: [ 90 { 91 attr: "title", 92 value: "another description", 93 }, 94 ], 95 waitFor: [[EVENT_NAME_CHANGE, "image"]], 96 expected: "", 97 }, 98 { 99 desc: "No description with only @title attribute which is used as the name", 100 attrs: [ 101 { 102 attr: "aria-describedby", 103 }, 104 ], 105 waitFor: [[EVENT_DESCRIPTION_CHANGE, "image"]], 106 expected: "", 107 }, 108 { 109 desc: 110 "Description from @title attribute when @alt and @atitle are not the " + 111 "same", 112 attrs: [ 113 { 114 attr: "alt", 115 value: "aria description", 116 }, 117 ], 118 waitFor: [[EVENT_NAME_CHANGE, "image"]], 119 expected: "another description", 120 }, 121 { 122 desc: 123 "No description from @title since it is the same as the @alt " + 124 "attribute which is used as the name", 125 attrs: [ 126 { 127 attr: "alt", 128 value: "another description", 129 }, 130 ], 131 waitFor: [[EVENT_NAME_CHANGE, "image"]], 132 expected: "", 133 }, 134 { 135 desc: 136 "No description from @aria-describedby since it is the same as the " + 137 "@alt (used for name) and @title attributes", 138 attrs: [ 139 { 140 attr: "aria-describedby", 141 value: "description2", 142 }, 143 ], 144 waitFor: [[EVENT_DESCRIPTION_CHANGE, "image"]], 145 expected: "", 146 }, 147 { 148 desc: 149 "Description from @aria-describedby attribute when it is different " + 150 "from @alt (used for name) and @title attributes", 151 attrs: [ 152 { 153 attr: "aria-describedby", 154 value: "description", 155 }, 156 ], 157 waitFor: [[EVENT_DESCRIPTION_CHANGE, "image"]], 158 expected: "aria description", 159 }, 160 { 161 desc: 162 "No description from @aria-describedby since it is the same as the " + 163 "@alt attribute (used for name) but different from title", 164 attrs: [ 165 { 166 attr: "alt", 167 value: "aria description", 168 }, 169 ], 170 waitFor: [[EVENT_NAME_CHANGE, "image"]], 171 expected: "", 172 }, 173 { 174 desc: 175 "Description from @aria-describedby attribute when @alt (used for " + 176 "name) and @aria-describedby are not the same but @title and " + 177 "aria-describedby are", 178 attrs: [ 179 { 180 attr: "aria-describedby", 181 value: "description2", 182 }, 183 ], 184 waitFor: [[EVENT_DESCRIPTION_CHANGE, "image"]], 185 expected: "another description", 186 }, 187 ]; 188 189 /** 190 * Test caching of accessible object description 191 */ 192 addAccessibleTask( 193 ` 194 <p id="description">aria description</p> 195 <p id="description2">another description</p> 196 <img id="image" src="http://example.com/a11y/accessible/tests/mochitest/moz.png" />`, 197 async function (browser, accDoc) { 198 let imgAcc = findAccessibleChildByID(accDoc, "image"); 199 200 for (let { desc, waitFor, attrs, expected } of tests) { 201 info(desc); 202 let onUpdate; 203 if (waitFor) { 204 onUpdate = waitForOrderedEvents(waitFor); 205 } 206 if (attrs) { 207 for (let { attr, value } of attrs) { 208 await invokeSetAttribute(browser, "image", attr, value); 209 } 210 } 211 await onUpdate; 212 // When attribute change (alt) triggers reorder event, accessible will 213 // become defunct. 214 if (isDefunct(imgAcc)) { 215 imgAcc = findAccessibleChildByID(accDoc, "image"); 216 } 217 testDescr(imgAcc, expected); 218 } 219 }, 220 { iframe: true, remoteIframe: true } 221 ); 222 223 /** 224 * Test that the description is updated when the content of a hidden aria-describedby 225 * subtree changes. 226 */ 227 addAccessibleTask( 228 ` 229 <button id="button" aria-describedby="desc"> 230 <div id="desc" hidden>a</div> 231 `, 232 async function (browser, docAcc) { 233 const button = findAccessibleChildByID(docAcc, "button"); 234 testDescr(button, "a"); 235 info("Changing desc textContent"); 236 let descChanged = waitForEvent(EVENT_DESCRIPTION_CHANGE, button); 237 await invokeContentTask(browser, [], () => { 238 content.document.getElementById("desc").textContent = "c"; 239 }); 240 await descChanged; 241 testDescr(button, "c"); 242 info("Prepending text node to desc"); 243 descChanged = waitForEvent(EVENT_DESCRIPTION_CHANGE, button); 244 await invokeContentTask(browser, [], () => { 245 content.document 246 .getElementById("desc") 247 .prepend(content.document.createTextNode("b")); 248 }); 249 await descChanged; 250 testDescr(button, "bc"); 251 }, 252 { chrome: true, topLevel: true, iframe: true, remoteIframe: true } 253 ); 254 255 /** 256 * Test aria-description, including mutations. 257 */ 258 addAccessibleTask( 259 `<button id="button" aria-description="a">button</button>`, 260 async function (browser, docAcc) { 261 const button = findAccessibleChildByID(docAcc, "button"); 262 testDescr(button, "a"); 263 info("Changing aria-description"); 264 let changed = waitForEvent(EVENT_DESCRIPTION_CHANGE, button); 265 await invokeSetAttribute(browser, "button", "aria-description", "b"); 266 await changed; 267 testDescr(button, "b"); 268 info("Removing aria-description"); 269 changed = waitForEvent(EVENT_DESCRIPTION_CHANGE, button); 270 await invokeSetAttribute(browser, "button", "aria-description"); 271 await changed; 272 testDescr(button, ""); 273 info("Setting aria-description"); 274 changed = waitForEvent(EVENT_DESCRIPTION_CHANGE, button); 275 await invokeSetAttribute(browser, "button", "aria-description", "c"); 276 await changed; 277 testDescr(button, "c"); 278 }, 279 { chrome: true, topLevel: true, iframe: true, remoteIframe: true } 280 );