View Javadoc
1   /*
2    * Copyright (c) 2002-2025 Gargoyle Software Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * https://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
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   * Tests for {@link XPathResult}.
25   *
26   * @author Ahmed Ashour
27   * @author Marc Guillemot
28   * @author Chuck Dumont
29   * @author Ronald Brill
30   */
31  @RunWith(BrowserRunner.class)
32  public class XPathResultTest extends WebDriverTestCase {
33  
34      /**
35       * @throws Exception if the test fails
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       * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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      * @throws Exception if the test fails
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 }