1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.javascript.host.dom;
16
17 import org.htmlunit.WebDriverTestCase;
18 import org.htmlunit.junit.BrowserRunner;
19 import org.htmlunit.junit.annotation.Alerts;
20 import org.junit.Test;
21 import org.junit.runner.RunWith;
22
23
24
25
26
27
28
29
30 @RunWith(BrowserRunner.class)
31 public class TreeWalkerTest extends WebDriverTestCase {
32 private static final String CONTENT_START = DOCTYPE_HTML
33 + "<html><head><title></title>\n"
34 + "<script>\n"
35 + LOG_TITLE_FUNCTION
36 + "function safeTagName(o) {\n"
37 + " return o ? o.tagName : undefined\n"
38 + "}\n"
39 + "function alertTreeWalker(tw) {\n"
40 + " log(safeTagName(tw.root));\n"
41 + " log(safeTagName(tw.currentNode));\n"
42 + " log(tw.whatToShow);\n"
43 + " log(tw.expandEntityReferences);\n"
44 + "}\n"
45 + "function test() {\n"
46 + " try {\n";
47
48 private static final String CONTENT_END = "\n } catch(e) { logEx(e) }\n"
49 + "\n}\n</script></head>\n"
50 + "<body onload='test()'>\n"
51 + "<div id='theDiv'>Hello, <span id='theSpan'>this is a test for"
52 + "<a id='theA' href='http://htmlunit.sf.net'>HtmlUnit</a> support"
53 + "</div>\n"
54 + "<p id='theP'>for TreeWalker's</p>\n"
55 + "</body></html>";
56
57 private void test(final String script) throws Exception {
58 final String html = CONTENT_START + script + CONTENT_END;
59
60 loadPageVerifyTitle2(html);
61 }
62
63 private static final String CONTENT_START2 =
64 "<html><head><title></title>\n"
65 + "<script>\n"
66 + LOG_TITLE_FUNCTION
67 + "function safeTagName(o) {\n"
68 + " return o ? o.tagName : undefined\n"
69 + "}\n"
70 + "function test() {\n"
71 + " try {\n";
72
73 private static final String CONTENT_END2 = "\n } catch(e) { logEx(e) }\n"
74 + "\n}\n</script></head>\n"
75 + "<body onload='test()'>\n"
76 + "<div id='theDiv'>Hello, <span id='theSpan'>this is a test for"
77 + "<a id='theA' href='http://htmlunit.sf.net'>HtmlUnit</a> support"
78 + "</div>\n"
79 + "<p id='theP'>for <br/>TreeWalkers<span>something</span>that is <a>important to me</a></p>\n"
80 + "<span>something <code>codey</code>goes <pre> here</pre></span>\n"
81 + "</body></html>";
82
83 private void test2(final String script) throws Exception {
84 final String html = CONTENT_START2 + script + CONTENT_END2;
85
86 loadPageVerifyTitle2(html);
87 }
88
89
90
91
92 @Test
93 @Alerts({"BODY", "BODY", "1", "undefined"})
94 public void getters1() throws Exception {
95 final String script = "var tw = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, null, false);"
96 + "alertTreeWalker(tw);";
97
98 test(script);
99 }
100
101
102
103
104 @Test
105 @Alerts({"A", "A", "4294967295", "undefined"})
106
107 public void getters2() throws Exception {
108 final String script = "var theA = document.getElementById('theA');\n"
109 + "var tw = document.createTreeWalker(theA, NodeFilter.SHOW_ALL, null, true);\n"
110 + "alertTreeWalker(tw);\n";
111
112 test(script);
113 }
114
115
116
117
118 @Test
119 @Alerts({"BODY", "DIV", "1", "undefined"})
120 public void firstChild() throws Exception {
121 final String script =
122 "var tw = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, null, true);\n"
123 + "tw.firstChild();\n"
124 + "alertTreeWalker(tw);\n";
125
126 test(script);
127 }
128
129
130
131
132 @Test
133 @Alerts({"BODY", "SPAN", "1", "undefined"})
134 public void firstChild2() throws Exception {
135 final String script =
136 "var tw = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, null, true);\n"
137 + "tw.currentNode = document.getElementById('theDiv');\n"
138 + "tw.firstChild();\n"
139 + "alertTreeWalker(tw);\n";
140
141 test(script);
142 }
143
144
145
146
147 @Test
148 @Alerts({"BODY", "P", "1", "undefined"})
149 public void lastChild() throws Exception {
150 final String script =
151 "var tw = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, null, true);\n"
152 + "tw.lastChild();\n"
153 + "alertTreeWalker(tw);\n";
154
155 test(script);
156 }
157
158
159
160
161 @Test
162 @Alerts({"BODY", "SPAN", "1", "undefined"})
163 public void lastChild2() throws Exception {
164 final String script =
165 "var tw = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, null, true);\n"
166 + "tw.currentNode = document.getElementById('theDiv');\n"
167 + "tw.lastChild();\n"
168 + "alertTreeWalker(tw);\n";
169
170 test(script);
171 }
172
173
174
175
176 @Test
177 @Alerts({"BODY", "BODY", "1", "undefined", "null"})
178 public void parentNode() throws Exception {
179 final String script =
180 "var tw = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, null, true);\n"
181 + "tw.currentNode = document.getElementById('theDiv');\n"
182 + "tw.parentNode();\n"
183 + "alertTreeWalker(tw);\n"
184 + "log(tw.parentNode());";
185
186 test(script);
187 }
188
189
190
191
192 @Test
193 @Alerts({"BODY", "DIV", "1", "undefined"})
194 public void parentNode2() throws Exception {
195 final String script =
196 "var tw = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, null, true);\n"
197 + "tw.currentNode = document.getElementById('theSpan');\n"
198 + "tw.parentNode();\n"
199 + "alertTreeWalker(tw);";
200
201 test(script);
202 }
203
204
205
206
207 @Test
208 @Alerts({"BODY", "P", "1", "undefined", "null"})
209 public void siblings() throws Exception {
210 final String script =
211 "var tw = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, null, true);\n"
212 + "tw.currentNode = document.getElementById('theDiv');\n"
213 + "tw.nextSibling();\n"
214 + "alertTreeWalker(tw);\n"
215 + "log(tw.nextSibling());\n";
216
217 test(script);
218 }
219
220
221
222
223 @Test
224 @Alerts({"BODY", "DIV", "1", "undefined", "null"})
225 public void siblings2() throws Exception {
226 final String script1 =
227 "var tw = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, null, true);\n"
228 + "tw.currentNode = document.getElementById('theP');\n"
229 + "tw.previousSibling();\n"
230 + "alertTreeWalker(tw);\n"
231 + "log(tw.previousSibling());\n";
232
233 test(script1);
234 }
235
236
237
238
239 @Test
240 @Alerts({"BODY", "DIV", "SPAN", "A", "P", "undefined", "P"})
241 public void next() throws Exception {
242 final String script =
243 "var tw = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, null, true);\n"
244 + "log(safeTagName(tw.currentNode));\n"
245 + "log(safeTagName(tw.nextNode()));\n"
246 + "log(safeTagName(tw.nextNode()));\n"
247 + "log(safeTagName(tw.nextNode()));\n"
248 + "log(safeTagName(tw.nextNode()));\n"
249 + "log(safeTagName(tw.nextNode()));\n"
250 + "log(safeTagName(tw.currentNode));\n";
251
252 test(script);
253 }
254
255
256
257
258 @Test
259 @Alerts({"P", "A", "SPAN", "DIV", "BODY", "undefined", "BODY"})
260 public void previous() throws Exception {
261 final String script =
262 "var tw = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, null, true);\n"
263 + "tw.currentNode = document.getElementById('theP');\n"
264 + "log(safeTagName(tw.currentNode));\n"
265 + "log(safeTagName(tw.previousNode()));\n"
266 + "log(safeTagName(tw.previousNode()));\n"
267 + "log(safeTagName(tw.previousNode()));\n"
268 + "log(safeTagName(tw.previousNode()));\n"
269 + "log(safeTagName(tw.previousNode()));\n"
270 + "log(safeTagName(tw.currentNode));\n";
271
272 test(script);
273 }
274
275
276
277
278 @Test
279 @Alerts({"DIV", "SPAN", "A", "undefined", "P", "BODY", "undefined", "SPAN", "undefined",
280 "P", "SPAN", "CODE", "PRE", "undefined"})
281 public void walking() throws Exception {
282 final String script = "var tw = document.createTreeWalker(document.body, 1, null, true);\n"
283 + "log(safeTagName(tw.firstChild()));\n"
284 + "log(safeTagName(tw.firstChild()));\n"
285 + "log(safeTagName(tw.lastChild()));\n"
286 + "log(safeTagName(tw.lastChild()));\n"
287 + "log(safeTagName(tw.nextNode()));\n"
288 + "log(safeTagName(tw.parentNode()));\n"
289 + "log(safeTagName(tw.parentNode()));\n"
290 + "log(safeTagName(tw.lastChild()));\n"
291 + "log(safeTagName(tw.nextSibling()));\n"
292 + "log(safeTagName(tw.previousSibling()));\n"
293 + "log(safeTagName(tw.nextSibling()));\n"
294 + "log(safeTagName(tw.nextNode()));\n"
295 + "log(safeTagName(tw.nextNode()));\n"
296 + "log(safeTagName(tw.nextNode()));\n";
297
298 test2(script);
299 }
300
301
302
303
304 @Test
305 @Alerts({"TITLE", "SCRIPT", "HEAD", "HTML", "HEAD", "BODY", "undefined"})
306 public void walkingOutsideTheRoot() throws Exception {
307 final String script =
308 "var tw = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, null, true);\n"
309 + "tw.currentNode = document.firstChild.firstChild;\n"
310 + "log(safeTagName(tw.firstChild()));\n"
311 + "log(safeTagName(tw.nextNode()));\n"
312 + "log(safeTagName(tw.parentNode()));\n"
313 + "log(safeTagName(tw.previousNode()));\n"
314 + "log(safeTagName(tw.firstChild()));\n"
315 + "log(safeTagName(tw.nextSibling()));\n"
316 + "log(safeTagName(tw.previousSibling()));\n";
317
318 test2(script);
319 }
320
321
322
323
324 @Test
325 @Alerts("TypeError")
326 public void nullRoot() throws Exception {
327 final String script = "try {\n"
328 + "var tw = document.createTreeWalker(null, NodeFilter.SHOW_ELEMENT, null, true);\n"
329 + "} catch(e) { logEx(e); }\n";
330
331 test2(script);
332 }
333
334
335
336
337 @Test
338 @Alerts({"TITLE", "undefined", "HEAD", "HTML", "HEAD", "BODY", "undefined"})
339 public void simpleFilter() throws Exception {
340 final String script = "var noScripts = {\n"
341 + " acceptNode: function(node) {\n"
342 + " if (node.tagName == 'SCRIPT')\n"
343 + " return NodeFilter.FILTER_REJECT;\n"
344
345 + " return 1; // NodeFilter.FILTER_ACCEPT \n"
346 + " }\n"
347 + "}\n"
348 + "var tw = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, noScripts, true);\n"
349 + "tw.currentNode = document.firstChild.firstChild;\n"
350 + "log(safeTagName(tw.firstChild()));\n"
351 + "log(safeTagName(tw.nextSibling()));\n"
352 + "log(safeTagName(tw.parentNode()));\n"
353 + "log(safeTagName(tw.previousNode()));\n"
354 + "log(safeTagName(tw.firstChild()));\n"
355 + "log(safeTagName(tw.nextSibling()));\n"
356 + "log(safeTagName(tw.previousSibling()));\n";
357
358 test2(script);
359 }
360
361
362
363
364 @Test
365 @Alerts({"TITLE", "undefined", "HEAD", "HTML", "HEAD", "BODY", "undefined"})
366 public void simpleFilter_asAFunction() throws Exception {
367 final String script = "var noScripts = function(node) {\n"
368 + " if (node.tagName == 'SCRIPT')\n"
369 + " return NodeFilter.FILTER_REJECT;\n"
370 + " return 1;\n"
371 + "}\n"
372 + "var tw = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, noScripts, true);\n"
373 + "tw.currentNode = document.firstChild.firstChild;\n"
374 + "log(safeTagName(tw.firstChild()));\n"
375 + "log(safeTagName(tw.nextSibling()));\n"
376 + "log(safeTagName(tw.parentNode()));\n"
377 + "log(safeTagName(tw.previousNode()));\n"
378 + "log(safeTagName(tw.firstChild()));\n"
379 + "log(safeTagName(tw.nextSibling()));\n"
380 + "log(safeTagName(tw.previousSibling()));\n";
381
382 test2(script);
383 }
384
385
386
387
388 @Test
389 @Alerts("TypeError")
390 public void emptyFilter() throws Exception {
391 final String script = "try {\n"
392 + "var tw = document.createTreeWalker(null, NodeFilter.SHOW_ELEMENT, {}, true);\n"
393 + "} catch(e) { logEx(e); }\n";
394
395 test2(script);
396 }
397
398
399
400
401 @Test
402 @Alerts({"P", "undefined"})
403 public void secondFilterReject() throws Exception {
404 final String script = ""
405 + "var noScripts = {\n"
406 + " acceptNode: function(node) {\n"
407 + " if (node.tagName == 'SPAN' || node.tagName == 'DIV') {\n"
408 + " return NodeFilter.FILTER_REJECT;\n"
409 + " }\n"
410 + " return NodeFilter.FILTER_ACCEPT;\n"
411 + " }\n"
412 + "}\n"
413 + "var tw = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, noScripts, true);\n"
414 + "log(safeTagName(tw.firstChild()));\n"
415 + "log(safeTagName(tw.nextSibling()));\n";
416
417 test2(script);
418 }
419
420
421
422
423 @Test
424 @Alerts({"A", "P", "CODE", "PRE", "undefined"})
425 public void secondFilterSkip() throws Exception {
426 final String script = "var noScripts = {acceptNode: function(node) {if (node.tagName == 'SPAN' ||"
427 + "node.tagName == 'DIV') return NodeFilter.FILTER_SKIP;"
428 + "return NodeFilter.FILTER_ACCEPT}};\n"
429 + "var tw = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, noScripts, true);\n"
430 + "log(safeTagName(tw.firstChild()));\n"
431 + "log(safeTagName(tw.nextSibling()));\n"
432 + "log(safeTagName(tw.nextSibling()));\n"
433 + "log(safeTagName(tw.nextSibling()));\n"
434 + "log(safeTagName(tw.nextSibling()));\n";
435
436 test2(script);
437 }
438
439
440
441
442 @Test
443 @Alerts({"P", "undefined"})
444 public void secondFilterRejectReverse() throws Exception {
445 final String script = "var noScripts = {acceptNode: function(node) {if (node.tagName == 'SPAN' ||"
446 + "node.tagName == 'DIV') return NodeFilter.FILTER_REJECT;"
447 + "return NodeFilter.FILTER_ACCEPT}};\n"
448 + "var tw = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, noScripts, true);\n"
449 + "log(safeTagName(tw.lastChild()));\n"
450 + "log(safeTagName(tw.previousSibling()));\n";
451
452 test2(script);
453 }
454
455
456
457
458 @Test
459 @Alerts({"PRE", "CODE", "P", "A", "undefined"})
460 public void secondFilterSkipReverse() throws Exception {
461 final String script = "var noScripts = {acceptNode: function(node) {if (node.tagName == 'SPAN' ||"
462 + "node.tagName == 'DIV') return NodeFilter.FILTER_SKIP; return NodeFilter.FILTER_ACCEPT}};\n"
463 + "var tw = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, noScripts, true);\n"
464 + "log(safeTagName(tw.lastChild()));\n"
465 + "log(safeTagName(tw.previousSibling()));\n"
466 + "log(safeTagName(tw.previousSibling()));\n"
467 + "log(safeTagName(tw.previousSibling()));\n"
468 + "log(safeTagName(tw.previousSibling()));";
469
470 test2(script);
471 }
472 }