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
31 @RunWith(BrowserRunner.class)
32 public class XPathResultTest extends WebDriverTestCase {
33
34
35
36
37 @Test
38 @Alerts({"function", "TypeError"})
39 public void ctor() throws Exception {
40 final String html = DOCTYPE_HTML
41 + "<html>\n"
42 + "<head>\n"
43 + " <script>\n"
44 + LOG_TEXTAREA_FUNCTION
45
46 + " function test() {\n"
47 + " if (!('XPathResult' in window)) {\n"
48 + " log('XPathResult not available');\n"
49 + " return;\n"
50 + " }\n"
51
52 + " try {\n"
53 + " log(typeof XPathResult);\n"
54 + " new XPathResult();\n"
55 + " } catch(e) { logEx(e); }\n"
56 + " }\n"
57 + " </script>\n"
58 + "</head>\n"
59 + "<body onload='test()'>\n"
60 + LOG_TEXTAREA
61 + "</body>\n"
62 + "</html>";
63
64 loadPageVerifyTextArea2(html);
65 }
66
67
68
69
70 @Test
71 @Alerts({"4", "1", "3"})
72 public void resultType() throws Exception {
73 final String html = DOCTYPE_HTML
74 + "<html><head>\n"
75 + "<script>\n"
76 + LOG_TITLE_FUNCTION
77 + " function test() {\n"
78 + " if (document.evaluate && XPathResult) {\n"
79 + " try {\n"
80 + " var text='<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\\n';\n"
81 + " text += '<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://myNS\">\\n';\n"
82 + " text += ' <xsl:template match=\"/\">\\n';\n"
83 + " text += ' <html>\\n';\n"
84 + " text += ' <body>\\n';\n"
85 + " text += ' <div/>\\n';\n"
86 + " text += ' <div/>\\n';\n"
87 + " text += ' </body>\\n';\n"
88 + " text += ' </html>\\n';\n"
89 + " text += ' </xsl:template>\\n';\n"
90 + " text += '</xsl:stylesheet>';\n"
91 + " var parser = new DOMParser();\n"
92 + " var doc = parser.parseFromString(text, 'text/xml');\n"
93 + " var expressions = ['//div', 'count(//div)', 'count(//div) = 2'];\n"
94 + " for (var i = 0; i < expressions.length; i++) {\n"
95 + " var expression = expressions[i];\n"
96 + " var result = doc.evaluate(expression, doc.documentElement, null,"
97 + " XPathResult.ANY_TYPE, null);\n"
98 + " log(result.resultType);\n"
99 + " }\n"
100 + " } catch(e) { log(e); }\n"
101 + " } else {\n"
102 + " log('evaluate not supported');\n"
103 + " }\n"
104 + " }\n"
105 + "</script></head><body onload='test()'>\n"
106 + "</body></html>";
107
108 loadPageVerifyTitle2(html);
109 }
110
111
112
113
114 @Test
115 @Alerts({"7", "id1", "id2"})
116 public void snapshotType() throws Exception {
117 final String html = DOCTYPE_HTML
118 + "<html><head>\n"
119 + "<script>\n"
120 + LOG_TITLE_FUNCTION
121 + " function test() {\n"
122 + " if (document.evaluate && XPathResult) {\n"
123 + " try {\n"
124 + " var text='<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\\n';\n"
125 + " text += '<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://myNS\">\\n';\n"
126 + " text += ' <xsl:template match=\"/\">\\n';\n"
127 + " text += ' <html>\\n';\n"
128 + " text += ' <body>\\n';\n"
129 + " text += ' <div id=\\'id1\\'/>\\n';\n"
130 + " text += ' <div id=\\'id2\\'/>\\n';\n"
131 + " text += ' </body>\\n';\n"
132 + " text += ' </html>\\n';\n"
133 + " text += ' </xsl:template>\\n';\n"
134 + " text += '</xsl:stylesheet>';\n"
135 + " var parser=new DOMParser();\n"
136 + " var doc=parser.parseFromString(text,'text/xml');\n"
137 + " var result = doc.evaluate('//div', doc.documentElement, null,"
138 + " XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);\n"
139 + " log(result.resultType);\n"
140 + " for (var i = 0; i < result.snapshotLength; i++) {\n"
141 + " log(result.snapshotItem(i).getAttribute('id'));\n"
142 + " }\n"
143 + " } catch(e) { log(e); }\n"
144 + " } else {\n"
145 + " log('evaluate not supported');\n"
146 + " }\n"
147 + " }\n"
148 + "</script></head><body onload='test()'>\n"
149 + "</body></html>";
150
151 loadPageVerifyTitle2(html);
152 }
153
154
155
156
157 @Test
158 @Alerts({"9", "id1"})
159 public void singleNodeValue() throws Exception {
160 final String html = DOCTYPE_HTML
161 + "<html><head>\n"
162 + "<script>\n"
163 + LOG_TITLE_FUNCTION
164 + " function test() {\n"
165 + " if (document.evaluate && XPathResult) {\n"
166 + " try {\n"
167 + " var text='<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\\n';\n"
168 + " text += '<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://myNS\">\\n';\n"
169 + " text += ' <xsl:template match=\"/\">\\n';\n"
170 + " text += ' <html>\\n';\n"
171 + " text += ' <body>\\n';\n"
172 + " text += ' <div id=\\'id1\\'/>\\n';\n"
173 + " text += ' <div id=\\'id2\\'/>\\n';\n"
174 + " text += ' </body>\\n';\n"
175 + " text += ' </html>\\n';\n"
176 + " text += ' </xsl:template>\\n';\n"
177 + " text += '</xsl:stylesheet>';\n"
178 + " var parser=new DOMParser();\n"
179 + " var doc=parser.parseFromString(text,'text/xml');\n"
180 + " var result = doc.evaluate('//div', doc.documentElement, null,"
181 + " XPathResult.FIRST_ORDERED_NODE_TYPE, null);\n"
182 + " log(result.resultType);\n"
183 + " log(result.singleNodeValue.getAttribute('id'));\n"
184 + " } catch(e) { log(e); }\n"
185 + " } else {\n"
186 + " log('evaluate not supported');\n"
187 + " }\n"
188 + " }\n"
189 + "</script></head><body onload='test()'>\n"
190 + "</body></html>";
191
192 loadPageVerifyTitle2(html);
193 }
194
195
196
197
198 @Test
199 @Alerts({"id1", "id2"})
200 public void iterateNext() throws Exception {
201 final String html = DOCTYPE_HTML
202 + "<html><head>\n"
203 + "<script>\n"
204 + LOG_TITLE_FUNCTION
205 + " function test() {\n"
206 + " if (document.evaluate && XPathResult) {\n"
207 + " try {\n"
208 + " var text='<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\\n';\n"
209 + " text += '<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://myNS\">\\n';\n"
210 + " text += ' <xsl:template match=\"/\">\\n';\n"
211 + " text += ' <html>\\n';\n"
212 + " text += ' <body>\\n';\n"
213 + " text += ' <div id=\"id1\"/>\\n';\n"
214 + " text += ' <div id=\"id2\"/>\\n';\n"
215 + " text += ' </body>\\n';\n"
216 + " text += ' </html>\\n';\n"
217 + " text += ' </xsl:template>\\n';\n"
218 + " text += '</xsl:stylesheet>';\n"
219 + " var parser=new DOMParser();\n"
220 + " var doc=parser.parseFromString(text,'text/xml');\n"
221 + " var result = doc.evaluate('" + "//div" + "', doc.documentElement, "
222 + "null, XPathResult.ANY_TYPE, null);\n"
223
224 + " var thisNode = result.iterateNext();\n"
225 + " while (thisNode) {\n"
226 + " log(thisNode.getAttribute('id'));\n"
227 + " thisNode = result.iterateNext();\n"
228 + " }\n"
229 + " } catch(e) { log(e); }\n"
230 + " } else {\n"
231 + " log('evaluate not supported');\n"
232 + " }\n"
233 + " }\n"
234 + "</script></head><body onload='test()'>\n"
235 + "</body></html>";
236
237 loadPageVerifyTitle2(html);
238 }
239
240
241
242
243 @Test
244 @Alerts("7")
245 public void notOr() throws Exception {
246 final String html = DOCTYPE_HTML
247 + "<html><head>\n"
248 + "<script>\n"
249 + LOG_TITLE_FUNCTION
250 + " function test() {\n"
251 + " if (document.evaluate && XPathResult) {\n"
252 + " try {\n"
253 + " var expression = \".//*[@id='level1']/*[not(preceding-sibling::* or following-sibling::*)]\";\n"
254 + " var result = document.evaluate(expression, document, null, "
255 + "XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);\n"
256 + " log(result.resultType);\n"
257 + " } catch(e) { log(e); }\n"
258 + " } else {\n"
259 + " log('evaluate not supported');\n"
260 + " }\n"
261 + " }\n"
262 + "</script></head><body onload='test()'>\n"
263 + "</body></html>";
264
265 loadPageVerifyTitle2(html);
266 }
267
268
269
270
271 @Test
272 @Alerts({"bar", "foo", "foo"})
273 public void stringType() throws Exception {
274 final String html = DOCTYPE_HTML
275 + "<html><head><title attr=\"bar\">foo</title><script>\n"
276 + LOG_TEXTAREA_FUNCTION
277 + " function test() {\n"
278 + " if (document.evaluate && XPathResult) {\n"
279 + " try {\n"
280 + " var result = document.evaluate('//title/@attr', document, null, "
281 + "XPathResult.STRING_TYPE, null);\n"
282 + " log(result.stringValue);\n"
283 + " result = document.evaluate('//title', document, null, "
284 + "XPathResult.STRING_TYPE, null);\n"
285 + " log(result.stringValue);\n"
286 + " var result = document.evaluate('//title/text()', document, null, "
287 + "XPathResult.STRING_TYPE, null);\n"
288 + " log(result.stringValue);\n"
289 + " } catch(e) { log(e); }\n"
290 + " } else {\n"
291 + " log('evaluate not supported');\n"
292 + " }\n"
293 + "}\n"
294 + "</script></head><body onload='test()'>\n"
295 + LOG_TEXTAREA
296 + "</body></html>";
297
298 loadPageVerifyTextArea2(html);
299 }
300
301
302
303
304 @Test
305 @Alerts({"true", "true", "true", "true"})
306 public void numberType() throws Exception {
307 final String html = DOCTYPE_HTML
308 + "<html><head><title attr=\"1234\">4321.5</title><span>foo</span><script>\n"
309 + LOG_TEXTAREA_FUNCTION
310 + " function test() {\n"
311 + " if (document.evaluate && XPathResult) {\n"
312 + " try {\n"
313 + " var result = document.evaluate('//title/@attr', document, null, "
314 + "XPathResult.NUMBER_TYPE, null);\n"
315 + " log(result.numberValue === 1234);\n"
316 + " result = document.evaluate('//title', document, null, "
317 + "XPathResult.NUMBER_TYPE, null);\n"
318 + " log(result.numberValue === 4321.5);\n"
319 + " result = document.evaluate('//title/text()', document, null, "
320 + "XPathResult.NUMBER_TYPE, null);\n"
321 + " log(result.numberValue === 4321.5);\n"
322 + " result = document.evaluate('//span', document, null, "
323 + "XPathResult.NUMBER_TYPE, null);\n"
324 + " log(isNaN(result.numberValue));\n"
325 + " } catch(e) { log(e); }\n"
326 + " } else {\n"
327 + " log('evaluate not supported');\n"
328 + " }\n"
329 + " }\n"
330 + "</script></head><body onload='test()'>\n"
331 + LOG_TEXTAREA
332 + "</body></html>";
333
334 loadPageVerifyTextArea2(html);
335 }
336
337
338
339
340 @Test
341 @Alerts({"true", "true", "true", "true", "true", "true"})
342 public void booleanType() throws Exception {
343 final String html = DOCTYPE_HTML
344 + "<html>\n"
345 + "<head>\n"
346 + "<script>\n"
347 + LOG_TITLE_FUNCTION
348 + " function test() {\n"
349 + " if (document.evaluate && XPathResult) {\n"
350 + " try {\n"
351 + " var result = document.evaluate('//unknown', document, null, "
352 + "XPathResult.BOOLEAN_TYPE, null);\n"
353 + " log(result.booleanValue === false);\n"
354
355 + " var result = document.evaluate('//title', document, null, "
356 + "XPathResult.BOOLEAN_TYPE, null);\n"
357 + " log(result.booleanValue === true);\n"
358
359 + " result = document.evaluate('//div', document, null, "
360 + "XPathResult.BOOLEAN_TYPE, null);\n"
361 + " log(result.booleanValue === true);\n"
362 + " result = document.evaluate('//div/@attr', document, null, "
363 + "XPathResult.BOOLEAN_TYPE, null);\n"
364 + " log(result.booleanValue === true);\n"
365
366 + " result = document.evaluate('//span', document, null, "
367 + "XPathResult.BOOLEAN_TYPE, null);\n"
368 + " log(result.booleanValue === true);\n"
369 + " result = document.evaluate('//span/@attr', document, null, "
370 + "XPathResult.BOOLEAN_TYPE, null);\n"
371 + " log(result.booleanValue === true);\n"
372 + " } catch(e) { log(e); }\n"
373 + " } else {\n"
374 + " log('evaluate not supported');\n"
375 + " }\n"
376 + " }\n"
377 + "</script>\n"
378 + "</head>\n"
379 + "<body onload='test()'>\n"
380 + " <div attr=\"false\">false</span>\n"
381 + " <span attr=\"true\">true</span>\n"
382 + "</body></html>";
383
384 loadPageVerifyTitle2(html);
385 }
386
387
388
389
390 @Test
391 @Alerts({"4", "not boolean", "not number", "not string", "not node", "not length"})
392 public void emptySetTypeAny() throws Exception {
393 emptySetType("XPathResult.ANY_TYPE");
394 }
395
396
397
398
399 @Test
400 @Alerts({"1", "not boolean", "NaN", "not string", "not node", "not length"})
401 public void emptySetTypeNumber() throws Exception {
402 emptySetType("XPathResult.NUMBER_TYPE");
403 }
404
405
406
407
408 @Test
409 @Alerts({"2", "not boolean", "not number", "", "not node", "not length"})
410 public void emptySetTypeString() throws Exception {
411 emptySetType("XPathResult.STRING_TYPE");
412 }
413
414
415
416
417 @Test
418 @Alerts({"3", "false", "not number", "not string", "not node", "not length"})
419 public void emptySetTypeBoolean() throws Exception {
420 emptySetType("XPathResult.BOOLEAN_TYPE");
421 }
422
423
424
425
426 @Test
427 @Alerts({"4", "not boolean", "not number", "not string", "not node", "not length"})
428 public void emptySetTypeUnorderedNodeIterator() throws Exception {
429 emptySetType("XPathResult.UNORDERED_NODE_ITERATOR_TYPE");
430 }
431
432
433
434
435 @Test
436 @Alerts({"5", "not boolean", "not number", "not string", "not node", "not length"})
437 public void emptySetTypeOrderedNodeIterator() throws Exception {
438 emptySetType("XPathResult.ORDERED_NODE_ITERATOR_TYPE");
439 }
440
441
442
443
444 @Test
445 @Alerts({"6", "not boolean", "not number", "not string", "not node", "0"})
446 public void emptySetTypeUnorderedNodeSnapshot() throws Exception {
447 emptySetType("XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE");
448 }
449
450
451
452
453 @Test
454 @Alerts({"7", "not boolean", "not number", "not string", "not node", "0"})
455 public void emptySetTypeOrderedNodeSnapshot() throws Exception {
456 emptySetType("XPathResult.ORDERED_NODE_SNAPSHOT_TYPE");
457 }
458
459
460
461
462 @Test
463 @Alerts({"8", "not boolean", "not number", "not string", "null", "not length"})
464 public void emptySetTypeAnyOrderedNode() throws Exception {
465 emptySetType("XPathResult.ANY_UNORDERED_NODE_TYPE");
466 }
467
468
469
470
471 @Test
472 @Alerts({"9", "not boolean", "not number", "not string", "null", "not length"})
473 public void emptySetTypeFirstOrderedNode() throws Exception {
474 emptySetType("XPathResult.FIRST_ORDERED_NODE_TYPE");
475 }
476
477 private void emptySetType(final String type) throws Exception {
478 type("//unknown", type);
479 }
480
481
482
483
484 @Test
485 @Alerts({"3", "false", "not number", "not string", "not node", "not length"})
486 public void zeroTypeBoolean() throws Exception {
487 typeBoolean("0");
488 }
489
490
491
492
493 @Test
494 @Alerts({"3", "true", "not number", "not string", "not node", "not length"})
495 public void minusOneTypeBoolean() throws Exception {
496 typeBoolean("-1");
497 }
498
499
500
501
502 @Test
503 @Alerts({"3", "true", "not number", "not string", "not node", "not length"})
504 public void infTypeBoolean() throws Exception {
505 typeBoolean("1.0 div 0.0");
506 }
507
508
509
510
511 @Test
512 @Alerts({"3", "true", "not number", "not string", "not node", "not length"})
513 public void minusInfTypeBoolean() throws Exception {
514 typeBoolean("-1.0 div 0.0");
515 }
516
517
518
519
520 @Test
521 @Alerts({"3", "true", "not number", "not string", "not node", "not length"})
522 public void stringTypeBoolean() throws Exception {
523 typeBoolean("\"abc\"");
524 }
525
526
527
528
529 @Test
530 @Alerts({"3", "false", "not number", "not string", "not node", "not length"})
531 public void emptyStringTypeBoolean() throws Exception {
532 typeBoolean("\"\"");
533 }
534
535 private void typeBoolean(final String xpath) throws Exception {
536 type(xpath, "XPathResult.BOOLEAN_TYPE");
537 }
538
539
540
541
542 @Test
543 @Alerts({"1", "not boolean", "0", "not string", "not node", "not length"})
544 public void zeroTypeNumber() throws Exception {
545 typeNumber("0");
546 }
547
548
549
550
551 @Test
552 @Alerts({"1", "not boolean", "Infinity", "not string", "not node", "not length"})
553 public void infTypeNumber() throws Exception {
554 typeNumber("1.0 div 0.0");
555 }
556
557
558
559
560 @Test
561 @Alerts({"1", "not boolean", "-Infinity", "not string", "not node", "not length"})
562 public void minusInfTypeNumber() throws Exception {
563 typeNumber("-1.0 div 0.0");
564 }
565
566
567
568
569 @Test
570 @Alerts({"1", "not boolean", "NaN", "not string", "not node", "not length"})
571 public void stringTypeNumber() throws Exception {
572 typeNumber("\"abc\"");
573 }
574
575
576
577
578 @Test
579 @Alerts({"1", "not boolean", "123.4", "not string", "not node", "not length"})
580 public void numberStringTypeNumber() throws Exception {
581 typeNumber("\"123.4\"");
582 }
583
584
585
586
587 @Test
588 @Alerts({"3", "false", "not number", "not string", "not node", "not length"})
589 public void emptyStringTypeNumber() throws Exception {
590 typeBoolean("\"\"");
591 }
592
593
594
595
596 @Test
597 @Alerts({"1", "not boolean", "1", "not string", "not node", "not length"})
598 public void trueTypeNumber() throws Exception {
599 typeNumber("true()");
600 }
601
602
603
604
605 @Test
606 @Alerts({"1", "not boolean", "0", "not string", "not node", "not length"})
607 public void falseTypeNumber() throws Exception {
608 typeNumber("false()");
609 }
610
611 private void typeNumber(final String xpath) throws Exception {
612 type(xpath, "XPathResult.NUMBER_TYPE");
613 }
614
615 private void type(final String xpath, final String type) throws Exception {
616 final String html = DOCTYPE_HTML
617 + "<html>\n"
618 + "<head>\n"
619 + "<script>\n"
620 + LOG_TITLE_FUNCTION
621 + " function test() {\n"
622 + " if (document.evaluate && XPathResult) {\n"
623 + " try {\n"
624 + " var result = document.evaluate('" + xpath + "', document, null, "
625 + type + ", null);\n"
626 + " log(result.resultType);\n"
627 + " try {\n"
628 + " log(result.booleanValue);\n"
629 + " } catch(e) { log('not boolean'); }\n"
630
631 + " try {\n"
632 + " log(result.numberValue);\n"
633 + " } catch(e) { log('not number'); }\n"
634
635 + " try {\n"
636 + " log(result.stringValue);\n"
637 + " } catch(e) { log('not string'); }\n"
638
639 + " try {\n"
640 + " log(result.singleNodeValue);\n"
641 + " } catch(e) { log('not node'); }\n"
642
643 + " try {\n"
644 + " log(result.snapshotLength);\n"
645 + " } catch(e) { log('not length'); }\n"
646 + " } catch(e) { log(e); }\n"
647 + " } else {\n"
648 + " log('evaluate not supported');\n"
649 + " }\n"
650 + " }\n"
651 + "</script>\n"
652 + "</head>\n"
653 + "<body onload='test()'>\n"
654 + " <div attr=\"false\">false</span>\n"
655 + " <span attr=\"true\">true</span>\n"
656 + "</body></html>";
657
658 loadPageVerifyTitle2(html);
659 }
660 }