OLD | NEW |
| (Empty) |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // Include test fixture. | |
6 GEN_INCLUDE(['../testing/chromevox_unittest_base.js']); | |
7 | |
8 /** | |
9 * Test fixture. | |
10 * @constructor | |
11 * @extends {ChromeVoxUnitTestBase} | |
12 */ | |
13 function CvoxDomUtilUnitTest() {} | |
14 | |
15 CvoxDomUtilUnitTest.prototype = { | |
16 __proto__: ChromeVoxUnitTestBase.prototype, | |
17 | |
18 /** @override */ | |
19 closureModuleDeps: [ | |
20 'cvox.ChromeVox', | |
21 'cvox.DescriptionUtil', | |
22 'cvox.DomUtil', | |
23 'cvox.TestMsgs', | |
24 ], | |
25 | |
26 /** @override */ | |
27 setUp: function() { | |
28 cvox.ChromeVox.msgs = new cvox.TestMsgs(); | |
29 }, | |
30 | |
31 asText_: function(node) { | |
32 var temp = document.createElement('div'); | |
33 temp.appendChild(node); | |
34 return temp.innerHTML; | |
35 }, | |
36 | |
37 assertEqualsAsText_: function(node1, node2) { | |
38 assertEquals(this.asText_(node1), this.asText_(node2)); | |
39 }, | |
40 | |
41 loadDomUtilTestDoc_: function() { | |
42 this.loadDoc(function() {/*! | |
43 <style type="text/css"> | |
44 #display_none { display: none; } | |
45 #visibility_hidden { visibility: hidden; } | |
46 #forced_visible { visibility: hidden; } | |
47 #visibility_collapse { visibility: collapse; } | |
48 #opacity_zero { opacity: 0; } | |
49 #opacity_partial { opacity: 0.5; } | |
50 #opacity_undefined { } | |
51 #nested_visibility_hide { visibility: hidden; } | |
52 #nested_visibility_show { visibility: visible; } | |
53 #nested_display_none { display: none; } | |
54 #nested_display_block { display: block; } | |
55 </style> | |
56 <form action=""> | |
57 | |
58 <div id="normal_node">1</div> | |
59 <div id="display_none">2</div> | |
60 <div id="visibility_hidden">3</div> | |
61 <div id="visibility_collapse">3b</div> | |
62 <div id="opacity_zero">4</div> | |
63 <div id="opacity_partial">4b</div> | |
64 <div id="opacity_undefined">5</div> | |
65 <select id="select_node"><option>5</option></select> | |
66 <textarea id="textarea">6</textarea> | |
67 <div id="forced_visible" aria-hidden="false">7</div> | |
68 <p id="normal_para">----</p> | |
69 <p id="presentation" role="presentation">----</p> | |
70 <p id="aria_hidden" aria-hidden="true">----</p> | |
71 <p id="only_spaces"> </p> | |
72 <p id="only_tabs"> </p> | |
73 <p id="only_newlines"> | |
74 | |
75 </p> | |
76 <p id="only_nbsp"> </p> | |
77 <p id="other_entity">&</p> | |
78 <img id="img"> | |
79 <img id="img_alt" alt="tree"> | |
80 <img id="img_blankalt" alt=""> | |
81 | |
82 <input id="check" type="checkbox"> | |
83 <input id="check_checked" type="checkbox" checked> | |
84 | |
85 <span><p id="a">a</p></span> | |
86 <span><p id="b">b</p><p id="c">c</p></span> | |
87 </form> | |
88 | |
89 <a id="special_link1" href="http://google.com"><span id="empty_span"></span> | |
90 </a> | |
91 <a id="special_link2" href="http://google.com"><span>Text content</span></a> | |
92 <a id="special_link3"><span></span></a> | |
93 | |
94 <div id="nested_visibility_hide"> | |
95 hide<div id="nested_visibility_show">show</div>me | |
96 </div> | |
97 <div id="nested_display_none"> | |
98 nothing<div id="nested_display_block">will</div>show | |
99 </div> | |
100 */}); | |
101 }, | |
102 }; | |
103 | |
104 TEST_F('CvoxDomUtilUnitTest', 'IsVisible', function() { | |
105 this.loadDomUtilTestDoc_(); | |
106 | |
107 // Simple tests. | |
108 var node = $('normal_node'); | |
109 assertEquals(true, cvox.DomUtil.isVisible(node)); | |
110 node = $('display_none'); | |
111 assertEquals(false, cvox.DomUtil.isVisible(node)); | |
112 node = $('visibility_hidden'); | |
113 assertEquals(false, cvox.DomUtil.isVisible(node)); | |
114 node = $('visibility_collapse'); | |
115 assertEquals(false, cvox.DomUtil.isVisible(node)); | |
116 node = $('opacity_zero'); | |
117 assertEquals(false, cvox.DomUtil.isVisible(node)); | |
118 node = $('opacity_partial'); | |
119 assertEquals(true, cvox.DomUtil.isVisible(node)); | |
120 node = $('opacity_undefined'); | |
121 assertEquals(true, cvox.DomUtil.isVisible(node)); | |
122 node = $('forced_visible'); | |
123 assertEquals(true, cvox.DomUtil.isVisible(node)); | |
124 | |
125 // Nested visibility tests. | |
126 node = $('nested_visibility_hide'); | |
127 assertEquals(true, cvox.DomUtil.isVisible(node)); // Has visible child. | |
128 node = $('nested_visibility_hide').childNodes[0]; | |
129 assertEquals(false, cvox.DomUtil.isVisible(node)); // TextNode is invisible. | |
130 node = $('nested_visibility_show'); | |
131 assertEquals(true, cvox.DomUtil.isVisible(node)); | |
132 node = $('nested_visibility_show').childNodes[0]; | |
133 assertEquals(true, cvox.DomUtil.isVisible(node)); // TextNode is visible. | |
134 node = $('nested_display_block'); | |
135 assertEquals(false, cvox.DomUtil.isVisible(node)); | |
136 | |
137 // Options tests (for performance). | |
138 node = $('nested_display_block'); | |
139 assertEquals(true, | |
140 cvox.DomUtil.isVisible(node, {checkAncestors: false})); | |
141 node = $('nested_visibility_hide'); | |
142 assertEquals(false, | |
143 cvox.DomUtil.isVisible(node, {checkDescendants: false})); | |
144 | |
145 // Test that an element not part of the DOM is treated as invisible. | |
146 var div = document.createElement('div'); | |
147 assertEquals(false, cvox.DomUtil.isVisible(div)); | |
148 document.body.appendChild(div); | |
149 assertEquals(true, cvox.DomUtil.isVisible(div)); | |
150 }); | |
151 | |
152 /** Test determining if a node is a leaf node or not. @export */ | |
153 TEST_F('CvoxDomUtilUnitTest', 'IsLeafNode', function() { | |
154 this.loadDomUtilTestDoc_(); | |
155 | |
156 var node = $('normal_node'); | |
157 assertEquals(false, cvox.DomUtil.isLeafNode(node)); | |
158 node = $('display_none'); | |
159 assertEquals(true, cvox.DomUtil.isLeafNode(node)); | |
160 node = $('visibility_hidden'); | |
161 assertEquals(true, cvox.DomUtil.isLeafNode(node)); | |
162 node = $('opacity_zero'); | |
163 assertEquals(true, cvox.DomUtil.isLeafNode(node)); | |
164 node = $('select_node'); | |
165 assertEquals(true, cvox.DomUtil.isLeafNode(node)); | |
166 node = $('textarea'); | |
167 assertEquals(true, cvox.DomUtil.isLeafNode(node)); | |
168 node = $('normal_para'); | |
169 assertEquals(false, cvox.DomUtil.isLeafNode(node)); | |
170 node = $('aria_hidden'); | |
171 assertEquals(true, cvox.DomUtil.isLeafNode(node)); | |
172 node = $('special_link1'); | |
173 assertEquals(true, cvox.DomUtil.isLeafNode(node)); | |
174 node = $('special_link2'); | |
175 assertEquals(true, cvox.DomUtil.isLeafNode(node)); | |
176 node = $('special_link3'); | |
177 assertEquals(false, cvox.DomUtil.isLeafNode(node)); | |
178 node = $('nested_visibility_hide'); | |
179 assertEquals(false, cvox.DomUtil.isLeafNode(node)); | |
180 }); | |
181 | |
182 /** Test determining if a node has content or not. @export */ | |
183 TEST_F('CvoxDomUtilUnitTest', 'HasContent', function() { | |
184 this.loadDomUtilTestDoc_(); | |
185 | |
186 var node = $('normal_node'); | |
187 cvox.DomUtil.hasContent(node); | |
188 assertEquals(true, cvox.DomUtil.hasContent(node)); | |
189 node = $('display_none'); | |
190 assertEquals(false, cvox.DomUtil.hasContent(node)); | |
191 node = $('visibility_hidden'); | |
192 assertEquals(false, cvox.DomUtil.hasContent(node)); | |
193 node = $('opacity_zero'); | |
194 assertEquals(false, cvox.DomUtil.hasContent(node)); | |
195 node = $('select_node'); | |
196 assertEquals(true, cvox.DomUtil.hasContent(node)); | |
197 node = $('textarea'); | |
198 assertEquals(true, cvox.DomUtil.hasContent(node)); | |
199 node = $('normal_para'); | |
200 assertEquals(true, cvox.DomUtil.hasContent(node)); | |
201 // TODO (adu): This test fails. Will inspect. | |
202 // node = $('presentation'); | |
203 // assertEquals(false, cvox.DomUtil.hasContent(node)); | |
204 node = $('aria_hidden'); | |
205 assertEquals(false, cvox.DomUtil.hasContent(node)); | |
206 node = $('only_spaces'); | |
207 assertEquals(false, cvox.DomUtil.hasContent(node)); | |
208 node = $('only_tabs'); | |
209 assertEquals(false, cvox.DomUtil.hasContent(node)); | |
210 node = $('only_newlines'); | |
211 assertEquals(false, cvox.DomUtil.hasContent(node)); | |
212 node = $('other_entity'); | |
213 assertEquals(true, cvox.DomUtil.hasContent(node)); | |
214 node = $('img'); | |
215 assertEquals(true, cvox.DomUtil.hasContent(node)); | |
216 node = $('img_alt'); | |
217 assertEquals(true, cvox.DomUtil.hasContent(node)); | |
218 node = $('img_blankalt'); | |
219 assertEquals(false, cvox.DomUtil.hasContent(node)); | |
220 }); | |
221 | |
222 /** Test getting a node's state. @export */ | |
223 TEST_F('CvoxDomUtilUnitTest', 'NodeState', function() { | |
224 this.loadDomUtilTestDoc_(); | |
225 this.appendDoc(function() {/*! | |
226 <input id="state1_enabled"> | |
227 <input id="state1_disabled" disabled> | |
228 <button id="state2_enabled">Button</button> | |
229 <button id="state2_disabled" disabled>Button</button> | |
230 <textarea id="state3_enabled">Textarea</textarea> | |
231 <textarea id="state3_disabled" disabled>Textarea</textarea> | |
232 <select id="state4_enabled"><option>Select</option></select> | |
233 <select id="state4_disabled" disabled><option>Select</option></select> | |
234 <div role="button" id="state5_enabled" tabindex="0">ARIAButton</div> | |
235 <div role="button" id="state5_disabled" tabindex="0" disabled>ARIAButton</div> | |
236 <fieldset> | |
237 <input id="state6_enabled"> | |
238 </fieldset> | |
239 <fieldset disabled> | |
240 <input id="state6_disabled"> | |
241 </fieldset> | |
242 */}); | |
243 var node = $('check'); | |
244 assertEquals('not checked', cvox.DomUtil.getState(node, true)); | |
245 node = $('check_checked'); | |
246 assertEquals('checked', cvox.DomUtil.getState(node, true)); | |
247 node = $('state1_enabled'); | |
248 assertEquals('', cvox.DomUtil.getState(node, true)); | |
249 node = $('state1_disabled'); | |
250 assertEquals('Disabled', cvox.DomUtil.getState(node, true)); | |
251 node = $('state2_enabled'); | |
252 assertEquals('', cvox.DomUtil.getState(node, true)); | |
253 node = $('state2_disabled'); | |
254 assertEquals('Disabled', cvox.DomUtil.getState(node, true)); | |
255 node = $('state3_enabled'); | |
256 assertEquals('', cvox.DomUtil.getState(node, true)); | |
257 node = $('state3_disabled'); | |
258 assertEquals('Disabled', cvox.DomUtil.getState(node, true)); | |
259 node = $('state4_enabled'); | |
260 assertEquals('1 of 1', cvox.DomUtil.getState(node, true)); | |
261 node = $('state4_disabled'); | |
262 assertEquals('1 of 1 Disabled', cvox.DomUtil.getState(node, true)); | |
263 node = $('state5_enabled'); | |
264 assertEquals('', cvox.DomUtil.getState(node, true)); | |
265 node = $('state5_disabled'); | |
266 assertEquals('', cvox.DomUtil.getState(node, true)); | |
267 node = $('state6_enabled'); | |
268 assertEquals('', cvox.DomUtil.getState(node, true)); | |
269 node = $('state6_disabled'); | |
270 assertEquals('Disabled', cvox.DomUtil.getState(node, true)); | |
271 }); | |
272 | |
273 /** Test finding the next/previous leaf node. @export */ | |
274 TEST_F('CvoxDomUtilUnitTest', 'LeafNodeTraversal', function() { | |
275 this.loadDomUtilTestDoc_(); | |
276 | |
277 var node = $('a'); | |
278 node = cvox.DomUtil.directedNextLeafNode(node); | |
279 assertEquals('\n ', node.textContent); | |
280 node = cvox.DomUtil.directedNextLeafNode(node); | |
281 assertEquals('b', node.textContent); | |
282 node = cvox.DomUtil.directedNextLeafNode(node); | |
283 assertEquals('c', node.textContent); | |
284 node = cvox.DomUtil.previousLeafNode(node); | |
285 assertEquals('b', node.textContent); | |
286 node = cvox.DomUtil.previousLeafNode(node); | |
287 assertEquals('\n ', node.textContent); | |
288 node = cvox.DomUtil.previousLeafNode(node); | |
289 assertEquals('a', node.textContent); | |
290 }); | |
291 | |
292 /** Test finding the label for controls. @export */ | |
293 TEST_F('CvoxDomUtilUnitTest', 'GetLabel', function() { | |
294 this.loadDoc(function() {/*! | |
295 <fieldset id="Fieldset"> | |
296 <legend>This is a legend inside a fieldset</legend> | |
297 <div align="right"> | |
298 <span> | |
299 Username: | |
300 </span> | |
301 </div> | |
302 <input name="Email" id="Email" size="18" value="" type="text"> | |
303 <span> | |
304 Password: | |
305 </span> | |
306 <input name="Passwd" id="Passwd" size="18" type="password"> | |
307 <input name="PersistentCookie" id="PersistentCookie" type="checkbox"> | |
308 <label for="PersistentCookie" id="PersistentCookieLabel"> | |
309 Stay signed in | |
310 </label> | |
311 <input name="signIn" id="signIn" value="Sign in" type="submit"> | |
312 <input id="dummyA" size="18" value="" type="text" title=""> | |
313 <input id="dummyB" size="18" value="" type="text" aria-label=""> | |
314 </fieldset> | |
315 */}); | |
316 | |
317 function getControlText(control) { | |
318 var description = cvox.DescriptionUtil.getControlDescription(control); | |
319 return cvox.DomUtil.collapseWhitespace( | |
320 description.context + ' ' + | |
321 description.text + ' ' + | |
322 description.userValue + ' ' + | |
323 description.annotation); | |
324 } | |
325 | |
326 var fieldsetElement = $('Fieldset'); | |
327 assertEquals('This is a legend inside a fieldset', | |
328 cvox.DomUtil.getName(fieldsetElement, false, false)); | |
329 | |
330 var usernameField = $('Email'); | |
331 assertEquals('', cvox.DomUtil.getValue(usernameField)); | |
332 assertEquals('Username:', | |
333 cvox.DomUtil.getControlLabelHeuristics(usernameField)); | |
334 assertEquals('Username: Edit text', getControlText(usernameField)); | |
335 var passwordField = $('Passwd'); | |
336 assertEquals('', cvox.DomUtil.getValue(passwordField)); | |
337 assertEquals('Password:', | |
338 cvox.DomUtil.getControlLabelHeuristics(passwordField)); | |
339 assertEquals('Password: Password edit text', getControlText(passwordField)); | |
340 var cookieCheckbox = $('PersistentCookie'); | |
341 assertEquals('Stay signed in', cvox.DomUtil.getName(cookieCheckbox)); | |
342 assertEquals('Stay signed in Check box not checked', | |
343 getControlText(cookieCheckbox)); | |
344 var signinButton = $('signIn'); | |
345 assertEquals('Sign in', cvox.DomUtil.getName(signinButton)); | |
346 assertEquals('Sign in Button', getControlText(signinButton)); | |
347 var dummyInputA = $('dummyA'); | |
348 assertEquals('', cvox.DomUtil.getName(dummyInputA)); | |
349 var dummyInputB = $('dummyB'); | |
350 assertEquals('', cvox.DomUtil.getName(dummyInputB)); | |
351 | |
352 // The heuristic no longer returns 'Stay signed in' as the label for | |
353 // the signIn button because 'Stay signed in' is in a label that's | |
354 // explicitly associated with another control. | |
355 //assertEquals('Stay signed in ', | |
356 // cvox.DomUtil.getControlLabelHeuristics(signinButton)); | |
357 }); | |
358 | |
359 /** Test finding the label for controls with a more complex setup. @export */ | |
360 TEST_F('CvoxDomUtilUnitTest', 'GetLabelComplex', function() { | |
361 this.loadDoc(function() {/*! | |
362 <table class="bug-report-table"> | |
363 <tbody><tr> | |
364 <td class="bug-report-fieldlabel"> | |
365 <input id="page-url-checkbox" type="checkbox"> | |
366 <span id="page-url-label" i18n-content="page-url">Include this URL:</span> | |
367 </td> | |
368 <td> | |
369 <input id="page-url-text" class="bug-report-field" maxlength="200"> | |
370 </td> | |
371 </tr> | |
372 </tbody></table> | |
373 <table id="user-email-table" class="bug-report-table"> | |
374 <tbody><tr> | |
375 <td class="bug-report-fieldlabel"> | |
376 <input id="user-email-checkbox" checked="checked" type="checkbox"> | |
377 <span id="user-email-label">Include this email:</span> | |
378 </td> | |
379 <td> | |
380 <label id="user-email-text" class="bug-report-field"></label> | |
381 </td> | |
382 </tr> | |
383 </tbody></table> | |
384 <table class="bug-report-table"> | |
385 <tbody><tr> | |
386 <td class="bug-report-fieldlabel"> | |
387 <input id="sys-info-checkbox" checked="checked" type="checkbox"> | |
388 <span id="sysinfo-label"> | |
389 <a id="sysinfo-url" href="#">Send system information</a> | |
390 </span> | |
391 </td> | |
392 </tr> | |
393 </tbody></table> | |
394 <table class="bug-report-table"> | |
395 <tbody><tr> | |
396 <td class="bug-report-fieldlabel"> | |
397 <input id="screenshot-checkbox" type="checkbox"> | |
398 <span id="screenshot-label-current">Include the current screenshot:</span> | |
399 </td> | |
400 </tr> | |
401 </tbody></table> | |
402 */}); | |
403 var urlCheckbox = $('page-url-checkbox'); | |
404 assertEquals('Include this URL:', | |
405 cvox.DomUtil.getControlLabelHeuristics(urlCheckbox)); | |
406 var emailCheckbox = $('user-email-checkbox'); | |
407 assertEquals('Include this email:', | |
408 cvox.DomUtil.getControlLabelHeuristics(emailCheckbox)); | |
409 var sysCheckbox = $('sys-info-checkbox'); | |
410 assertEquals('Send system information', | |
411 cvox.DomUtil.getControlLabelHeuristics(sysCheckbox)); | |
412 }); | |
413 | |
414 /**************************************************************/ | |
415 | |
416 TEST_F('CvoxDomUtilUnitTest', 'EscapedNames', function() { | |
417 this.loadDoc(function() {/*! | |
418 <p id="en-title" title="<>"></p> | |
419 <p id="en-arialabel" aria-label="<>"></p> | |
420 <img id="en-img" title="<>"></img> | |
421 <p id="en-double" title="&lt;&gt;"></p> | |
422 */}); | |
423 assertEquals('<>', cvox.DomUtil.getName( | |
424 $('en-title'))); | |
425 assertEquals('<>', cvox.DomUtil.getName( | |
426 $('en-arialabel'))); | |
427 assertEquals('<>', cvox.DomUtil.getName( | |
428 $('en-img'))); | |
429 assertEquals('<>', cvox.DomUtil.getName( | |
430 $('en-double'))); | |
431 }); | |
432 | |
433 /** Test a paragraph with plain text. @export */ | |
434 TEST_F('CvoxDomUtilUnitTest', 'SimplePara', function() { | |
435 this.loadDoc(function() {/*! | |
436 <p id="simplepara">This is a simple paragraph.</p> | |
437 */}); | |
438 var node = $('simplepara'); | |
439 var text = cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(node)); | |
440 assertEquals('This is a simple paragraph.', text); | |
441 }); | |
442 | |
443 /** Test a paragraph with nested tags. @export */ | |
444 TEST_F('CvoxDomUtilUnitTest', 'NestedPara', function() { | |
445 this.loadDoc(function() {/*! | |
446 <p id="nestedpara">This is a <b>paragraph</b> with <i>nested</i> tags.</p> | |
447 */}); | |
448 var node = $('nestedpara'); | |
449 var text = cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(node)); | |
450 assertEquals('This is a paragraph with nested tags.', text); | |
451 }); | |
452 | |
453 /** | |
454 * Test a paragraph with nested tags and varying visibility. | |
455 * @export | |
456 */ | |
457 TEST_F('CvoxDomUtilUnitTest', 'NestedVisibilityPara', function() { | |
458 this.loadDoc(function() {/*! | |
459 <style type="text/css"> | |
460 #nested_visibility_paragraph { } | |
461 #nested_visibility_paragraph .hide { visibility: hidden; } | |
462 #nested_visibility_paragraph .show { visibility: visible; } | |
463 </style> | |
464 <p id="nested_visibility_paragraph"> | |
465 This is | |
466 <span class="hide"> | |
467 not | |
468 <span class="show"> a sentence.</span> | |
469 </span> | |
470 </p> | |
471 */}); | |
472 var node = $('nested_visibility_paragraph'); | |
473 var text = cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(node)); | |
474 assertEquals('This is a sentence.', text); | |
475 }); | |
476 | |
477 /** Test getting text from an IMG node. @export */ | |
478 TEST_F('CvoxDomUtilUnitTest', 'Image', function() { | |
479 this.loadDoc(function() {/*! | |
480 <img id="img"> | |
481 <img id="img_noalt" src="rose.png"> | |
482 <img id="img_alt" alt="flower" src="rose.png"> | |
483 <img id="img_title" title="a Flower" src="rose.png"> | |
484 <img id="img_noalt_long" | |
485 src="777777777777777777777777777777777.png"> | |
486 */}); | |
487 | |
488 var node = $('img'); | |
489 assertEquals('Image', cvox.DomUtil.getName(node)); | |
490 node = $('img_noalt'); | |
491 assertEquals('rose Image', cvox.DomUtil.getName(node)); | |
492 node = $('img_alt'); | |
493 assertEquals('flower', cvox.DomUtil.getName(node)); | |
494 node = $('img_title'); | |
495 assertEquals('a Flower', cvox.DomUtil.getName(node)); | |
496 node = $('img_noalt_long'); | |
497 assertEquals('Image', cvox.DomUtil.getName(node)); | |
498 }); | |
499 | |
500 /** Test getting text from a select box. @export */ | |
501 TEST_F('CvoxDomUtilUnitTest', 'Select', function() { | |
502 this.loadDoc(function() {/*! | |
503 <select id="select_noneselected"> | |
504 <option>Apple</option> | |
505 <option>Banana</option> | |
506 <option>Pear</option> | |
507 </select> | |
508 <select id="select_bananaselected"> | |
509 <option>Apple</option> | |
510 <option selected>Banana</option> | |
511 <option>Pear</option> | |
512 </select> | |
513 */}); | |
514 | |
515 $('select_noneselected').selectedIndex = -1; | |
516 var node = $('select_noneselected'); | |
517 assertEquals('', cvox.DomUtil.getValue(node)); | |
518 node = $('select_bananaselected'); | |
519 assertEquals('Banana', cvox.DomUtil.getValue(node)); | |
520 }); | |
521 | |
522 /** Test whether funky html causes getName to go into infinite loop. */ | |
523 TEST_F('CvoxDomUtilUnitTest', 'GetNameInfiniteLoop', function() { | |
524 this.loadDoc(function() {/*! | |
525 <div> | |
526 <label for="a"> | |
527 <p id="a">asdf</p> | |
528 </label> | |
529 </div> | |
530 */}); | |
531 // intentionally no asserts; if there is an infinite (recursive) loop, | |
532 // the stack will blow up | |
533 var node = $('a'); | |
534 var label = cvox.DomUtil.getName(node); | |
535 }); | |
536 | |
537 /** Test getting text from an INPUT control. @export */ | |
538 TEST_F('CvoxDomUtilUnitTest', 'Input', function() { | |
539 this.loadDoc(function() {/*! | |
540 <form action=""> | |
541 <input id="hidden" type="hidden" value="hidden1"> | |
542 <input id="input_img" type="image" src="rose.png"> | |
543 <input id="input_img_alt" type="image" alt="flower" src="rose.png"> | |
544 <input id="submit" type="submit"> | |
545 <input id="submit_withvalue" type="submit" value="Go"> | |
546 <input id="reset" type="reset"> | |
547 <input id="reset_withvalue" type="reset" value="Stop"> | |
548 <input id="button" type="button" value="Button"> | |
549 <input id="checkbox" type="checkbox" value="ignore1"> | |
550 <input id="checkbox_title" type="checkbox" value="ignore1" title="toggle"> | |
551 <input id="radio" type="radio" value="ignore2"> | |
552 <input id="password" type="password" value="dragon"> | |
553 <input id="text" value="my text"> | |
554 <input id="placeholder0" placeholder="Phone number"> | |
555 <input id="placeholder1" title="Phone number"> | |
556 <input id="placeholder2" title="Phone number" placeholder="xxx-yyy-zzzz"> | |
557 <input id="placeholder3" title="Phone number" placeholder="xxx-yyy-zzzz" | |
558 value="310-555-1212"> | |
559 </form> | |
560 */}); | |
561 | |
562 var node = $('hidden'); | |
563 assertEquals('', cvox.DomUtil.getName(node)); | |
564 node = $('input_img'); | |
565 assertEquals('rose Image', cvox.DomUtil.getName(node)); | |
566 node = $('input_img_alt'); | |
567 assertEquals('flower', cvox.DomUtil.getName(node)); | |
568 node = $('submit'); | |
569 assertEquals('Submit', cvox.DomUtil.getName(node)); | |
570 node = $('submit_withvalue'); | |
571 assertEquals('Go', cvox.DomUtil.getName(node)); | |
572 node = $('reset'); | |
573 assertEquals('Reset', cvox.DomUtil.getName(node)); | |
574 node = $('reset_withvalue'); | |
575 assertEquals('Stop', cvox.DomUtil.getName(node)); | |
576 node = $('button'); | |
577 assertEquals('Button', cvox.DomUtil.getName(node)); | |
578 node = $('checkbox'); | |
579 assertEquals('', cvox.DomUtil.getName(node)); | |
580 node = $('checkbox_title'); | |
581 assertEquals('toggle', cvox.DomUtil.getName(node)); | |
582 node = $('radio'); | |
583 assertEquals('', cvox.DomUtil.getName(node)); | |
584 node = $('password'); | |
585 assertEquals('dot dot dot dot dot dot ', cvox.DomUtil.getValue(node)); | |
586 node = $('text'); | |
587 assertEquals('my text', cvox.DomUtil.getValue(node)); | |
588 node = $('placeholder0'); | |
589 assertEquals('Phone number', cvox.DomUtil.getName(node)); | |
590 node = $('placeholder1'); | |
591 assertEquals('Phone number', cvox.DomUtil.getName(node)); | |
592 node = $('placeholder2'); | |
593 assertEquals('xxx-yyy-zzzz', | |
594 cvox.DomUtil.getName(node)); | |
595 node = $('placeholder3'); | |
596 assertEquals('310-555-1212 xxx-yyy-zzzz', | |
597 cvox.DomUtil.getValue(node) + ' ' + cvox.DomUtil.getName(node)); | |
598 }); | |
599 | |
600 | |
601 /** Test checking if something is a control. @export */ | |
602 TEST_F('CvoxDomUtilUnitTest', 'IsControl', function() { | |
603 this.loadDoc(function() {/*! | |
604 <table width="100%" border="0" cellpadding="0" cellspacing="0"> | |
605 <tbody> | |
606 <tr> | |
607 <td> </td> | |
608 | |
609 <td nowrap="nowrap"> | |
610 <table width="100%" border="0" cellpadding="0" cellspacing="0"> | |
611 <tbody> | |
612 <tr> | |
613 <td bgcolor="#3366CC"><img alt="" width="1" height="1"></td> | |
614 </tr> | |
615 </tbody> | |
616 </table> | |
617 | |
618 <table width="100%" border="0" cellpadding="0" cellspacing="0"> | |
619 <tbody> | |
620 <tr> | |
621 <td bgcolor="#E5ECF9" nowrap="nowrap"><font color="#000000" | |
622 face="arial,sans-serif" size="+1"><b> Preferences</b> | |
623 </font></td> | |
624 | |
625 <td align="right" bgcolor="#E5ECF9" nowrap="nowrap"> | |
626 <font color="#000000" face="arial,sans-serif" size="-1"> | |
627 <a href="http://www.google.com/accounts/ManageAccount">Google | |
628 Account settings</a> | <a href="http://www.google.com/"> | |
629 Preferences Help</a> | <a href="/about.html">About | |
630 Google</a> </font></td> | |
631 </tr> | |
632 </tbody> | |
633 </table> | |
634 </td> | |
635 </tr> | |
636 </tbody> | |
637 </table> | |
638 | |
639 <table width="100%" border="0" cellpadding="2" cellspacing="0"> | |
640 <tbody> | |
641 <tr bgcolor="#E5ECF9"> | |
642 <td><font face="arial,sans-serif" size="-1"><b>Save</b> your | |
643 preferences when finished and <b>return to search</b>.</font></td> | |
644 | |
645 <td align="right"><font face="arial,sans-serif" size="-1"> | |
646 <input value="Save Preferences " name="submit2" type="submit"> | |
647 </font></td> | |
648 </tr> | |
649 </tbody> | |
650 </table> | |
651 | |
652 <h1>Global Preferences</h1><font size="-1">(changes apply to all Google | |
653 services)</font><br> | |
654 | |
655 <table width="100%" border="0" cellpadding="0" cellspacing="0"> | |
656 <tbody> | |
657 <tr> | |
658 <td bgcolor="#CBDCED"><img alt="" width="1" height="2"></td> | |
659 </tr> | |
660 </tbody> | |
661 </table> | |
662 | |
663 <table width="100%" border="0" cellpadding="0" cellspacing="0"> | |
664 <tbody> | |
665 <tr> | |
666 <td width="1" bgcolor="#CBDCED"><img alt="" width="2" height="1"></td> | |
667 | |
668 <td valign="top" width="175" nowrap="nowrap"> | |
669 <br> | |
670 | |
671 | |
672 <h2>Interface Language</h2> | |
673 </td> | |
674 | |
675 <td colspan="2"><br> | |
676 <font face="arial,sans-serif" size="-1">Display Google tips and | |
677 messages in: <select name="hl"> | |
678 <option value="af"> | |
679 Afrikaans | |
680 </option> | |
681 | |
682 <option value="ak"> | |
683 Akan | |
684 </option> | |
685 | |
686 <option value="sq"> | |
687 Albanian | |
688 </option> | |
689 | |
690 <option value="am"> | |
691 Amharic | |
692 </option> | |
693 | |
694 <option value="ar"> | |
695 Arabic | |
696 </option> | |
697 </select><br> | |
698 If you do not find your native language in the pulldown above, you | |
699 can<br> | |
700 help Google create it through our | |
701 <a href="http://services.google.com/">Google in Your Language | |
702 program</a>.<br> | |
703 </font></td> | |
704 </tr> | |
705 </tbody> | |
706 </table> | |
707 | |
708 <table width="100%" border="0" cellpadding="0" cellspacing="0"> | |
709 <tbody> | |
710 <tr> | |
711 <td colspan="4" bgcolor="#CBDCED"><img alt="" width="1" height="1"></td> | |
712 </tr> | |
713 | |
714 <tr> | |
715 <td width="1" bgcolor="#CBDCED"><img alt="" width="2" height="1"></td> | |
716 | |
717 <td valign="top" width="175" nowrap="nowrap"> | |
718 <br> | |
719 | |
720 | |
721 <h2>Search Language</h2> | |
722 </td> | |
723 | |
724 <td> | |
725 <br> | |
726 <font face="arial,sans-serif" size="-1">Prefer pages written in these | |
727 language(s):</font><br> | |
728 | |
729 <table border="0" cellpadding="5" cellspacing="10"> | |
730 <tbody> | |
731 <tr> | |
732 <td valign="top" nowrap="nowrap"><font face="arial,sans-serif" | |
733 size="-1"><label><input name="lr" value="lang_af" | |
734 onclick="tick()" id="paf" type="checkbox"> | |
735 <span id="taf">Afrikaans</span></label><br> | |
736 <label><input name="lr" value="lang_ar" onclick="tick()" | |
737 id="par" type="checkbox"> <span id="tar">Arabic</span></label> | |
738 <br> | |
739 <label><input name="lr" value="lang_hy" onclick="tick()" | |
740 id="phy" type="checkbox"> <span id="thy">Armenian</span> | |
741 </label><br> | |
742 <label><input name="lr" value="lang_be" onclick="tick()" | |
743 id="pbe" type="checkbox"> <span id="tbe">Belarusian</span> | |
744 </label><br> | |
745 <label><input name="lr" value="lang_bg" onclick="tick()" | |
746 id="pbg" type="checkbox"> <span id="tbg">Bulgarian</span> | |
747 </label><br> | |
748 <label><input name="lr" value="lang_ca" onclick="tick()" | |
749 id="pca" type="checkbox"> <span id="tca">Catalan</span> | |
750 </label><br> | |
751 <label><input name="lr" value="lang_zh-CN" onclick="tick()" | |
752 id="pzh-CN" type="checkbox"> <span id="tzh-CN"> | |
753 Chinese (Simplified)</span></label><br> | |
754 <label><input name="lr" value="lang_zh-TW" onclick="tick()" | |
755 id="pzh-TW" type="checkbox"> <span id="tzh-TW"> | |
756 Chinese (Traditional)</span></label><br> | |
757 <label><input name="lr" value="lang_hr" onclick="tick()" | |
758 id="phr" type="checkbox"> <span id="thr">Croatian</span> | |
759 </label><br> | |
760 <label><input name="lr" value="lang_cs" onclick="tick()" | |
761 id="pcs" type="checkbox"> <span id="tcs">Czech</span> | |
762 </label><br> | |
763 <label><input name="lr" value="lang_da" onclick="tick()" | |
764 id="pda" type="checkbox"> <span id="tda">Danish</span> | |
765 </label><br> | |
766 <label><input name="lr" value="lang_nl" onclick="tick()" | |
767 id="pnl" type="checkbox"> <span id="tnl">Dutch</span> | |
768 </label></font></td> | |
769 </tr> | |
770 </tbody> | |
771 </table> | |
772 </td> | |
773 </tr> | |
774 </tbody> | |
775 </table><a name="loc" id="loc"></a> | |
776 | |
777 <table width="100%" border="0" cellpadding="0" cellspacing="0"> | |
778 <tbody> | |
779 <tr> | |
780 <td colspan="4" bgcolor="#CBDCED"><img alt="" width="1" height="1"></td> | |
781 </tr> | |
782 | |
783 <tr> | |
784 <td width="1" bgcolor="#CBDCED"><img alt="" width="2" height="1"></td> | |
785 | |
786 <td valign="top" width="175" nowrap="nowrap"> | |
787 <br> | |
788 | |
789 | |
790 <h2>Location</h2> | |
791 </td> | |
792 | |
793 <td> | |
794 <br> | |
795 | |
796 <div style="color: rgb(204, 0, 0); display: none;" id="locerr"> | |
797 <span id="lem"><font face="arial,sans-serif" size="-1">The location | |
798 <b>X</b> was not recognized.</font></span> | |
799 <font face="arial,sans-serif" size="-1"><br> | |
800 <br> | |
801 Suggestions:<br></font> | |
802 | |
803 <ul> | |
804 <li><font face="arial,sans-serif" size="-1">Make sure all street | |
805 and city names are spelled correctly.</font></li> | |
806 | |
807 <li><font face="arial,sans-serif" size="-1">Make sure the address | |
808 included a city and state.</font></li> | |
809 | |
810 <li><font face="arial,sans-serif" size="-1">Try entering a Zip | |
811 code.</font></li> | |
812 </ul> | |
813 </div> | |
814 | |
815 <div style="color: rgb(204, 0, 0); display: none;" id="locterr"> | |
816 <font face="arial,sans-serif" size="-1">Please enter a valid US | |
817 city or zip code<br> | |
818 <br></font> | |
819 </div> | |
820 | |
821 <div style="color: rgb(204, 0, 0); display: none;" id="locserr"> | |
822 <font face="arial,sans-serif" size="-1">Server error. Please try | |
823 again.<br> | |
824 <br></font> | |
825 </div><font face="arial,sans-serif" size="-1">Use as the default | |
826 location in Google Maps, customized search results, and other Google | |
827 products:<br> | |
828 <input name="uulo" value="1" type="hidden"><input name="muul" | |
829 value="4_20" type="hidden"><input name="luul" size="60" value="" | |
830 type="text"><br> | |
831 This location is saved on this computer. | |
832 <a href="/support/websearch/bin/answer.py?answer=35892&hl=en"> | |
833 Learn more</a><br> | |
834 <br></font> | |
835 </td> | |
836 </tr> | |
837 </tbody> | |
838 </table> | |
839 | |
840 <table width="100%" border="0" cellpadding="0" cellspacing="0"> | |
841 <tbody> | |
842 <tr> | |
843 <td colspan="4" bgcolor="#CBDCED"><img alt="" width="1" height="1"></td> | |
844 </tr> | |
845 | |
846 <tr> | |
847 <td rowspan="2" width="1" bgcolor="#CBDCED"> | |
848 <img alt="" width="2" height="1"></td> | |
849 | |
850 <td width="175" nowrap="nowrap"> | |
851 <br> | |
852 | |
853 <h2>SafeSearch Filtering</h2> | |
854 </td> | |
855 <td><br> | |
856 <font face="arial,sans-serif" size="-1"> | |
857 <a href="http://www.google.com/"> | |
858 Google's SafeSearch</a> blocks web pages containing explicit sexual | |
859 content from appearing in search results.</font></td> | |
860 </tr> | |
861 <tr valign="top"> | |
862 <td width="175" nowrap="nowrap"> </td> | |
863 <td> | |
864 <div style="margin-bottom: 1.2em; font: smaller arial,sans-serif;"> | |
865 <input id="stf" name="safeui" value="on" type="radio"> | |
866 <label for="stf">Use strict filtering (Filter both explicit | |
867 text and explicit images)</label><br> | |
868 <input id="modf" name="safeui" value="images" checked="checked" | |
869 type="radio"><label for="modf">Use moderate | |
870 filtering (Filter explicit images only - default | |
871 behavior)</label><br> | |
872 <input id="nof" name="safeui" value="off" type="radio"> | |
873 <label for="nof">Do not filter my search results</label> | |
874 </div> | |
875 <p style="margin-bottom: 1.2em; font-size: smaller;">This will apply | |
876 strict filtering to all searches from this computer using Firefox. | |
877 <a href="http://www.google.com/">Learn more</a></p> | |
878 </td> | |
879 </tr> | |
880 </tbody> | |
881 </table> | |
882 <table width="100%" border="0" cellpadding="0" cellspacing="0"> | |
883 <tbody> | |
884 <tr> | |
885 <td colspan="4" bgcolor="#CBDCED"><img alt="" width="1" height="1"></td> | |
886 </tr> | |
887 | |
888 <tr> | |
889 <td width="1" bgcolor="#CBDCED"><img alt="" width="2" height="1"></td> | |
890 | |
891 <td valign="top" width="175" nowrap="nowrap"> | |
892 <br> | |
893 | |
894 | |
895 <h2>Number of Results</h2> | |
896 </td> | |
897 | |
898 <td> <br> | |
899 <font face="arial,sans-serif" size="-1">Google's default (10 results) | |
900 provides the fastest results.<br> | |
901 Display <select name="num"> | |
902 <option value="10" selected="selected"> | |
903 10 | |
904 </option> | |
905 | |
906 <option value="20"> | |
907 20 | |
908 </option> | |
909 | |
910 <option value="30"> | |
911 30 | |
912 </option> | |
913 | |
914 <option value="50"> | |
915 50 | |
916 </option> | |
917 | |
918 <option value="100"> | |
919 100 | |
920 </option> | |
921 </select> results per page.<br> | |
922 </font></td> | |
923 </tr> | |
924 </tbody> | |
925 </table> | |
926 | |
927 <table width="100%" border="0" cellpadding="0" cellspacing="0"> | |
928 <tbody> | |
929 <tr> | |
930 <td colspan="4" bgcolor="#CBDCED"><img alt="" width="1" height="1"></td> | |
931 </tr> | |
932 | |
933 <tr> | |
934 <td width="1" bgcolor="#CBDCED"><img alt="" width="2" height="1"></td> | |
935 | |
936 <td valign="top" width="175" nowrap="nowrap"> | |
937 <br> | |
938 | |
939 | |
940 <h2>Results Window</h2><a name="safeui" id="safeui"> </a> | |
941 </td> | |
942 | |
943 <td> <br> | |
944 <font face="arial,sans-serif" size="-1"><input id="nwc" name="newwindow" | |
945 value="1" type="checkbox"> <label for="nwc">Open | |
946 search results in a new browser window.</label></font><br> | |
947 </td> | |
948 </tr> | |
949 </tbody> | |
950 </table> | |
951 | |
952 <table width="100%" border="0" cellpadding="0" cellspacing="0"> | |
953 <tbody> | |
954 <tr> | |
955 <td colspan="4" bgcolor="#CBDCED"><img alt="" width="1" height="1"></td> | |
956 </tr> | |
957 | |
958 <tr> | |
959 <td width="1" bgcolor="#CBDCED"><img alt="" width="2" height="1"></td> | |
960 | |
961 <td valign="top" width="175" nowrap="nowrap"> | |
962 <br> | |
963 | |
964 | |
965 <h2>Google Instant</h2> | |
966 </td> | |
967 | |
968 <td> <br> | |
969 <font face="arial,sans-serif" size="-1"><input id="suggon" name="suggon" | |
970 value="1" checked="checked" type="radio"><label for="suggon">Use Google | |
971 Instant predictions and results appear while typing</label><br> | |
972 <input id="suggmid" name="suggon" value="2" type="radio"> | |
973 <label for="suggmid">Do not use Google Instant</label><br> | |
974 <br> | |
975 Signed-in users can remove personalized predictions from their | |
976 <a href="/history">Web History</a>. <a href="http://www.google.com/"> | |
977 Learn more</a><br> | |
978 <br> | |
979 </font></td> | |
980 </tr> | |
981 | |
982 <tr> | |
983 <td colspan="4" bgcolor="#CBDCED"><img alt="" width="1" height="2"></td> | |
984 </tr> | |
985 </tbody> | |
986 </table><br> | |
987 */}); | |
988 var submitButton = document.getElementsByName('submit2')[0]; | |
989 assertEquals(true, cvox.DomUtil.isControl(submitButton)); | |
990 var selectControl = document.getElementsByName('hl')[0]; | |
991 assertEquals(true, cvox.DomUtil.isControl(selectControl)); | |
992 var checkbox = $('paf'); | |
993 assertEquals(true, cvox.DomUtil.isControl(checkbox)); | |
994 var textInput = document.getElementsByName('luul')[0]; | |
995 assertEquals(true, cvox.DomUtil.isControl(textInput)); | |
996 var radioButton = $('suggmid'); | |
997 assertEquals(true, cvox.DomUtil.isControl(radioButton)); | |
998 var h1Elem = document.getElementsByTagName('h1'); | |
999 assertEquals(false, cvox.DomUtil.isControl(h1Elem)); | |
1000 }); | |
1001 | |
1002 /** Test if something is an ARIA control. @export */ | |
1003 TEST_F('CvoxDomUtilUnitTest', 'IsAriaControl', function() { | |
1004 this.loadDoc(function() {/*! | |
1005 <li id="cb1" role="checkbox" tabindex="0" aria-checked="false" | |
1006 aria-describedby="cond desc1"> | |
1007 Lettuce | |
1008 </li> | |
1009 <li id="larger1" role="button" tabindex="0" aria-pressed="false" | |
1010 aria-labelledby="larger_label">+</li> | |
1011 <li id="r1" role="radio" tabindex="-1" aria-checked="false">Thai</li> | |
1012 <li id="treeitem1" role="treeitem" tabindex="-1">Oranges</li> | |
1013 */}); | |
1014 var checkbox = $('cb1'); | |
1015 assertEquals(true, cvox.DomUtil.isControl(checkbox)); | |
1016 var button = $('larger1'); | |
1017 assertEquals(true, cvox.DomUtil.isControl(button)); | |
1018 var radio = $('r1'); | |
1019 assertEquals(true, cvox.DomUtil.isControl(radio)); | |
1020 var treeitem = $('treeitem1'); | |
1021 assertEquals(false, cvox.DomUtil.isControl(treeitem)); | |
1022 }); | |
1023 | |
1024 /** Test if something is an focusable. @export */ | |
1025 TEST_F('CvoxDomUtilUnitTest', 'IsFocusable', function() { | |
1026 this.loadDoc(function() {/*! | |
1027 <a id="focus_link" href="#">Link</a> | |
1028 <a id="focus_anchor">Unfocusable anchor</a> | |
1029 <input id="focus_input" value="Input" /> | |
1030 <select id="focus_select"><option>Select</option></select> | |
1031 <button id="focus_button1">Button</button> | |
1032 <button id="focus_button2" tabindex="-1">Button 2</button> | |
1033 <button id="focus_button3" tabindex="0">Button 3</button> | |
1034 <button id="focus_button4" tabindex="1">Button 4</button> | |
1035 <div id="focus_div1">Div</div> | |
1036 <div id="focus_div2" tabindex="-1">Div 2</div> | |
1037 <div id="focus_div3" tabindex="0">Div 3</div> | |
1038 <div id="focus_div4" tabindex="1">Div 4</div> | |
1039 */}); | |
1040 var node; | |
1041 node = $('focus_link'); | |
1042 assertEquals(true, cvox.DomUtil.isFocusable(node)); | |
1043 node = $('focus_anchor'); | |
1044 assertEquals(false, cvox.DomUtil.isFocusable(node)); | |
1045 node = $('focus_input'); | |
1046 assertEquals(true, cvox.DomUtil.isFocusable(node)); | |
1047 node = $('focus_select'); | |
1048 assertEquals(true, cvox.DomUtil.isFocusable(node)); | |
1049 node = $('focus_button1'); | |
1050 assertEquals(true, cvox.DomUtil.isFocusable(node)); | |
1051 node = $('focus_button2'); | |
1052 assertEquals(true, cvox.DomUtil.isFocusable(node)); | |
1053 node = $('focus_button3'); | |
1054 assertEquals(true, cvox.DomUtil.isFocusable(node)); | |
1055 node = $('focus_button4'); | |
1056 assertEquals(true, cvox.DomUtil.isFocusable(node)); | |
1057 node = $('focus_div1'); | |
1058 assertEquals(false, cvox.DomUtil.isFocusable(node)); | |
1059 node = $('focus_div2'); | |
1060 assertEquals(true, cvox.DomUtil.isFocusable(node)); | |
1061 node = $('focus_div3'); | |
1062 assertEquals(true, cvox.DomUtil.isFocusable(node)); | |
1063 node = $('focus_div4'); | |
1064 assertEquals(true, cvox.DomUtil.isFocusable(node)); | |
1065 | |
1066 // Test it with null. | |
1067 assertEquals(false, cvox.DomUtil.isFocusable(null)); | |
1068 | |
1069 // Test it with something that's not an element. | |
1070 assertEquals(false, cvox.DomUtil.isFocusable(new Object())); | |
1071 | |
1072 // Test it with a Text node. | |
1073 node = $('focus_button1').firstChild; | |
1074 assertEquals(false, cvox.DomUtil.isFocusable(node)); | |
1075 }); | |
1076 | |
1077 /** Some additional tests for getName function. */ | |
1078 TEST_F('CvoxDomUtilUnitTest', 'GetName', function() { | |
1079 this.loadDoc(function() {/*! | |
1080 <span id="test-span" aria-labelledby="fake-id">Some text</span> | |
1081 <label id="label1">One</label> | |
1082 <label id="label3">Label</label> | |
1083 <div id="test-div" aria-labelledby="label1 label2 label3"></div> | |
1084 */}); | |
1085 var node = $('test-span'); | |
1086 // Makes sure we can deal with invalid ids in aria-labelledby. | |
1087 var text = cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(node)); | |
1088 assertEquals('Some text', text); | |
1089 node = $('test-div'); | |
1090 text = cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(node)); | |
1091 assertEquals('One Label', cvox.DomUtil.getName(node)); | |
1092 }); | |
1093 | |
1094 /** Test for getLinkURL. */ | |
1095 TEST_F('CvoxDomUtilUnitTest', 'GetLinkURL', function() { | |
1096 this.loadDoc(function() {/*! | |
1097 <a id="l1" name="nohref">Anchor</a> | |
1098 <a id="l2" href="">Empty link</a> | |
1099 <a id="l3" href="#">Link to self</a> | |
1100 <a id="l4" href="http://google.com">Google</a> | |
1101 <span id="l5" role="link" onClick="javascript:alert('?')">Something</span> | |
1102 <div id="l6" role="link">Div with link role</a> | |
1103 */}); | |
1104 var node = $('l1'); | |
1105 assertEquals('', cvox.DomUtil.getLinkURL(node)); | |
1106 node = $('l2'); | |
1107 assertEquals('', cvox.DomUtil.getLinkURL(node)); | |
1108 node = $('l3'); | |
1109 assertEquals('Internal link', cvox.DomUtil.getLinkURL(node)); | |
1110 node = $('l4'); | |
1111 assertEquals('http://google.com', cvox.DomUtil.getLinkURL(node)); | |
1112 node = $('l5'); | |
1113 assertEquals('Unknown link', cvox.DomUtil.getLinkURL(node)); | |
1114 node = $('l6'); | |
1115 assertEquals('Unknown link', cvox.DomUtil.getLinkURL(node)); | |
1116 }); | |
1117 | |
1118 /** Test for isDisabled. */ | |
1119 TEST_F('CvoxDomUtilUnitTest', 'IsDisabled', function() { | |
1120 this.loadDoc(function() {/*! | |
1121 <input id="button1" type="button" value="Press me!"/> | |
1122 <input id="button2" type="button" value="Don't touch me!" disabled/> | |
1123 */}); | |
1124 var node = $('button1'); | |
1125 assertEquals(false, cvox.DomUtil.isDisabled(node)); | |
1126 node = $('button2'); | |
1127 assertEquals(true, cvox.DomUtil.isDisabled(node)); | |
1128 }); | |
1129 | |
1130 /** Test for a tree with aria-expanded attribute. */ | |
1131 TEST_F('CvoxDomUtilUnitTest', 'Tree', function() { | |
1132 this.loadDoc(function() {/*! | |
1133 <div id=":0" role="tree" aria-selected="false" aria-expanded="true" | |
1134 aria-level="0" aria-labelledby=":0.label" tabindex="0" | |
1135 aria-activedescendant=":1"> | |
1136 <span id=":0.label">Countries</span> | |
1137 <div class="goog-tree-item" id=":1" role="treeitem" aria-selected="true" | |
1138 aria-expanded="false" aria-labelledby=":1.label" aria-level="1"> | |
1139 <span id=":1.label">A</span> | |
1140 </div> | |
1141 <div class="goog-tree-item" id=":2" role="treeitem" aria-selected="false" | |
1142 aria-expanded="false" aria-labelledby=":2.label" aria-level="1"> | |
1143 <span id=":2.label">B<span> | |
1144 </div> | |
1145 <div class="goog-tree-item" id=":3" role="treeitem" aria-selected="false" | |
1146 aria-expanded="true" aria-labelledby=":3.label" aria-level="1"> | |
1147 <span id=":3.label">C</span> | |
1148 <div class="goog-tree-children" role="group"> | |
1149 <div class="goog-tree-item" id=":3a" role="treeitem" | |
1150 aria-selected="false" aria-expanded="false" | |
1151 aria-labelledby=":3a.label" aria-level="2"> | |
1152 <span id=":3a.label">Chile</span> | |
1153 </div> | |
1154 <div class="goog-tree-item" id=":3b" role="treeitem" | |
1155 aria-selected="false" aria-expanded="false" | |
1156 aria-labelledby=":3b.label" aria-level="2"> | |
1157 <span id=":3b.label">China</span> | |
1158 </div> | |
1159 <div class="goog-tree-item" id=":3c" role="treeitem" | |
1160 aria-selected="false" aria-expanded="false" | |
1161 aria-labelledby=":3c.label" aria-level="2"> | |
1162 <span id=":3c.label">Christmas Island</span> | |
1163 </div> | |
1164 <div class="goog-tree-item" id=":3d" role="treeitem" | |
1165 aria-selected="false" aria-expanded="false" | |
1166 aria-labelledby=":3d.label" aria-level="2"> | |
1167 <span id=":3d.label">Cocos (Keeling) Islands</span> | |
1168 </div> | |
1169 </div> | |
1170 </div> | |
1171 </div> | |
1172 */}); | |
1173 var node = $(':0'); | |
1174 assertEquals('A Collapsed Selected 1 of 3', | |
1175 cvox.DomUtil.getControlValueAndStateString(node)); | |
1176 node = $(':1'); | |
1177 assertEquals('A Collapsed Selected 1 of 3', | |
1178 cvox.DomUtil.getControlValueAndStateString(node)); | |
1179 node = $(':2'); | |
1180 assertEquals('B Collapsed Not selected 2 of 3', | |
1181 cvox.DomUtil.getControlValueAndStateString(node)); | |
1182 node = $(':3'); | |
1183 assertEquals('C Expanded Not selected 3 of 3', | |
1184 cvox.DomUtil.getControlValueAndStateString(node)); | |
1185 node = $(':3b'); | |
1186 assertEquals('China Collapsed Not selected 2 of 4', | |
1187 cvox.DomUtil.getControlValueAndStateString(node)); | |
1188 }); | |
1189 | |
1190 /** Test for tables with different border specifications */ | |
1191 TEST_F('CvoxDomUtilUnitTest', 'TableBorders', function() { | |
1192 this.loadDoc(function() {/*! | |
1193 <table id=":0" border="1"> | |
1194 <tr> | |
1195 <td>A</td> | |
1196 </tr> | |
1197 </table> | |
1198 <table id=":1" border="0"> | |
1199 <tr> | |
1200 <td>A</td> | |
1201 </tr> | |
1202 </table> | |
1203 <table id=":2" border="0px"> | |
1204 <tr> | |
1205 <td>A</td> | |
1206 </tr> | |
1207 </table> | |
1208 <table id=":3" frame="box"> | |
1209 <tr> | |
1210 <td>A</td> | |
1211 </tr> | |
1212 </table> | |
1213 <table id=":4" frame="void"> | |
1214 <tr> | |
1215 <td>A</td> | |
1216 </tr> | |
1217 </table> | |
1218 <table id=":5" style="border-width: medium"> | |
1219 <tr> | |
1220 <td>A</td> | |
1221 </tr> | |
1222 </table> | |
1223 <table id=":6" style="border-width: medium; border-style: none"> | |
1224 <tr> | |
1225 <td>A</td> | |
1226 </tr> | |
1227 </table> | |
1228 <table id=":7" style="border-color: red"> | |
1229 <tr> | |
1230 <td>A</td> | |
1231 </tr> | |
1232 </table> | |
1233 <table id=":8" style="border-style: dotted; border-width: 0px"> | |
1234 <tr> | |
1235 <td>A</td> | |
1236 </tr> | |
1237 </table> | |
1238 <table id=":9" style="border-width: 0px"> | |
1239 <tr> | |
1240 <td>A</td> | |
1241 </tr> | |
1242 </table> | |
1243 <table id=":10" style="border: 0px"> | |
1244 <tr> | |
1245 <td>A</td> | |
1246 </tr> | |
1247 </table> | |
1248 <table id=":11" style="border: 0"> | |
1249 <tr> | |
1250 <td>A</td> | |
1251 </tr> | |
1252 </table> | |
1253 */}); | |
1254 var node = $(':0'); | |
1255 assertTrue(cvox.DomUtil.hasBorder(node)); | |
1256 | |
1257 node = $(':1'); | |
1258 assertFalse(cvox.DomUtil.hasBorder(node)); | |
1259 | |
1260 node = $(':2'); | |
1261 assertFalse(cvox.DomUtil.hasBorder(node)); | |
1262 | |
1263 node = $(':3'); | |
1264 assertTrue(cvox.DomUtil.hasBorder(node)); | |
1265 | |
1266 node = $(':4'); | |
1267 assertFalse(cvox.DomUtil.hasBorder(node)); | |
1268 | |
1269 node = $(':5'); | |
1270 assertTrue(cvox.DomUtil.hasBorder(node)); | |
1271 | |
1272 node = $(':6'); | |
1273 assertFalse(cvox.DomUtil.hasBorder(node)); | |
1274 | |
1275 node = $(':7'); | |
1276 assertTrue(cvox.DomUtil.hasBorder(node)); | |
1277 | |
1278 node = $(':8'); | |
1279 assertFalse(cvox.DomUtil.hasBorder(node)); | |
1280 | |
1281 node = $(':9'); | |
1282 assertFalse(cvox.DomUtil.hasBorder(node)); | |
1283 | |
1284 node = $(':10'); | |
1285 assertFalse(cvox.DomUtil.hasBorder(node)); | |
1286 | |
1287 node = $(':11'); | |
1288 assertFalse(cvox.DomUtil.hasBorder(node)); | |
1289 }); | |
1290 | |
1291 /** Tests for shallowChildlessClone */ | |
1292 TEST_F('CvoxDomUtilUnitTest', 'ShallowChildlessClone', function() { | |
1293 this.loadDoc(function() {/*! | |
1294 <div id='simple'>asdf</div> | |
1295 <div id='expectedSimpleClone'>asdf</div> | |
1296 <div id='oneLevel'><div>asdf</div></div> | |
1297 <div id='expectedOneLevelClone'><div></div></div> | |
1298 <div id='withAttrs'><div class="asdf">asdf</div></div> | |
1299 <div id='expectedWithAttrsClone'><div class="asdf"></div></div> | |
1300 */}); | |
1301 | |
1302 var simple = $('simple').firstChild; | |
1303 var expectedSimpleClone = $('expectedSimpleClone').firstChild; | |
1304 var oneLevel = $('oneLevel').firstChild; | |
1305 var expectedOneLevelClone = $('expectedOneLevelClone').firstChild; | |
1306 var withAttrs = $('withAttrs').firstChild; | |
1307 var expectedWithAttrsClone = $('expectedWithAttrsClone').firstChild; | |
1308 | |
1309 var simpleClone = cvox.DomUtil.shallowChildlessClone(simple); | |
1310 this.assertEqualsAsText_(simpleClone, expectedSimpleClone); | |
1311 | |
1312 var oneLevelClone = cvox.DomUtil.shallowChildlessClone(oneLevel); | |
1313 this.assertEqualsAsText_(oneLevelClone, expectedOneLevelClone); | |
1314 | |
1315 var withAttrsClone = cvox.DomUtil.shallowChildlessClone(withAttrs); | |
1316 this.assertEqualsAsText_(withAttrsClone, expectedWithAttrsClone); | |
1317 }); | |
1318 | |
1319 /** Tests for deepClone */ | |
1320 TEST_F('CvoxDomUtilUnitTest', 'DeepClone', function() { | |
1321 this.loadDoc(function() {/*! | |
1322 <div id='simple'>asdf</div> | |
1323 */}); | |
1324 var simpleClone = cvox.DomUtil.deepClone($('simple')); | |
1325 this.assertEqualsAsText_(simpleClone, $('simple')); | |
1326 | |
1327 this.loadDoc(function() {/*! | |
1328 <div id="withAttrs" class="asdf">asdf</div> | |
1329 */}); | |
1330 var withAttrsClone = cvox.DomUtil.deepClone($('withAttrs')); | |
1331 this.assertEqualsAsText_(withAttrsClone, $('withAttrs')); | |
1332 }); | |
1333 | |
1334 /** Tests for findNode */ | |
1335 TEST_F('CvoxDomUtilUnitTest', 'FindNode', function() { | |
1336 this.loadDoc(function() {/*! | |
1337 <div id="root"> | |
1338 <p id="a">a</p> | |
1339 <a href="#" id="b">b</a> | |
1340 </div> | |
1341 */}); | |
1342 var f = cvox.DomUtil.findNode; | |
1343 var node = f($('root'), function(n) {return n.id == 'b';}); | |
1344 assertEquals('b', node.id); | |
1345 }); | |
1346 | |
1347 /** Tests for getState for a list */ | |
1348 TEST_F('CvoxDomUtilUnitTest', 'ListLength', function() { | |
1349 this.loadDoc(function() {/*! | |
1350 <ul id="ul1"> | |
1351 <li>A | |
1352 <li>B | |
1353 <li>C | |
1354 </ul> | |
1355 <ul id="ul2"> | |
1356 <li aria-setsize="10">A | |
1357 <li aria-setsize="10">B | |
1358 <li aria-setsize="10">C | |
1359 </ul> | |
1360 */}); | |
1361 var ul1 = $('ul1'); | |
1362 assertEquals('with 3 items', | |
1363 cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getState(ul1))); | |
1364 | |
1365 var ul2 = $('ul2'); | |
1366 assertEquals('with 10 items', | |
1367 cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getState(ul2))); | |
1368 }); | |
1369 | |
1370 /** Tests for hasLongDesc */ | |
1371 TEST_F('CvoxDomUtilUnitTest', 'HasLongDesc', function() { | |
1372 this.loadDoc(function() {/*! | |
1373 <img id="img0" longdesc="desc.html" src="img0.jpg"></img> | |
1374 <img id="img1" src="img1.jpg"></img> | |
1375 */}); | |
1376 var img0 = $('img0'); | |
1377 assertEquals(true, cvox.DomUtil.hasLongDesc(img0)); | |
1378 | |
1379 var img1 = $('img1'); | |
1380 assertEquals(false, cvox.DomUtil.hasLongDesc(img1)); | |
1381 }); | |
1382 | |
1383 /** Tests for various link leaf types. */ | |
1384 TEST_F('CvoxDomUtilUnitTest', 'LinkLeaf', function() { | |
1385 this.loadDoc(function() {/*! | |
1386 <a id='leaf' href='google.com'><strong>Click</strong><div>here</div></a> | |
1387 <a id='non-leaf' href='google.com'>Click <h2>here</h2></a> | |
1388 */}); | |
1389 var leaf = $('leaf'); | |
1390 var nonLeaf = $('non-leaf'); | |
1391 assertTrue(cvox.DomUtil.isLeafNode(leaf)); | |
1392 assertFalse(cvox.DomUtil.isLeafNode(nonLeaf)); | |
1393 }); | |
1394 | |
1395 | |
1396 /** Test the value and state of a multiple select. */ | |
1397 TEST_F('CvoxDomUtilUnitTest', 'MultipleSelectValue', function() { | |
1398 this.loadDoc(function() {/*! | |
1399 <select id='cars' multiple> | |
1400 <option value="volvo">Volvo</option> | |
1401 <option value="saab">Saab</option> | |
1402 <option value="opel" selected>Opel</option> | |
1403 <option value="audi" selected>Audi</option> | |
1404 </select> | |
1405 */}); | |
1406 var cars = $('cars'); | |
1407 assertEquals('Opel to Audi', cvox.DomUtil.getValue(cars)); | |
1408 assertEquals('selected 2 items', cvox.DomUtil.getState(cars)); | |
1409 }); | |
1410 | |
1411 | |
1412 /** | |
1413 * Test correctness of elementToPoint. | |
1414 * | |
1415 * Absolute positioning of the container is used to avoid the window of the | |
1416 * browser being too small to contain the test elements. | |
1417 */ | |
1418 TEST_F('CvoxDomUtilUnitTest', 'ElementToPoint', function() { | |
1419 this.loadDoc(function() {/*! | |
1420 <div style="position: absolute; top: 0; left: 0"> | |
1421 <a id='one' href='#a'>First</a> | |
1422 <p id='two'>Some text</p> | |
1423 <ul><li id='three'>LI</li><li>LI2</li></ul> | |
1424 </div> | |
1425 */}); | |
1426 var one = $('one'); | |
1427 var two = $('two'); | |
1428 var three = $('three'); | |
1429 | |
1430 var oneHitPoint = cvox.DomUtil.elementToPoint(one); | |
1431 var twoHitPoint = cvox.DomUtil.elementToPoint(two); | |
1432 var threeHitPoint = cvox.DomUtil.elementToPoint(three); | |
1433 | |
1434 assertEquals(one, document.elementFromPoint(oneHitPoint.x, oneHitPoint.y)); | |
1435 assertEquals(two, document.elementFromPoint(twoHitPoint.x, twoHitPoint.y)); | |
1436 assertEquals(three, | |
1437 document.elementFromPoint(threeHitPoint.x, threeHitPoint.y)); | |
1438 }); | |
1439 | |
1440 /** Tests we compute the correct name for hidden aria labelledby nodes. */ | |
1441 TEST_F('CvoxDomUtilUnitTest', 'HiddenAriaLabelledby', function() { | |
1442 this.loadDoc(function() {/*! | |
1443 <span id="acc_name" style="display: none"> | |
1444 hello world! | |
1445 </span> | |
1446 <button id="button" aria-labelledby="acc_name"> | |
1447 */}); | |
1448 assertEquals('hello world!', | |
1449 cvox.DomUtil.getName($('button'))); | |
1450 }); | |
1451 | |
1452 /** Tests that we compute the correct state for accesskeys. */ | |
1453 TEST_F('CvoxDomUtilUnitTest', 'AccessKey', function() { | |
1454 this.loadDoc(function() {/*! | |
1455 <a id='accessKey' href="#f" title="Next page" accesskey="n">Next page</a> | |
1456 */}); | |
1457 var a = $('accessKey'); | |
1458 assertEquals('has access key, n', cvox.DomUtil.getState(a)); | |
1459 }); | |
1460 | |
1461 | |
1462 /** Tests that we compute the correct name for ordered listitems. */ | |
1463 TEST_F('CvoxDomUtilUnitTest', 'OrderedListitem', function() { | |
1464 this.loadDoc(function() {/*! | |
1465 <ol id="fruits_ol"> | |
1466 <li id='ol_li1'>apple | |
1467 <li id='ol_li2'>orange | |
1468 <li id='ol_li3'>strawberry | |
1469 <li id='ol_li4'>banana | |
1470 </ol> | |
1471 */}); | |
1472 var li1 = $('ol_li1'); | |
1473 var li2 = $('ol_li2'); | |
1474 var li3 = $('ol_li3'); | |
1475 var li4 = $('ol_li4'); | |
1476 // Note that whitespace processing happens at a higher layer | |
1477 // (DescriptionUtil). | |
1478 assertEquals('1. apple', | |
1479 cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(li1))); | |
1480 assertEquals('2. orange', | |
1481 cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(li2))); | |
1482 assertEquals('3. strawberry', | |
1483 cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(li3))); | |
1484 assertEquals('4. banana', | |
1485 cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(li4))); | |
1486 | |
1487 $('fruits_ol').style.listStyleType = 'lower-latin'; | |
1488 | |
1489 assertEquals('A. apple', | |
1490 cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(li1))); | |
1491 assertEquals('B. orange', | |
1492 cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(li2))); | |
1493 assertEquals('C. strawberry', | |
1494 cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(li3))); | |
1495 assertEquals('D. banana', | |
1496 cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(li4))); | |
1497 }); | |
1498 | |
1499 /** Tests a node with title, and textContent containing only whitespace. */ | |
1500 TEST_F('CvoxDomUtilUnitTest', 'TitleOverridesInnerWhitespace', function() { | |
1501 this.loadDoc(function() {/*! | |
1502 <button id="btn1" title="Remove from Chrome"> | |
1503 <span class="lid"></span> | |
1504 <span class="can"></span> | |
1505 </button> | |
1506 */}); | |
1507 var btn1 = $('btn1'); | |
1508 assertEquals('Remove from Chrome', cvox.DomUtil.getName(btn1)); | |
1509 }); | |
1510 | |
1511 /** Test memoization. **/ | |
1512 TEST_F('CvoxDomUtilUnitTest', 'Memoization', function() { | |
1513 this.loadDoc(function() {/*! | |
1514 <div id="container"> | |
1515 </div> | |
1516 */}); | |
1517 | |
1518 // Nest divs 100 levels deep. | |
1519 var container = $('container'); | |
1520 var outer = container; | |
1521 for (var i = 0; i < 100; i++) { | |
1522 var inner = document.createElement('div'); | |
1523 outer.appendChild(inner); | |
1524 outer = inner; | |
1525 } | |
1526 var target = document.createElement('p'); | |
1527 target.innerHTML = 'Text'; | |
1528 outer.appendChild(target); | |
1529 | |
1530 var iterations = 200; | |
1531 | |
1532 function logTime(msg, fn) { | |
1533 var t0 = new Date(); | |
1534 fn(); | |
1535 console.log(msg + ' elapsed time: ' + (new Date() - t0) + ' ms'); | |
1536 } | |
1537 | |
1538 // First, test without memoization. | |
1539 logTime('No memoization', function() { | |
1540 container.style.visibility = 'hidden'; | |
1541 for (var i = 0; i < iterations; i++) { | |
1542 assertFalse(cvox.DomUtil.isVisible(target)); | |
1543 } | |
1544 container.style.visibility = 'visible'; | |
1545 for (var i = 0; i < iterations; i++) { | |
1546 assertTrue(cvox.DomUtil.isVisible(target)); | |
1547 } | |
1548 }); | |
1549 | |
1550 // Now test with memoization enabled. | |
1551 logTime('With memoization', function() { | |
1552 cvox.Memoize.scope(function() { | |
1553 container.style.visibility = 'hidden'; | |
1554 for (var i = 0; i < iterations; i++) { | |
1555 assertFalse(cvox.DomUtil.isVisible(target)); | |
1556 } | |
1557 }); | |
1558 cvox.Memoize.scope(function() { | |
1559 container.style.visibility = 'visible'; | |
1560 for (var i = 0; i < iterations; i++) { | |
1561 assertTrue(cvox.DomUtil.isVisible(target)); | |
1562 } | |
1563 }); | |
1564 }); | |
1565 | |
1566 // Finally as a sanity check that things are being memoized, turn on | |
1567 // memoization and show that we get the wrong result if we change the | |
1568 // DOM and call isVisible again. | |
1569 cvox.Memoize.scope(function() { | |
1570 container.style.visibility = 'hidden'; | |
1571 assertFalse(cvox.DomUtil.isVisible(target)); | |
1572 | |
1573 container.style.visibility = 'visible'; | |
1574 // This should be true! It will return the wrong answer because | |
1575 // we're deliberately leaving memoization on while modifying the DOM. | |
1576 assertFalse(cvox.DomUtil.isVisible(target)); | |
1577 }); | |
1578 }); | |
OLD | NEW |