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.css;
16  
17  import java.nio.charset.StandardCharsets;
18  
19  import org.htmlunit.WebDriverTestCase;
20  import org.htmlunit.junit.annotation.Alerts;
21  import org.htmlunit.util.UrlUtils;
22  import org.junit.jupiter.api.Test;
23  import org.openqa.selenium.WebDriver;
24  
25  /**
26   * Tests for CSS selectors.
27   *
28   * @author Ronald Brill
29   * @author Marc Guillemot
30   * @author Ahmed Ashour
31   * @author Frank Danek
32   */
33  public class CSSSelectorTest extends WebDriverTestCase {
34  
35      /**
36       * @throws Exception if an error occurs
37       */
38      @Test
39      @Alerts({"0", "0"})
40      public void querySelectorAll_nullUndefined() throws Exception {
41          final String html = DOCTYPE_HTML
42              + "<html><head>\n"
43              + "<script>\n"
44              + LOG_TITLE_FUNCTION
45              + "function test() {\n"
46              + "  log(document.querySelectorAll(null).length);\n"
47              + "  log(document.querySelectorAll(undefined).length);\n"
48              + "}\n"
49              + "</script></head>\n"
50              + "<body onload='test()'>\n"
51              + "<ul>\n"
52              + "  <li id='li1'></li>\n"
53              + "  <li id='li2'></li>\n"
54              + "  <li id='li3'></li>\n"
55              + "</ul>\n"
56              + "</body></html>";
57  
58          loadPageVerifyTitle2(html);
59      }
60  
61      /**
62       * @throws Exception if an error occurs
63       */
64      @Test
65      @Alerts({"SyntaxError/DOMException", "SyntaxError/DOMException"})
66      public void querySelectorAll_emptyString() throws Exception {
67          final String html = DOCTYPE_HTML
68              + "<html><head>\n"
69              + "<script>\n"
70              + LOG_TITLE_FUNCTION
71              + "function test() {\n"
72              + "  try {\n"
73              + "    log(document.querySelectorAll(''));\n"
74              + "  } catch(e) { logEx(e) }\n"
75              + "  try {\n"
76              + "    log(document.querySelectorAll('  '));\n"
77              + "  } catch(e) { logEx(e) }\n"
78              + "}\n"
79              + "</script></head>\n"
80              + "<body onload='test()'>\n"
81              + "<ul>\n"
82              + "  <li id='li1'></li>\n"
83              + "  <li id='li2'></li>\n"
84              + "  <li id='li3'></li>\n"
85              + "</ul>\n"
86              + "</body></html>";
87  
88          loadPageVerifyTitle2(html);
89      }
90  
91      /**
92       * Test for bug 1287.
93       *
94       * @throws Exception if an error occurs
95       */
96      @Test
97      @Alerts({"li2", "li1", "li2", "li1", "li3", "li1", "2", "li1", "li2"})
98      public void nth_child() throws Exception {
99          final String html = DOCTYPE_HTML
100             + "<html><head>\n"
101             + "<script>\n"
102             + LOG_TITLE_FUNCTION
103             + "function test() {\n"
104             + "  log(document.querySelectorAll('li:nth-child(2)')[0].id);\n"
105             + "  log(document.querySelectorAll('li:nth-child(n)')[0].id);\n"
106             + "  log(document.querySelectorAll('li:nth-child(2n)')[0].id);\n"
107             + "  log(document.querySelectorAll('li:nth-child(2n+1)')[0].id);\n"
108             + "  log(document.querySelectorAll('li:nth-child(2n+1)')[1].id);\n"
109             + "  log(document.querySelectorAll('li:nth-child(2n-1)')[0].id);\n"
110 
111             + "  log(document.querySelectorAll('li:nth-child(-n+2)').length);\n"
112             + "  log(document.querySelectorAll('li:nth-child(-n+2)')[0].id);\n"
113             + "  log(document.querySelectorAll('li:nth-child(-n+2)')[1].id);\n"
114             + "}\n"
115             + "</script></head>\n"
116             + "<body onload='test()'>\n"
117             + "<ul>\n"
118             + "  <li id='li1'></li>\n"
119             + "  <li id='li2'></li>\n"
120             + "  <li id='li3'></li>\n"
121             + "</ul>\n"
122             + "</body></html>";
123 
124         loadPageVerifyTitle2(html);
125     }
126 
127     /**
128      * @throws Exception if an error occurs
129      */
130     @Test
131     @Alerts({"1", "li2", "2", "li1", "li3"})
132     public void nth_child_even_odd() throws Exception {
133         final String html = DOCTYPE_HTML
134             + "<html><head>\n"
135             + "<script>\n"
136             + LOG_TITLE_FUNCTION
137             + "function test() {\n"
138             + "  log(document.querySelectorAll('li:nth-child(even)').length);\n"
139             + "  log(document.querySelectorAll('li:nth-child(eVen)')[0].id);\n"
140             + "  log(document.querySelectorAll('li:nth-child(odd)').length);\n"
141             + "  log(document.querySelectorAll('li:nth-child(OdD)')[0].id);\n"
142             + "  log(document.querySelectorAll('li:nth-child(ODD)')[1].id);\n"
143             + "}\n"
144             + "</script></head>\n"
145             + "<body onload='test()'>\n"
146             + "<ul>\n"
147             + "  <li id='li1'></li>\n"
148             + "  <li id='li2'></li>\n"
149             + "  <li id='li3'></li>\n"
150             + "</ul>\n"
151             + "</body></html>";
152 
153         loadPageVerifyTitle2(html);
154     }
155 
156     /**
157      * @throws Exception if an error occurs
158      */
159     @Test
160     @Alerts({"1", "[object HTMLBodyElement]", "1", "0"})
161     public void childSelector_html_body() throws Exception {
162         final String html = DOCTYPE_HTML
163             + "<html><head>\n"
164             + "<script>\n"
165             + LOG_TITLE_FUNCTION
166             + "function test() {\n"
167             + "  log(document.querySelectorAll('html > body').length);\n"
168             + "  log(document.querySelectorAll('html > body')[0]);\n"
169             + "  log(document.querySelectorAll('  \\t\\r\\n  html > body  \\t\\r\\n  ').length);\n"
170 
171             + "  elem = document.getElementById('root');\n"
172             + "  log(elem.querySelectorAll('html > body').length);\n"
173             + "}\n"
174             + "</script></head>\n"
175             + "<body onload='test()'>\n"
176             + "<div id='root'>\n"
177             + "</div>\n"
178             + "</body></html>";
179 
180         loadPageVerifyTitle2(html);
181     }
182 
183     /**
184      * @throws Exception if an error occurs
185      */
186     @Test
187     @Alerts("SyntaxError/DOMException")
188     public void nth_child_no_argument() throws Exception {
189         final String html = DOCTYPE_HTML
190             + "<html><head><script>\n"
191             + LOG_TITLE_FUNCTION
192             + "function test() {\n"
193             + "  try {\n"
194             + "    log(document.querySelectorAll('li:nth-child()'));\n"
195             + "  } catch(e) { logEx(e) }\n"
196             + "}\n"
197             + "</script></head>\n"
198             + "<body onload='test()'>\n"
199             + "<ul>\n"
200             + "  <li id='li1'></li>\n"
201             + "  <li id='li2'></li>\n"
202             + "  <li id='li3'></li>\n"
203             + "</ul>\n"
204             + "</body></html>";
205 
206         loadPageVerifyTitle2(html);
207     }
208 
209     /**
210      * @throws Exception if an error occurs
211      */
212     @Test
213     @Alerts({"li1", "li4", "li7", "li10"})
214     public void nth_child_equation() throws Exception {
215         final String html = DOCTYPE_HTML
216             + "<html><head><script>\n"
217             + LOG_TITLE_FUNCTION
218             + "function test() {\n"
219             + "  var list = document.querySelectorAll('li:nth-child(3n+1)');\n"
220             + "  for (var i = 0 ; i < list.length; i++) {\n"
221             + "    log(list[i].id);\n"
222             + "  }\n"
223             + "}\n"
224             + "</script></head>\n"
225             + "<body onload='test()'>\n"
226             + "<ul>\n"
227             + "  <li id='li1'></li>\n"
228             + "  <li id='li2'></li>\n"
229             + "  <li id='li3'></li>\n"
230             + "  <li id='li4'></li>\n"
231             + "  <li id='li5'></li>\n"
232             + "  <li id='li6'></li>\n"
233             + "  <li id='li7'></li>\n"
234             + "  <li id='li8'></li>\n"
235             + "  <li id='li9'></li>\n"
236             + "  <li id='li10'></li>\n"
237             + "</ul>\n"
238             + "</body></html>";
239 
240         loadPageVerifyTitle2(html);
241     }
242 
243     /**
244      * Exception should be thrown for an invalid selector.
245      *
246      * @throws Exception if an error occurs
247      */
248     @Test
249     @Alerts("SyntaxError/DOMException")
250     public void invalid() throws Exception {
251         final String html = DOCTYPE_HTML
252             + "<html><head><script>\n"
253             + LOG_TITLE_FUNCTION
254             + "function test() {\n"
255             + "  try {\n"
256             + "    log(document.querySelectorAll('td:gt(4)').length);\n"
257             + "  } catch(e) { logEx(e) }\n"
258             + "}\n"
259             + "</script></head>\n"
260             + "<body onload='test()'>\n"
261             + "</body></html>";
262 
263         loadPageVerifyTitle2(html);
264     }
265 
266     /**
267      * @throws Exception if an error occurs
268      */
269     @Test
270     @Alerts({"1", "ul2"})
271     public void directAdjacentSelector() throws Exception {
272         final String html = DOCTYPE_HTML
273             + "<html><head>\n"
274             + "<script>\n"
275             + LOG_TITLE_FUNCTION
276             + "function test() {\n"
277             + "  var list = document.querySelectorAll('p+ul');\n"
278             + "  log(list.length);\n"
279             + "  log(list[0].id);\n"
280             + "}\n"
281             + "</script></head>\n"
282             + "<body onload='test()'>\n"
283             + "  <div></div>\n"
284             + "  <ul id='ul1'></ul>\n"
285             + "  <p></p>\n"
286             + "  <ul id='ul2'></ul>\n"
287             + "</body></html>";
288 
289         loadPageVerifyTitle2(html);
290     }
291 
292     /**
293      * @throws Exception if an error occurs
294      */
295     @Test
296     @Alerts({"1", "thing1"})
297     public void prefixAttribute() throws Exception {
298         final String html = DOCTYPE_HTML
299             + "<html><head>\n"
300             + "<script>\n"
301             + LOG_TITLE_FUNCTION
302             + "function test() {\n"
303             + "  var list = document.querySelectorAll('[id^=\"thing\"]');\n"
304             + "  log(list.length);\n"
305             + "  log(list[0].id);\n"
306             + "}\n"
307             + "</script></head>\n"
308             + "<body onload='test()'>\n"
309             + "  <div></div>\n"
310             + "  <ul id='something'></ul>\n"
311             + "  <p></p>\n"
312             + "  <ul id='thing1'></ul>\n"
313             + "  <ul id='tHIng2'></ul>\n"
314             + "</body></html>";
315 
316         loadPageVerifyTitle2(html);
317     }
318 
319     /**
320      * @throws Exception if an error occurs
321      */
322     @Test
323     @Alerts({"2", "thing1", "tHIng2"})
324     public void prefixAttributeCaseInSensitive() throws Exception {
325         final String html = DOCTYPE_HTML
326             + "<html><head>\n"
327             + "<script>\n"
328             + LOG_TITLE_FUNCTION
329             + "function test() {\n"
330             + "  var list = document.querySelectorAll('[id^=\"thing\" i]');\n"
331             + "  log(list.length);\n"
332             + "  log(list[0].id);\n"
333             + "  log(list[1].id);\n"
334             + "}\n"
335             + "</script></head>\n"
336             + "<body onload='test()'>\n"
337             + "  <div></div>\n"
338             + "  <ul id='something'></ul>\n"
339             + "  <p></p>\n"
340             + "  <ul id='thing1'></ul>\n"
341             + "  <ul id='tHIng2'></ul>\n"
342             + "</body></html>";
343 
344         loadPageVerifyTitle2(html);
345     }
346 
347     /**
348      * @throws Exception if an error occurs
349      */
350     @Test
351     @Alerts("0")
352     public void prefixAttributeEmpty() throws Exception {
353         final String html = DOCTYPE_HTML
354             + "<html><head>\n"
355             + "<script>\n"
356             + LOG_TITLE_FUNCTION
357             + "function test() {\n"
358             + "  var list = document.querySelectorAll('[id^=\"\"]');\n"
359             + "  log(list.length);\n"
360             + "  for (var i = 0 ; i < list.length; i++) {\n"
361             + "    log(list[i].outerHTML.replace(/^\\s+|\\s+$/g, ''));\n"
362             + "  }\n"
363             + "}\n"
364             + "</script></head>\n"
365             + "<body onload='test()'>\n"
366             + "  <div></div>\n"
367             + "  <ul id='something'></ul>\n"
368             + "  <p></p>\n"
369             + "  <ul id='thing1'></ul>\n"
370             + "</body></html>";
371 
372         loadPageVerifyTitle2(html);
373     }
374 
375     /**
376      * @throws Exception if an error occurs
377      */
378     @Test
379     @Alerts({"1", "something"})
380     public void suffixAttribute() throws Exception {
381         final String html = DOCTYPE_HTML
382             + "<html><head>\n"
383             + "<script>\n"
384             + LOG_TITLE_FUNCTION
385             + "function test() {\n"
386             + "  var list = document.querySelectorAll('[id$=\"thing\"]');\n"
387             + "  log(list.length);\n"
388             + "  log(list[0].id);\n"
389             + "}\n"
390             + "</script></head>\n"
391             + "<body onload='test()'>\n"
392             + "  <div></div>\n"
393             + "  <ul id='something'></ul>\n"
394             + "  <ul id='AnyThinG'></ul>\n"
395             + "  <p></p>\n"
396             + "  <ul id='thing2'></ul>\n"
397             + "</body></html>";
398 
399         loadPageVerifyTitle2(html);
400     }
401 
402     /**
403      * @throws Exception if an error occurs
404      */
405     @Test
406     @Alerts({"2", "something", "AnyThinG"})
407     public void suffixAttributeCaseInSensitive() throws Exception {
408         final String html = DOCTYPE_HTML
409             + "<html><head>\n"
410             + "<script>\n"
411             + LOG_TITLE_FUNCTION
412             + "function test() {\n"
413             + "  var list = document.querySelectorAll('[id$=\"thing\" I]');\n"
414             + "  log(list.length);\n"
415             + "  log(list[0].id);\n"
416             + "  log(list[1].id);\n"
417             + "}\n"
418             + "</script></head>\n"
419             + "<body onload='test()'>\n"
420             + "  <div></div>\n"
421             + "  <ul id='something'></ul>\n"
422             + "  <ul id='AnyThinG'></ul>\n"
423             + "  <p></p>\n"
424             + "  <ul id='thing2'></ul>\n"
425             + "</body></html>";
426 
427         loadPageVerifyTitle2(html);
428     }
429 
430     /**
431      * @throws Exception if an error occurs
432      */
433     @Test
434     @Alerts("0")
435     public void suffixAttributeEmpty() throws Exception {
436         final String html = DOCTYPE_HTML
437             + "<html><head>\n"
438             + "<script>\n"
439             + LOG_TITLE_FUNCTION
440             + "function test() {\n"
441             + "  var list = document.querySelectorAll('[id$=\"\"]');\n"
442             + "  log(list.length);\n"
443             + "  for (var i = 0 ; i < list.length; i++) {\n"
444             + "    log(list[i].outerHTML.replace(/^\\s+|\\s+$/g, ''));\n"
445             + "  }\n"
446             + "}\n"
447             + "</script></head>\n"
448             + "<body onload='test()'>\n"
449             + "  <div></div>\n"
450             + "  <ul id='something'></ul>\n"
451             + "  <p></p>\n"
452             + "  <ul id='thing2'></ul>\n"
453             + "</body></html>";
454 
455         loadPageVerifyTitle2(html);
456     }
457 
458     /**
459      * @throws Exception if an error occurs
460      */
461     @Test
462     @Alerts({"2", "something", "thing2"})
463     public void substringAttribute() throws Exception {
464         final String html = DOCTYPE_HTML
465             + "<html><head>\n"
466             + "<script>\n"
467             + LOG_TITLE_FUNCTION
468             + "function test() {\n"
469             + "  var list = document.querySelectorAll('[id*=\"thing\"]');\n"
470             + "  log(list.length);\n"
471             + "  log(list[0].id);\n"
472             + "  log(list[1].id);\n"
473             + "}\n"
474             + "</script></head>\n"
475             + "<body onload='test()'>\n"
476             + "  <div></div>\n"
477             + "  <ul id='something'></ul>\n"
478             + "  <p></p>\n"
479             + "  <ul id='thing2'></ul>\n"
480             + "</body></html>";
481 
482         loadPageVerifyTitle2(html);
483     }
484 
485     /**
486      * @throws Exception if an error occurs
487      */
488     @Test
489     @Alerts({"2", "sometHIng", "thinG2"})
490     public void substringAttributeInSensitive() throws Exception {
491         final String html = DOCTYPE_HTML
492             + "<html><head>\n"
493             + "<script>\n"
494             + LOG_TITLE_FUNCTION
495             + "function test() {\n"
496             + "  var list = document.querySelectorAll('[id*=\"thin\" i ]');\n"
497             + "  log(list.length);\n"
498             + "  log(list[0].id);\n"
499             + "  log(list[1].id);\n"
500             + "}\n"
501             + "</script></head>\n"
502             + "<body onload='test()'>\n"
503             + "  <div></div>\n"
504             + "  <ul id='sometHIng'></ul>\n"
505             + "  <p></p>\n"
506             + "  <ul id='thinG2'></ul>\n"
507             + "</body></html>";
508 
509         loadPageVerifyTitle2(html);
510     }
511 
512     /**
513      * @throws Exception if an error occurs
514      */
515     @Test
516     @Alerts("0")
517     public void substringAttributeEmpty() throws Exception {
518         final String html = DOCTYPE_HTML
519             + "<html><head>\n"
520             + "<script>\n"
521             + LOG_TITLE_FUNCTION
522             + "function test() {\n"
523             + "  var list = document.querySelectorAll('[id*=\"\"]');\n"
524             + "  log(list.length);\n"
525             + "  for (var i = 0 ; i < list.length; i++) {\n"
526             + "    log(list[i].outerHTML.replace(/^\\s+|\\s+$/g, ''));\n"
527             + "  }\n"
528             + "}\n"
529             + "</script></head>\n"
530             + "<body onload='test()'>\n"
531             + "  <div></div>\n"
532             + "  <ul id='something'></ul>\n"
533             + "  <p></p>\n"
534             + "  <ul id='thing2'></ul>\n"
535             + "</body></html>";
536 
537         loadPageVerifyTitle2(html);
538     }
539 
540     /**
541      * @throws Exception if an error occurs
542      */
543     @Test
544     @Alerts({"2", "id1", "id2"})
545     public void oneOfAttribute() throws Exception {
546         final String html = DOCTYPE_HTML
547             + "<html><head>\n"
548             + "<script>\n"
549             + LOG_TITLE_FUNCTION
550             + "function test() {\n"
551             + "  var list = document.querySelectorAll('[title~=\"w2\"]');\n"
552             + "  log(list.length);\n"
553             + "  log(list[0].id);\n"
554             + "  log(list[1].id);\n"
555             + "}\n"
556             + "</script></head>\n"
557             + "<body onload='test()'>\n"
558             + "  <div></div>\n"
559             + "  <ul id='id1' title='w1 w2 w3'></ul>\n"
560             + "  <p id='id2' title='w2'></p>\n"
561             + "  <ul id='id3' title='w1w2 w3'></ul>\n"
562             + "</body></html>";
563 
564         loadPageVerifyTitle2(html);
565     }
566 
567     /**
568      * @throws Exception if an error occurs
569      */
570     @Test
571     @Alerts({"2", "id1", "id2"})
572     public void oneOfAttributeInSensitive() throws Exception {
573         final String html = DOCTYPE_HTML
574             + "<html><head>\n"
575             + "<script>\n"
576             + LOG_TITLE_FUNCTION
577             + "function test() {\n"
578             + "  var list = document.querySelectorAll('[title~=\"W2\"i]');\n"
579             + "  log(list.length);\n"
580             + "  log(list[0].id);\n"
581             + "  log(list[1].id);\n"
582             + "}\n"
583             + "</script></head>\n"
584             + "<body onload='test()'>\n"
585             + "  <div></div>\n"
586             + "  <ul id='id1' title='w1 w2 w3'></ul>\n"
587             + "  <p id='id2' title='W2'></p>\n"
588             + "  <ul id='id3' title='w1w2 w3'></ul>\n"
589             + "</body></html>";
590 
591         loadPageVerifyTitle2(html);
592     }
593 
594     /**
595      * @throws Exception if an error occurs
596      */
597     @Test
598     @Alerts("0")
599     public void oneOfAttributeEmpty() throws Exception {
600         final String html = DOCTYPE_HTML
601             + "<html><head>\n"
602             + "<script>\n"
603             + LOG_TITLE_FUNCTION
604             + "function test() {\n"
605             + "  var list = document.querySelectorAll('[title~=\"\"]');\n"
606             + "  log(list.length);\n"
607             + "}\n"
608             + "</script></head>\n"
609             + "<body onload='test()'>\n"
610             + "  <div></div>\n"
611             + "  <ul id='id1' title='w1 w2 w3'></ul>\n"
612             + "  <p id='id2' title='w2'></p>\n"
613             + "  <ul id='id3' title='w1w2 w3'></ul>\n"
614             + "</body></html>";
615 
616         loadPageVerifyTitle2(html);
617     }
618 
619     /**
620      * @throws Exception if an error occurs
621      */
622     @Test
623     @Alerts({"2", "id2", "id3"})
624     public void hasAttribute() throws Exception {
625         final String html = DOCTYPE_HTML
626             + "<html><head>\n"
627             + "<script>\n"
628             + LOG_TITLE_FUNCTION
629             + "function test() {\n"
630             + "  var list = document.querySelectorAll('[title]');\n"
631             + "  log(list.length);\n"
632             + "  for (var i = 0 ; i < list.length; i++) {\n"
633             + "    log(list[i].id);\n"
634             + "  }\n"
635             + "}\n"
636             + "</script></head>\n"
637             + "<body onload='test()'>\n"
638             + "  <div></div>\n"
639             + "  <ul id='id1'></ul>\n"
640             + "  <p id='id2' title='w2'></p>\n"
641             + "  <ul id='id3' title=''></ul>\n"
642             + "</body></html>";
643 
644         loadPageVerifyTitle2(html);
645     }
646 
647     /**
648      * @throws Exception if an error occurs
649      */
650     @Test
651     @Alerts({"5", "id1", "id2", "id5", "id6", "id7"})
652     public void hyphenSeparatedAttributeValue() throws Exception {
653         final String html = DOCTYPE_HTML
654             + "<html><head>\n"
655             + "<script>\n"
656             + LOG_TITLE_FUNCTION
657             + "function test() {\n"
658             + "  var list = document.querySelectorAll('[title|=\"abc\"]');\n"
659             + "  log(list.length);\n"
660             + "  for (var i = 0 ; i < list.length; i++) {\n"
661             + "    log(list[i].id);\n"
662             + "  }\n"
663             + "}\n"
664             + "</script></head>\n"
665             + "<body onload='test()'>\n"
666             + "  <div></div>\n"
667             + "  <ul id='id1' title='abc'></ul>\n"
668             + "  <p id='id2' title='abc-def'></p>\n"
669             + "  <p id='id3' title='x-abc-def'></p>\n"
670             + "  <p id='id4' title='abc -def'></p>\n"
671             + "  <p id='id5' title='abc- def'></p>\n"
672             + "  <p id='id6' title='abc-def gh'></p>\n"
673             + "  <p id='id7' title='abc-def-gh'></p>\n"
674             + "  <p id='id8' title='xabc'></p>\n"
675             + "  <ul id='id9' title='abcd'></ul>\n"
676             + "  <p id='id10' title='abc def'></p>\n"
677             + "  <p id='id11' title=' abc-def gh'></p>\n"
678             + "</body></html>";
679 
680         loadPageVerifyTitle2(html);
681     }
682 
683     /**
684      * @throws Exception if an error occurs
685      */
686     @Test
687     @Alerts({"5", "id1", "id2", "id5", "id6", "id7"})
688     public void hyphenSeparatedAttributeValueInSensitive() throws Exception {
689         final String html = DOCTYPE_HTML
690             + "<html><head>\n"
691             + "<script>\n"
692             + LOG_TITLE_FUNCTION
693             + "function test() {\n"
694             + "  var list = document.querySelectorAll('[title|=\"Abc\" i]');\n"
695             + "  log(list.length);\n"
696             + "  for (var i = 0 ; i < list.length; i++) {\n"
697             + "    log(list[i].id);\n"
698             + "  }\n"
699             + "}\n"
700             + "</script></head>\n"
701             + "<body onload='test()'>\n"
702             + "  <div></div>\n"
703             + "  <ul id='id1' title='abc'></ul>\n"
704             + "  <p id='id2' title='abc-def'></p>\n"
705             + "  <p id='id3' title='x-aBc-def'></p>\n"
706             + "  <p id='id4' title='abc -def'></p>\n"
707             + "  <p id='id5' title='aBc- def'></p>\n"
708             + "  <p id='id6' title='abc-def gh'></p>\n"
709             + "  <p id='id7' title='abC-def-gh'></p>\n"
710             + "  <p id='id8' title='xabc'></p>\n"
711             + "  <ul id='id9' title='abcd'></ul>\n"
712             + "  <p id='id10' title='abc def'></p>\n"
713             + "  <p id='id11' title=' abc-def gh'></p>\n"
714             + "</body></html>";
715 
716         loadPageVerifyTitle2(html);
717     }
718 
719     /**
720      * @throws Exception if an error occurs
721      */
722     @Test
723     @Alerts({"2", "id1", "id4"})
724     public void hyphenSeparatedAttributeValueHyphenInSelector() throws Exception {
725         final String html = DOCTYPE_HTML
726             + "<html><head>\n"
727             + "<script>\n"
728             + LOG_TITLE_FUNCTION
729             + "function test() {\n"
730             + "  var list = document.querySelectorAll('[title|=\"ab-c\"]');\n"
731             + "  log(list.length);\n"
732             + "  for (var i = 0 ; i < list.length; i++) {\n"
733             + "    log(list[i].id);\n"
734             + "  }\n"
735             + "}\n"
736             + "</script></head>\n"
737             + "<body onload='test()'>\n"
738             + "  <div></div>\n"
739             + "  <ul id='id1' title='ab-c'></ul>\n"
740             + "  <p id='id2' title='ab-cd'></p>\n"
741             + "  <ul id='id3' title='ab-c d'></ul>\n"
742             + "  <p id='id4' title='ab-c-d'></p>\n"
743             + "</body></html>";
744 
745         loadPageVerifyTitle2(html);
746     }
747 
748     /**
749      * @throws Exception if an error occurs
750      */
751     @Test
752     @Alerts({"2", "id2", "id6"})
753     public void hyphenSeparatedAttributeValueEmpty() throws Exception {
754         final String html = DOCTYPE_HTML
755             + "<html><head>\n"
756             + "<script>\n"
757             + LOG_TITLE_FUNCTION
758             + "function test() {\n"
759             + "  var list = document.querySelectorAll('[title|=\"\"]');\n"
760             + "  log(list.length);\n"
761             + "  for (var i = 0 ; i < list.length; i++) {\n"
762             + "    log(list[i].id);\n"
763             + "  }\n"
764             + "}\n"
765             + "</script></head>\n"
766             + "<body onload='test()'>\n"
767             + "  <div></div>\n"
768             + "  <ul id='id1' title='abc'></ul>\n"
769             + "  <p id='id2' title=''></p>\n"
770             + "  <ul id='id3' title=' '></ul>\n"
771             + "  <p id='id4' title=' -abc'></p>\n"
772             + "  <p id='id5' title=' -abc'></p>\n"
773             + "  <p id='id6' title='-abc'></p>\n"
774             + "  <p id='id7' title='\\t'></p>\n"
775             + "</body></html>";
776 
777         loadPageVerifyTitle2(html);
778     }
779 
780     /**
781      * @throws Exception if an error occurs
782      */
783     @Test
784     @Alerts({"1", "id3"})
785     public void emptyAttributeValue() throws Exception {
786         final String html = DOCTYPE_HTML
787             + "<html><head>\n"
788             + "<script>\n"
789             + LOG_TITLE_FUNCTION
790             + "function test() {\n"
791             + "  var list = document.querySelectorAll('[title=\"\"]');\n"
792             + "  log(list.length);\n"
793             + "  for (var i = 0 ; i < list.length; i++) {\n"
794             + "    log(list[i].id);\n"
795             + "  }\n"
796             + "}\n"
797             + "</script></head>\n"
798             + "<body onload='test()'>\n"
799             + "  <div></div>\n"
800             + "  <ul id='id1' title='w1'></ul>\n"
801             + "  <p id='id2' title=' '></p>\n"
802             + "  <ul id='id3' title=''></ul>\n"
803             + "</body></html>";
804 
805         loadPageVerifyTitle2(html);
806     }
807 
808     /**
809      * @throws Exception if an error occurs
810      */
811     @Test
812     @Alerts({"2", "ul2", "ul3"})
813     public void generalAdjacentSelector() throws Exception {
814         final String html = DOCTYPE_HTML
815             + "<html><head>\n"
816             + "<script>\n"
817             + LOG_TITLE_FUNCTION
818             + "function test() {\n"
819             + "  var list = document.querySelectorAll('div~ul');\n"
820             + "  log(list.length);\n"
821             + "  for (var i = 0 ; i < list.length; i++) {\n"
822             + "    log(list[i].id);\n"
823             + "  }\n"
824             + "}\n"
825             + "</script></head>\n"
826             + "<body onload='test()'>\n"
827             + "  <div></div>\n"
828             + "  <p></p>\n"
829             + "  <ul id='ul2'></ul>\n"
830             + "  <ul id='ul3'></ul>\n"
831             + "</body></html>";
832 
833         loadPageVerifyTitle2(html);
834     }
835 
836     /**
837      * @throws Exception if an error occurs
838      */
839     @Test
840     @Alerts({"li3", "2", "li1", "li3"})
841     public void nth_last_child() throws Exception {
842         final String html = DOCTYPE_HTML
843             + "<html><head>\n"
844             + "<script>\n"
845             + LOG_TITLE_FUNCTION
846             + "function test() {\n"
847             + "  log(document.querySelectorAll('li:nth-last-child(1)')[0].id);\n"
848             + "  log(document.querySelectorAll('li:nth-last-child(odd)').length);\n"
849             + "  log(document.querySelectorAll('li:nth-last-child(odd)')[0].id);\n"
850             + "  log(document.querySelectorAll('li:nth-last-child(odd)')[1].id);\n"
851             + "}\n"
852             + "</script></head>\n"
853             + "<body onload='test()'>\n"
854             + "<ul>\n"
855             + "  <li id='li1'></li>\n"
856             + "  <li id='li2'></li>\n"
857             + "  <li id='li3'></li>\n"
858             + "</ul>\n"
859             + "</body></html>";
860 
861         loadPageVerifyTitle2(html);
862     }
863 
864     /**
865      * @throws Exception if an error occurs
866      */
867     @Test
868     @Alerts({"2", "div1", "div3", "2", "div1", "div3", "2", "div1", "div3", "0"})
869     public void nth_last_child2() throws Exception {
870         final String html = DOCTYPE_HTML
871             + "<html><head>\n"
872             + "<script>\n"
873             + LOG_TITLE_FUNCTION
874             + "function test() {\n"
875             + "  log(document.querySelectorAll('.nthchild1 > :nth-last-child(odd)').length);\n"
876             + "  log(document.querySelectorAll('.nthchild1 > :nth-last-child(odd)')[0].id);\n"
877             + "  log(document.querySelectorAll('.nthchild1 > :nth-last-child(odd)')[1].id);\n"
878 
879             + "  elem = document.getElementById('root');\n"
880             + "  log(elem.querySelectorAll('.nthchild1 > :nth-last-child(odd)').length);\n"
881             + "  log(elem.querySelectorAll('.nthchild1 > :nth-last-child(odd)')[0].id);\n"
882             + "  log(elem.querySelectorAll('.nthchild1 > :nth-last-child(odd)')[1].id);\n"
883 
884             + "  elem = document.getElementById('parent');\n"
885             + "  log(elem.querySelectorAll('.nthchild1 > :nth-last-child(odd)').length);\n"
886             + "  log(elem.querySelectorAll('.nthchild1 > :nth-last-child(odd)')[0].id);\n"
887             + "  log(elem.querySelectorAll('.nthchild1 > :nth-last-child(odd)')[1].id);\n"
888 
889             + "  elem = document.getElementById('div1');\n"
890             + "  log(elem.querySelectorAll('.nthchild1 > :nth-last-child(odd)').length);\n"
891             + "}\n"
892             + "</script></head>\n"
893             + "<body onload='test()'>\n"
894             + "<div id='root'>\n"
895             + "  <div id='parent' class='nthchild1'>\n"
896             + "    <div id='div1'>1</div>\n"
897             + "    <div id='div2'>2</div>\n"
898             + "    <div id='div3'>3</div>\n"
899             + "  </div>\n"
900             + "</div>\n"
901             + "</body></html>";
902 
903         loadPageVerifyTitle2(html);
904     }
905 
906     /**
907      * @throws Exception if an error occurs
908      */
909     @Test
910     @Alerts("id3")
911     public void nth_of_type() throws Exception {
912         final String html = DOCTYPE_HTML
913             + "<html><head>\n"
914             + "<script>\n"
915             + LOG_TITLE_FUNCTION
916             + "function test() {\n"
917             + "  log(document.querySelectorAll('p:nth-of-type(2)')[0].id);\n"
918             + "}\n"
919             + "</script></head>\n"
920             + "<body onload='test()'>\n"
921             + "<section>\n"
922             + "  <h1 id='id11'></h1>\n"
923             + "  <p id='id2'></p>\n"
924             + "  <p id='id3'></p>\n"
925             + "</section>\n"
926             + "</body></html>";
927 
928         loadPageVerifyTitle2(html);
929     }
930 
931     /**
932      * @throws Exception if an error occurs
933      */
934     @Test
935     @Alerts("id3")
936     public void nth_last_of_type() throws Exception {
937         final String html = DOCTYPE_HTML
938             + "<html><head>\n"
939             + "<script>\n"
940             + LOG_TITLE_FUNCTION
941             + "function test() {\n"
942             + "  log(document.querySelectorAll('p:nth-last-of-type(1)')[0].id);\n"
943             + "}\n"
944             + "</script></head>\n"
945             + "<body onload='test()'>\n"
946             + "<section>\n"
947             + "  <h1 id='id1'></h1>\n"
948             + "  <p  id='id2'></p>\n"
949             + "  <p  id='id3'></p>\n"
950             + "</section>\n"
951             + "</body></html>";
952 
953         loadPageVerifyTitle2(html);
954     }
955 
956     /**
957      * @throws Exception if an error occurs
958      */
959     @Test
960     public void pseudoAfter() throws Exception {
961         final String html = DOCTYPE_HTML
962             + "<html><head>\n"
963             + "<script>\n"
964             + LOG_TITLE_FUNCTION
965             + "function test() {\n"
966             + "  var list = document.querySelectorAll('#li1:after');\n"
967             + "  for (var i = 0 ; i < list.length; i++) {\n"
968             + "    log(list[i].id);\n"
969             + "  }\n"
970             + "}\n"
971             + "</script></head>\n"
972             + "<body onload='test()'>\n"
973             + "<ul>\n"
974             + "  <li id='li1'></li>\n"
975             + "  <li id='li2'></li>\n"
976             + "</ul>\n"
977             + "</body></html>";
978 
979         loadPageVerifyTitle2(html);
980     }
981 
982     /**
983      * @throws Exception if an error occurs
984      */
985     @Test
986     @Alerts({"1", "checkbox2", "1", "checkbox2"})
987     public void pseudoCheckboxChecked() throws Exception {
988         final String html = DOCTYPE_HTML
989             + "<html><head>\n"
990             + "<script>\n"
991             + LOG_TITLE_FUNCTION
992             + "function test() {\n"
993             + "  var list = document.querySelectorAll('input[type=checkbox]:checked');\n"
994             + "  log(list.length);\n"
995             + "  log(list[0].id);\n"
996 
997             + "  var list = document.querySelectorAll('#t2 > input[type=checkbox]:checked');\n"
998             + "  log(list.length);\n"
999             + "  log(list[0].id);\n"
1000             + "}\n"
1001             + "</script></head>\n"
1002             + "<body onload='test()'>\n"
1003             + "  <div id='t2'>\n"
1004             + "    <input type='checkbox' name='checkbox1' id='checkbox1' value='foo'>\n"
1005             + "    <input type='checkbox' name='checkbox2' id='checkbox2' value='bar' checked>\n"
1006             + "  </div>\n"
1007             + "</body></html>";
1008 
1009         loadPageVerifyTitle2(html);
1010     }
1011 
1012     /**
1013      * @throws Exception if an error occurs
1014      */
1015     @Test
1016     @Alerts({"1", "radio2", "1", "radio2"})
1017     public void pseudoRadioChecked() throws Exception {
1018         final String html = DOCTYPE_HTML
1019             + "<html><head>\n"
1020             + "<script>\n"
1021             + LOG_TITLE_FUNCTION
1022             + "function test() {\n"
1023             + "  var list = document.querySelectorAll('input[type=radio]:checked');\n"
1024             + "  log(list.length);\n"
1025             + "  log(list[0].id);\n"
1026 
1027             + "  var list = document.querySelectorAll('#t2 > input[type=radio]:checked');\n"
1028             + "  log(list.length);\n"
1029             + "  log(list[0].id);\n"
1030             + "}\n"
1031             + "</script></head>\n"
1032             + "<body onload='test()'>\n"
1033             + "  <div id='t2'>\n"
1034             + "    <input type='radio' name='radio1' id='radio1' value='foo'>\n"
1035             + "    <input type='radio' name='radio2' id='radio2' value='bar' checked>\n"
1036             + "  </div>\n"
1037             + "</body></html>";
1038 
1039         loadPageVerifyTitle2(html);
1040     }
1041 
1042     /**
1043      * See https://www.w3.org/TR/selectors-4/#validity-pseudos.
1044      *
1045      * @throws Exception if an error occurs
1046      */
1047     @Test
1048     @Alerts({"theform", "id3"})
1049     public void pseudoInvalid() throws Exception {
1050         final String html = DOCTYPE_HTML
1051                 + "<html><head>\n"
1052                 + "<script>\n"
1053                 + LOG_TITLE_FUNCTION
1054                 + "function test() {\n"
1055                 + "  var list = document.querySelectorAll(':invalid');\n"
1056                 + "  for (var i = 0 ; i < list.length; i++) {\n"
1057                 + "    log(list[i].id);\n"
1058                 + "  }\n"
1059                 + "}\n"
1060                 + "</script></head>\n"
1061                 + "<body onload='test()'>\n"
1062                 + "<form id='theform'>\n"
1063                 + "  <input id='id1' type='text' value='foo' required>\n"
1064                 + "  <input id='id2' type='text' value=''>\n"
1065                 + "  <input id='id3' type='text' value='' required>\n"
1066                 + "  <input id='id4' type='text' minLength='2' maxLength='5' value='foo'>\n"
1067                 + "  <input id='id5' type='text' maxLength='2' value='foo'>\n"
1068                 + "  <input id='id6' type='text' minLength='5' value='foo'>\n"
1069                 + "  <p id='id7'>foo</p>\n"
1070                 + "</form>\n"
1071                 + "</body></html>";
1072 
1073         loadPageVerifyTitle2(html);
1074     }
1075 
1076     /**
1077      * See https://www.w3.org/TR/selectors-4/#validity-pseudos.
1078      *
1079      * @throws Exception if an error occurs
1080      */
1081     @Test
1082     @Alerts({"id1", "id2", "id4", "id5", "id6"})
1083     public void pseudoValid() throws Exception {
1084         final String html = DOCTYPE_HTML
1085                 + "<html><head>\n"
1086                 + "<script>\n"
1087                 + LOG_TITLE_FUNCTION
1088                 + "function test() {\n"
1089                 + "  var list = document.querySelectorAll(':valid');\n"
1090                 + "  for (var i = 0 ; i < list.length; i++) {\n"
1091                 + "    log(list[i].id);\n"
1092                 + "  }\n"
1093                 + "}\n"
1094                 + "</script></head>\n"
1095                 + "<body onload='test()'>\n"
1096                 + "<form id='theform'>\n"
1097                 + "  <input id='id1' type='text' value='foo' required>\n"
1098                 + "  <input id='id2' type='text' value=''>\n"
1099                 + "  <input id='id3' type='text' value='' required>\n"
1100                 + "  <input id='id4' type='text' minLength='2' maxLength='5' value='foo'>\n"
1101                 + "  <input id='id5' type='text' maxLength='2' value='foo'>\n"
1102                 + "  <input id='id6' type='text' minLength='5' value='foo'>\n"
1103                 + "  <p id='id7'>foo</p>\n"
1104                 + "</form>\n"
1105                 + "</body></html>";
1106 
1107         loadPageVerifyTitle2(html);
1108     }
1109 
1110     /**
1111      * @throws Exception if an error occurs
1112      */
1113     @Test
1114     @Alerts("li1")
1115     public void first_child() throws Exception {
1116         final String html = DOCTYPE_HTML
1117             + "<html><head>\n"
1118             + "<script>\n"
1119             + LOG_TITLE_FUNCTION
1120             + "function test() {\n"
1121             + "  log(document.querySelectorAll('li:first-child')[0].id);\n"
1122             + "}\n"
1123             + "</script></head>\n"
1124             + "<body onload='test()'>\n"
1125             + "<ul>\n"
1126             + "  <li id='li1'></li>\n"
1127             + "  <li id='li2'></li>\n"
1128             + "  <li id='li3'></li>\n"
1129             + "</ul>\n"
1130             + "</body></html>";
1131 
1132         loadPageVerifyTitle2(html);
1133     }
1134 
1135     /**
1136      * @throws Exception if an error occurs
1137      */
1138     @Test
1139     @Alerts("li3")
1140     public void last_child() throws Exception {
1141         final String html = DOCTYPE_HTML
1142             + "<html><head>\n"
1143             + "<script>\n"
1144             + LOG_TITLE_FUNCTION
1145             + "function test() {\n"
1146             + "  log(document.querySelectorAll('li:last-child')[0].id);\n"
1147             + "}\n"
1148             + "</script></head>\n"
1149             + "<body onload='test()'>\n"
1150             + "<ul>\n"
1151             + "  <li id='li1'></li>\n"
1152             + "  <li id='li2'></li>\n"
1153             + "  <li id='li3'></li>\n"
1154             + "</ul>\n"
1155             + "</body></html>";
1156 
1157         loadPageVerifyTitle2(html);
1158     }
1159 
1160     /**
1161      * @throws Exception if an error occurs
1162      */
1163     @Test
1164     @Alerts("id2")
1165     public void first_of_type() throws Exception {
1166         final String html = DOCTYPE_HTML
1167             + "<html><head>\n"
1168             + "<script>\n"
1169             + LOG_TITLE_FUNCTION
1170             + "function test() {\n"
1171             + "  log(document.querySelectorAll('p:first-of-type')[0].id);\n"
1172             + "}\n"
1173             + "</script></head>\n"
1174             + "<body onload='test()'>\n"
1175             + "<section>\n"
1176             + "  <h1 id='id1'></h1>\n"
1177             + "  <p  id='id2'></p>\n"
1178             + "  <h1 id='id3'></h1>\n"
1179             + "  <p  id='id4'></p>\n"
1180             + "  <h1 id='id5'></h1>\n"
1181             + "</section>\n"
1182             + "</body></html>";
1183 
1184         loadPageVerifyTitle2(html);
1185     }
1186 
1187     /**
1188      * See http://dev.w3.org/csswg/selectors3/#negation and
1189      * http://dev.w3.org/csswg/selectors3/#simple-selectors-dfn.
1190      *
1191      * @throws Exception if an error occurs
1192      */
1193     @Test
1194     @Alerts({"2", "link_2", "link_3"})
1195     public void invalid_not() throws Exception {
1196         final String html = DOCTYPE_HTML
1197             + "<html><head>\n"
1198             + "<script>\n"
1199             + LOG_TITLE_FUNCTION
1200             + "function test() {\n"
1201             + "  try {\n"
1202             + "    var found = document.querySelectorAll('p a:not(a:first-of-type)');\n"
1203             + "    log(found.length);\n"
1204             + "    log(found[0].id);\n"
1205             + "    log(found[1].id);\n"
1206             + "  } catch(e) { logEx(e) }\n"
1207             + "}\n"
1208             + "</script></head>\n"
1209             + "<body onload='test()'>\n"
1210             + "<p>\n"
1211             + "  <strong id='strong'>This</strong> is a short blurb\n"
1212             + "  <a id='link_1' href='#'>with a link</a> or\n"
1213             + "  <a id='link_2' href='#'>two</a>.\n"
1214             + "  <a id='link_3' href='#'>three</a>.\n"
1215             + "  Or <cite id='with_title' title='hello world!'>a citation</cite>.\n"
1216             + "</p>\n"
1217             + "</body></html>";
1218 
1219         loadPageVerifyTitle2(html);
1220     }
1221 
1222     /**
1223      * @throws Exception if an error occurs
1224      */
1225     @Test
1226     @Alerts("id4")
1227     public void last_of_type() throws Exception {
1228         final String html = DOCTYPE_HTML
1229             + "<html><head>\n"
1230             + "<script>\n"
1231             + LOG_TITLE_FUNCTION
1232             + "function test() {\n"
1233             + "  log(document.querySelectorAll('p:last-of-type')[0].id);\n"
1234             + "}\n"
1235             + "</script></head>\n"
1236             + "<body onload='test()'>\n"
1237             + "<section>\n"
1238             + "  <h1 id='id1'></h1>\n"
1239             + "  <p  id='id2'></p>\n"
1240             + "  <h1 id='id3'></h1>\n"
1241             + "  <p  id='id4'></p>\n"
1242             + "  <h1 id='id5'></h1>\n"
1243             + "</section>\n"
1244             + "</body></html>";
1245 
1246         loadPageVerifyTitle2(html);
1247     }
1248 
1249     /**
1250      * @throws Exception if an error occurs
1251      */
1252     @Test
1253     @Alerts("id3")
1254     public void only_child() throws Exception {
1255         final String html = DOCTYPE_HTML
1256             + "<html><head>\n"
1257             + "<script>\n"
1258             + LOG_TITLE_FUNCTION
1259             + "function test() {\n"
1260             + "  log(document.querySelectorAll('h1:only-child')[0].id);\n"
1261             + "}\n"
1262             + "</script></head>\n"
1263             + "<body onload='test()'>\n"
1264             + "<section>\n"
1265             + "  <h1 id='id1'></h1>\n"
1266             + "  <p  id='id2'></p>\n"
1267             + "</section>\n"
1268             + "<section>\n"
1269             + "  <h1 id='id3'></h1>\n"
1270             + "</section>\n"
1271             + "</body></html>";
1272 
1273         loadPageVerifyTitle2(html);
1274     }
1275 
1276     /**
1277      * @throws Exception if an error occurs
1278      */
1279     @Test
1280     @Alerts("id3")
1281     public void only_of_type() throws Exception {
1282         final String html = DOCTYPE_HTML
1283             + "<html><head>\n"
1284             + "<script>\n"
1285             + LOG_TITLE_FUNCTION
1286             + "function test() {\n"
1287             + "  log(document.querySelectorAll('p:only-of-type')[0].id);\n"
1288             + "}\n"
1289             + "</script></head>\n"
1290             + "<body onload='test()'>\n"
1291             + "<section>\n"
1292             + "  <p  id='id1'></p>\n"
1293             + "  <p  id='id2'></p>\n"
1294             + "</section>\n"
1295             + "<section>\n"
1296             + "  <p  id='id3'></p>\n"
1297             + "</section>\n"
1298             + "</body></html>";
1299 
1300         loadPageVerifyTitle2(html);
1301     }
1302 
1303     /**
1304      * @throws Exception if an error occurs
1305      */
1306     @Test
1307     @Alerts({"id2", "span1"})
1308     public void empty() throws Exception {
1309         final String html = DOCTYPE_HTML
1310             + "<html><head>\n"
1311             + "<script>\n"
1312             + LOG_TITLE_FUNCTION
1313             + "function test() {\n"
1314             + "  log(document.querySelectorAll('p:empty')[0].id);\n"
1315             + "  log(document.querySelectorAll('span:empty')[0].id);\n"
1316             + "}\n"
1317             + "</script></head>\n"
1318             + "<body onload='test()'>\n"
1319             + "  <p id='id1'>Hello, World!</p>\n"
1320             + "  <p id='id2'></p>\n"
1321             + "  <span id='span1'><!-- a comment --></span>\n"
1322             + "  <span id='span2'>a text</span>\n"
1323             + "</body></html>";
1324 
1325         loadPageVerifyTitle2(html);
1326     }
1327 
1328     /**
1329      * @throws Exception if an error occurs
1330      */
1331     @Test
1332     @Alerts("id2")
1333     public void not() throws Exception {
1334         final String html = DOCTYPE_HTML
1335             + "<html><head>\n"
1336             + "<script>\n"
1337             + LOG_TITLE_FUNCTION
1338             + "function test() {\n"
1339             + "  log(document.querySelectorAll('input:not([type=\"file\"])')[0].id);\n"
1340             + "}\n"
1341             + "</script></head>\n"
1342             + "<body onload='test()'>\n"
1343             + "  <input id='id1' type='file'>\n"
1344             + "  <input id='id2'>\n"
1345             + "</body></html>";
1346 
1347         loadPageVerifyTitle2(html);
1348     }
1349 
1350     /**
1351      * @throws Exception if an error occurs
1352      */
1353     @Test
1354     @Alerts("id2")
1355     public void notWithFirstOfType() throws Exception {
1356         final String html = DOCTYPE_HTML
1357             + "<html>\n"
1358             + "<head>\n"
1359             + "<script>\n"
1360             + LOG_TITLE_FUNCTION
1361             + "function test() {\n"
1362             + "  try {\n"
1363             + "    log(document.querySelectorAll('div:not(div:first-of-type)')[0].id);\n"
1364             + "  } catch(e) { logEx(e) }\n"
1365             + "}\n"
1366             + "</script></head>\n"
1367             + "<body onload='test()'>\n"
1368             + "  <div id='id1'>1</div>\n"
1369             + "  <div id='id2'>2</div>\n"
1370             + "  <div id='id3'>3</div>\n"
1371             + "</body></html>";
1372 
1373         loadPageVerifyTitle2(html);
1374     }
1375 
1376     /**
1377      * @throws Exception if an error occurs
1378      */
1379     @Test
1380     @Alerts({"2", "id2", "id3", "2", "id1", "id3", "2", "id1", "id2",
1381              "3", "id1", "id2", "id3"})
1382     public void notWithNthOfType() throws Exception {
1383         final String html = DOCTYPE_HTML
1384             + "<html>\n"
1385             + "<head>\n"
1386             + "<script>\n"
1387             + LOG_TITLE_FUNCTION
1388             + "function test() {\n"
1389             + "  try {\n"
1390             + "    var res = document.querySelectorAll('div:not(div:nth-of-type(1))');\n"
1391             + "    log(res.length);\n"
1392             + "    log(res[0].id);\n"
1393             + "    log(res[1].id);\n"
1394 
1395             + "    res = document.querySelectorAll('div:not(div:nth-of-type(2))');\n"
1396             + "    log(res.length);\n"
1397             + "    log(res[0].id);\n"
1398             + "    log(res[1].id);\n"
1399 
1400             + "    res = document.querySelectorAll('div:not(div:nth-of-type(3))');\n"
1401             + "    log(res.length);\n"
1402             + "    log(res[0].id);\n"
1403             + "    log(res[1].id);\n"
1404 
1405             + "    res = document.querySelectorAll('div:not(div:nth-of-type(4))');\n"
1406             + "    log(res.length);\n"
1407             + "    log(res[0].id);\n"
1408             + "    log(res[1].id);\n"
1409             + "    log(res[2].id);\n"
1410             + "  } catch(e) { logEx(e) }\n"
1411             + "}\n"
1412             + "</script></head>\n"
1413             + "<body onload='test()'>\n"
1414             + "  <div id='id1'>1</div>\n"
1415             + "  <div id='id2'>2</div>\n"
1416             + "  <div id='id3'>3</div>\n"
1417             + "</body></html>";
1418 
1419         loadPageVerifyTitle2(html);
1420     }
1421 
1422     /**
1423      * @throws Exception if an error occurs
1424      */
1425     @Test
1426     @Alerts("id2")
1427     public void notWithLastOfType() throws Exception {
1428         final String html = DOCTYPE_HTML
1429             + "<html>\n"
1430             + "<head>\n"
1431             + "<script>\n"
1432             + LOG_TITLE_FUNCTION
1433             + "function test() {\n"
1434             + "  try {\n"
1435             + "    log(document.querySelectorAll('div:not(div:last-of-type)')[1].id);\n"
1436             + "  } catch(e) { logEx(e) }\n"
1437             + "}\n"
1438             + "</script></head>\n"
1439             + "<body onload='test()'>\n"
1440             + "  <div id='id1'>1</div>\n"
1441             + "  <div id='id2'>2</div>\n"
1442             + "  <div id='id3'>3</div>\n"
1443             + "</body></html>";
1444 
1445         loadPageVerifyTitle2(html);
1446     }
1447 
1448     /**
1449      * @throws Exception if an error occurs
1450      */
1451     @Test
1452     @Alerts({"2", "id1", "id2", "2", "id1", "id3", "2", "id2", "id3",
1453              "3", "id1", "id2", "id3"})
1454     public void notWithNthLastOfType() throws Exception {
1455         final String html = DOCTYPE_HTML
1456             + "<html>\n"
1457             + "<head>\n"
1458             + "<script>\n"
1459             + LOG_TITLE_FUNCTION
1460             + "function test() {\n"
1461             + "  try {\n"
1462             + "    var res = document.querySelectorAll('div:not(div:nth-last-of-type(1))');\n"
1463             + "    log(res.length);\n"
1464             + "    log(res[0].id);\n"
1465             + "    log(res[1].id);\n"
1466 
1467             + "    res = document.querySelectorAll('div:not(div:nth-last-of-type(2))');\n"
1468             + "    log(res.length);\n"
1469             + "    log(res[0].id);\n"
1470             + "    log(res[1].id);\n"
1471 
1472             + "    res = document.querySelectorAll('div:not(div:nth-last-of-type(3))');\n"
1473             + "    log(res.length);\n"
1474             + "    log(res[0].id);\n"
1475             + "    log(res[1].id);\n"
1476 
1477             + "    res = document.querySelectorAll('div:not(div:nth-last-of-type(4))');\n"
1478             + "    log(res.length);\n"
1479             + "    log(res[0].id);\n"
1480             + "    log(res[1].id);\n"
1481             + "    log(res[2].id);\n"
1482             + "  } catch(e) { logEx(e) }\n"
1483             + "}\n"
1484             + "</script></head>\n"
1485             + "<body onload='test()'>\n"
1486             + "  <div id='id1'>1</div>\n"
1487             + "  <div id='id2'>2</div>\n"
1488             + "  <div id='id3'>3</div>\n"
1489             + "</body></html>";
1490 
1491         loadPageVerifyTitle2(html);
1492     }
1493 
1494     /**
1495      * @throws Exception if an error occurs
1496      */
1497     @Test
1498     @Alerts({"2", "item_2", "item_3"})
1499     public void childNot() throws Exception {
1500         final String html = DOCTYPE_HTML
1501             + "<html><head>\n"
1502             + "<script>\n"
1503             + LOG_TITLE_FUNCTION
1504             + "function test() {\n"
1505             + "  var res = document.querySelectorAll('#list li:not(#item_1)');\n"
1506             + "  log(res.length);\n"
1507             + "  log(res[0].id);\n"
1508             + "  log(res[1].id);\n"
1509             + "}\n"
1510             + "</script></head>\n"
1511             + "<body onload='test()'>\n"
1512             + "  <ul id='list'>\n"
1513             + "    <li id='item_1'>1</li>\n"
1514             + "    <li id='item_2'>2</li>\n"
1515             + "    <li id='item_3'>3</li>\n"
1516             + "  </ul>\n"
1517             + "</body></html>";
1518 
1519         loadPageVerifyTitle2(html);
1520     }
1521 
1522     /**
1523      * @throws Exception if an error occurs
1524      */
1525     @Test
1526     @Alerts({"1", "item_2"})
1527     public void childNotNot() throws Exception {
1528         final String html = DOCTYPE_HTML
1529             + "<html><head>\n"
1530             + "<script>\n"
1531             + LOG_TITLE_FUNCTION
1532             + "function test() {\n"
1533             + "  var res = document.querySelectorAll('#list li:not(#item_1):not(#item_3)');\n"
1534             + "  log(res.length);\n"
1535             + "  log(res[0].id);\n"
1536             + "}\n"
1537             + "</script></head>\n"
1538             + "<body onload='test()'>\n"
1539             + "  <ul id='list'>\n"
1540             + "    <li id='item_1'>1</li>\n"
1541             + "    <li id='item_2'>2</li>\n"
1542             + "    <li id='item_3'>3</li>\n"
1543             + "  </ul>\n"
1544             + "</body></html>";
1545 
1546         loadPageVerifyTitle2(html);
1547     }
1548 
1549     /**
1550      * @throws Exception if an error occurs
1551      */
1552     @Test
1553     @Alerts({"0", "undefined", "1", "[object HTMLInputElement]", "id2"})
1554     public void focus() throws Exception {
1555         final String html = DOCTYPE_HTML
1556             + "<html><head>\n"
1557             + "<script>\n"
1558             + LOG_TITLE_FUNCTION
1559             + "function test() {\n"
1560             + "  found = document.querySelectorAll(':focus');\n"
1561             + "  log(found.length);\n"
1562             + "  log(found[0]);\n"
1563             + "\n"
1564             + "  document.getElementById('id2').focus();\n"
1565             + "\n"
1566             + "  found = document.querySelectorAll(':focus');\n"
1567             + "  log(found.length);\n"
1568             + "  log(found[0]);\n"
1569             + "  log(found[0].id);\n"
1570             + "}\n"
1571             + "</script></head>\n"
1572             + "<body onload='setTimeout(test, 10);'>\n"
1573             + "  <form id='id0'>\n"
1574             + "    <input id='id1'>\n"
1575             + "    <input id='id2'>\n"
1576             + "  </form>\n"
1577             + "</body></html>";
1578 
1579         final WebDriver driver = loadPage2(html);
1580         verifyTitle2(DEFAULT_WAIT_TIME, driver, getExpectedAlerts());
1581     }
1582 
1583     /**
1584      * @throws Exception if an error occurs
1585      */
1586     @Test
1587     @Alerts({"0", "undefined",
1588              "4", "[object HTMLHtmlElement]", "[object HTMLBodyElement]",
1589              "[object HTMLFormElement]", "id0",
1590              "[object HTMLInputElement]", "id2"})
1591     public void focusWithin() throws Exception {
1592         final String html = DOCTYPE_HTML
1593             + "<html><head>\n"
1594             + "<script>\n"
1595             + LOG_TITLE_FUNCTION
1596             + "function test() {\n"
1597             + "  found = document.querySelectorAll(':focus-within');\n"
1598             + "  log(found.length);\n"
1599             + "  log(found[0]);\n"
1600             + "\n"
1601             + "  document.getElementById('id2').focus();\n"
1602             + "\n"
1603             + "  found = document.querySelectorAll(':focus-within');\n"
1604             + "  log(found.length);\n"
1605             + "  log(found[0]);\n"
1606             + "  log(found[1]);\n"
1607             + "  log(found[2]);\n"
1608             + "  log(found[2].id);\n"
1609             + "  log(found[3]);\n"
1610             + "  log(found[3].id);\n"
1611             + "}\n"
1612             + "</script></head>\n"
1613             + "<body onload='setTimeout(test, 10);'>\n"
1614             + "  <form id='id0'>\n"
1615             + "    <input id='id1'>\n"
1616             + "    <input id='id2'>\n"
1617             + "  </form>\n"
1618             + "</body></html>";
1619 
1620         final WebDriver driver = loadPage2(html);
1621         verifyTitle2(DEFAULT_WAIT_TIME, driver, getExpectedAlerts());
1622     }
1623 
1624     /**
1625      * @throws Exception if an error occurs
1626      */
1627     @Test
1628     @Alerts({"0", "undefined", "1", "[object HTMLInputElement]", "id2"})
1629     public void focusVisible() throws Exception {
1630         final String html = DOCTYPE_HTML
1631             + "<html><head>\n"
1632             + "<script>\n"
1633             + LOG_TITLE_FUNCTION
1634             + "function test() {\n"
1635             + "  found = document.querySelectorAll(':focus-visible');\n"
1636             + "  log(found.length);\n"
1637             + "  log(found[0]);\n"
1638             + "\n"
1639             + "  document.getElementById('id2').focus();\n"
1640             + "\n"
1641             + "  found = document.querySelectorAll(':focus-visible');\n"
1642             + "  log(found.length);\n"
1643             + "  log(found[0]);\n"
1644             + "  log(found[0].id);\n"
1645             + "}\n"
1646             + "</script></head>\n"
1647             + "<body onload='setTimeout(test, 10);'>\n"
1648             + "  <form id='id0'>\n"
1649             + "    <input id='id1'>\n"
1650             + "    <input id='id2'>\n"
1651             + "  </form>\n"
1652             + "</body></html>";
1653 
1654         final WebDriver driver = loadPage2(html);
1655         verifyTitle2(DEFAULT_WAIT_TIME, driver, getExpectedAlerts());
1656     }
1657 
1658     /**
1659      * @throws Exception if an error occurs
1660      */
1661     @Test
1662     @Alerts({"5", "cb1", "rd1", "sl1", "ml1", "ml3"})
1663     public void checked() throws Exception {
1664         final String html = DOCTYPE_HTML
1665             + "<html><head>\n"
1666             + "<script>\n"
1667             + LOG_TITLE_FUNCTION
1668             + "function test() {\n"
1669             + "  found = document.querySelectorAll(':checked');\n"
1670             + "  log(found.length);\n"
1671             + "  for (var i = 0; i < found.length; i++) { log(found[i].id); }\n"
1672             + "}\n"
1673             + "</script></head>\n"
1674             + "<body onload='test()'>\n"
1675             + "  <input id='id1'>\n"
1676             + "  <input id='id2' disabled='disabled'>\n"
1677             + "  <input id='id3' type'hidden'>\n"
1678             + "  <input type='checkbox' name='checkboxes' id='cb1' checked='checked' value='On' />\n"
1679             + "  <input type='checkbox' name='checkboxes' id='cb2' value='Off' />\n"
1680             + "  <input type='radio' name='radiobuttons' id='rd1' checked='checked' value='On' />\n"
1681             + "  <input type='radio' name='radiobuttons' id='rd2' value='Off' />\n"
1682             + "  <select name='sl'>\n"
1683             + "    <option value='sl1' id='sl1' selected='selected'>SL One</option>\n"
1684             + "    <option value='sl2' id='sl2' >SL Two</option>\n"
1685             + "  </select>\n"
1686             + "  <select name='ml'  multiple=multiple'>\n"
1687             + "    <option value='ml1' id='ml1' selected='selected'>ML One</option>\n"
1688             + "    <option value='ml2' id='ml2' >ML Two</option>\n"
1689             + "    <option value='ml3' id='ml3' selected='selected'>ML Three</option>\n"
1690             + "  </select>\n"
1691             + "</body></html>";
1692 
1693         loadPageVerifyTitle2(html);
1694     }
1695 
1696     /**
1697      * @throws Exception if an error occurs
1698      */
1699     @Test
1700     @Alerts({"2", "cb1", "rd1", "2", "cb2", "rd2"})
1701     public void checkedChanged() throws Exception {
1702         final String html = DOCTYPE_HTML
1703             + "<html><head>\n"
1704             + "<script>\n"
1705             + LOG_TITLE_FUNCTION
1706             + "function test() {\n"
1707             + "  found = document.querySelectorAll(':checked');\n"
1708             + "  log(found.length);\n"
1709             + "  for (var i = 0; i < found.length; i++) { log(found[i].id); }\n"
1710 
1711             + "  document.getElementById('cb1').checked = false;\n"
1712             + "  document.getElementById('cb2').checked = true;\n"
1713             + "  document.getElementById('rd1').checked = false;\n"
1714             + "  document.getElementById('rd2').checked = true;\n"
1715             + "  found = document.querySelectorAll(':checked');\n"
1716             + "  log(found.length);\n"
1717             + "  for (var i = 0; i < found.length; i++) { log(found[i].id); }\n"
1718             + "}\n"
1719             + "</script></head>\n"
1720             + "<body onload='test()'>\n"
1721             + "  <input type='checkbox' name='checkboxes' id='cb1' checked='checked' value='On' />\n"
1722             + "  <input type='checkbox' name='checkboxes' id='cb2' value='Off' />\n"
1723             + "  <input type='radio' name='radiobuttons' id='rd1' checked='checked' value='On' />\n"
1724             + "  <input type='radio' name='radiobuttons' id='rd2' value='Off' />\n"
1725             + "</body></html>";
1726 
1727         loadPageVerifyTitle2(html);
1728     }
1729 
1730     /**
1731      * @throws Exception if an error occurs
1732      */
1733     @Test
1734     @Alerts({"2", "cb1", "rd1", "2", "cb1", "rd1"})
1735     public void checkedAttribute() throws Exception {
1736         final String html = DOCTYPE_HTML
1737             + "<html><head>\n"
1738             + "<script>\n"
1739             + LOG_TITLE_FUNCTION
1740             + "function test() {\n"
1741             + "  found = document.querySelectorAll('[checked]');\n"
1742             + "  log(found.length);\n"
1743             + "  for (var i = 0; i < found.length; i++) { log(found[i].id); }\n"
1744 
1745             + "  document.getElementById('cb1').checked = false;\n"
1746             + "  document.getElementById('cb2').checked = true;\n"
1747             + "  document.getElementById('rd1').checked = false;\n"
1748             + "  document.getElementById('rd2').checked = true;\n"
1749             + "  found = document.querySelectorAll('[checked]');\n"
1750             + "  log(found.length);\n"
1751             + "  for (var i = 0; i < found.length; i++) { log(found[i].id); }\n"
1752             + "}\n"
1753             + "</script></head>\n"
1754             + "<body onload='test()'>\n"
1755             + "  <input type='checkbox' name='checkboxes' id='cb1' checked='checked' value='On' />\n"
1756             + "  <input type='checkbox' name='checkboxes' id='cb2' value='Off' />\n"
1757             + "  <input type='radio' name='radiobuttons' id='rd1' checked='checked' value='On' />\n"
1758             + "  <input type='radio' name='radiobuttons' id='rd2' value='Off' />\n"
1759             + "</body></html>";
1760 
1761         loadPageVerifyTitle2(html);
1762     }
1763 
1764     /**
1765      * @throws Exception if an error occurs
1766      */
1767     @Test
1768     @Alerts({"1", "1-iy", "1-iy", "2", "1-iy", "1-iz"})
1769     public void selectedChecked() throws Exception {
1770         final String html = DOCTYPE_HTML
1771             + "<html><head>\n"
1772             + "<script>\n"
1773             + LOG_TITLE_FUNCTION
1774             + "function test() {\n"
1775             + "  log(document.getElementById('s1').selectedIndex);\n"
1776             + "  var sel = document.querySelectorAll('[selected]');\n"
1777             + "  log(sel.length + '-' + sel[0].id);\n"
1778             + "  sel = document.querySelectorAll(':checked');\n"
1779             + "  log(sel.length + '-' + sel[0].id);\n"
1780 
1781             + "  document.getElementById('iz').selected = 'selected';\n"
1782             + "  log(document.getElementById('s1').selectedIndex);\n"
1783             + "  var sel = document.querySelectorAll('[selected]');\n"
1784             + "  log(sel.length + '-' + sel[0].id);\n"
1785             + "  sel = document.querySelectorAll(':checked');\n"
1786             + "  log(sel.length + '-' + sel[0].id);\n"
1787             + "}\n"
1788             + "</script></head>\n"
1789             + "<body onload='test()'>\n"
1790             + "  <select id='s1'>\n"
1791             + "    <option id='ix' value='x'>x</option>\n"
1792             + "    <option id='iy' value='y' selected>y</option> \n"
1793             + "    <option id='iz' value='z'>z</option> \n"
1794             + "  </select>\n"
1795             + "</body></html>";
1796 
1797         loadPageVerifyTitle2(html);
1798     }
1799 
1800     /**
1801      * @throws Exception if an error occurs
1802      */
1803     @Test
1804     @Alerts({"2", "id1", "id3"})
1805     public void enabled() throws Exception {
1806         final String html = DOCTYPE_HTML
1807             + "<html><head>\n"
1808             + "<script>\n"
1809             + LOG_TITLE_FUNCTION
1810             + "function test() {\n"
1811             + "  found = document.querySelectorAll('input:enabled');\n"
1812             + "  log(found.length);\n"
1813             + "  for (var i = 0; i < found.length; i++) { log(found[i].id); }\n"
1814             + "}\n"
1815             + "</script></head>\n"
1816             + "<body onload='test()'>\n"
1817             + "  <input id='id1'>\n"
1818             + "  <input id='id2' disabled='disabled'>\n"
1819             + "  <input id='id3' type'hidden'>\n"
1820             + "</body></html>";
1821 
1822         loadPageVerifyTitle2(html);
1823     }
1824 
1825     /**
1826      * @throws Exception if an error occurs
1827      */
1828     @Test
1829     @Alerts({"1", "id2"})
1830     public void disabled() throws Exception {
1831         final String html = DOCTYPE_HTML
1832             + "<html><head>\n"
1833             + "<script>\n"
1834             + LOG_TITLE_FUNCTION
1835             + "function test() {\n"
1836             + "  found = document.querySelectorAll('input:disabled');\n"
1837             + "  log(found.length);\n"
1838             + "  for (var i = 0; i < found.length; i++) { log(found[i].id); }\n"
1839             + "}\n"
1840             + "</script></head>\n"
1841             + "<body onload='test()'>\n"
1842             + "  <input id='id1' >\n"
1843             + "  <input id='id2' disabled='disabled'>\n"
1844             + "  <input id='id3' type'hidden'>\n"
1845             + "</body></html>";
1846 
1847         loadPageVerifyTitle2(html);
1848     }
1849 
1850     /**
1851      * @throws Exception if an error occurs
1852      */
1853     @Test
1854     @Alerts({"1", "fs"})
1855     public void disabledFieldset() throws Exception {
1856         final String html = DOCTYPE_HTML
1857             + "<html><head>\n"
1858             + "<script>\n"
1859             + LOG_TITLE_FUNCTION
1860             + "function test() {\n"
1861             + "  found = document.querySelectorAll('fieldset[disabled]');\n"
1862             + "  log(found.length);\n"
1863             + "  for (var i = 0; i < found.length; i++) { log(found[i].id); }\n"
1864             + "}\n"
1865             + "</script></head>\n"
1866             + "<body onload='test()'>\n"
1867             + "  <form>\n"
1868             + "    <input name='foo' value='bar'/>\n"
1869             + "    <fieldset id='fs' disabled>\n"
1870             + "      <input name='do' value='rey'/>\n"
1871             + "    </fieldset>\n"
1872             + "  </form>\n"
1873             + "</body></html>";
1874 
1875         loadPageVerifyTitle2(html);
1876     }
1877 
1878     /**
1879      * @throws Exception if an error occurs
1880      */
1881     @Test
1882     @Alerts({"2", "fs", "i2"})
1883     public void disabledFieldsetDisables() throws Exception {
1884         final String html = DOCTYPE_HTML
1885             + "<html><head>\n"
1886             + "<script>\n"
1887             + LOG_TITLE_FUNCTION
1888             + "function test() {\n"
1889             + "  found = document.querySelectorAll(':disabled');\n"
1890             + "  log(found.length);\n"
1891             + "  for (var i = 0; i < found.length; i++) { log(found[i].id); }\n"
1892             + "}\n"
1893             + "</script></head>\n"
1894             + "<body onload='test()'>\n"
1895             + "  <form>\n"
1896             + "    <input id='i1' name='foo' value='bar'/>\n"
1897             + "    <fieldset id='fs' disabled>\n"
1898             + "      <input id='i2' name='do' value='rey'/>\n"
1899             + "    </fieldset>\n"
1900             + "  </form>\n"
1901             + "</body></html>";
1902 
1903         loadPageVerifyTitle2(html);
1904     }
1905 
1906     /**
1907      * @throws Exception if an error occurs
1908      */
1909     @Test
1910     @Alerts({"1", "id2"})
1911     public void target() throws Exception {
1912         final String html = DOCTYPE_HTML
1913             + "<html><head>\n"
1914             + "<script>\n"
1915             + LOG_TITLE_FUNCTION
1916             + "function test() {\n"
1917             + "  found = document.querySelectorAll(':target');\n"
1918             + "  log(found.length);\n"
1919             + "  if (found.length > 0) { log(found[0].id); }\n"
1920             + "}\n"
1921             + "</script></head>\n"
1922             + "<body onload='test()'>\n"
1923             + "  <input id='id1' >\n"
1924             + "  <input id='id2'>\n"
1925             + "</body></html>";
1926 
1927         getMockWebConnection().setDefaultResponse(html);
1928         final WebDriver driver = loadPage2(UrlUtils.getUrlWithNewRef(URL_FIRST, "id2"), StandardCharsets.UTF_8);
1929         verifyTitle2(driver, getExpectedAlerts());
1930     }
1931 
1932     /**
1933      * @throws Exception if an error occurs
1934      */
1935     @Test
1936     @Alerts("0")
1937     public void targetNoHash() throws Exception {
1938         final String html = DOCTYPE_HTML
1939             + "<html><head>\n"
1940             + "<script>\n"
1941             + LOG_TITLE_FUNCTION
1942             + "function test() {\n"
1943             + "  found = document.querySelectorAll(':target');\n"
1944             + "  log(found.length);\n"
1945             + "}\n"
1946             + "</script></head>\n"
1947             + "<body onload='test()'>\n"
1948             + "  <input id='id1' >\n"
1949             + "  <input id='id2'>\n"
1950             + "</body></html>";
1951 
1952         loadPageVerifyTitle2(html);
1953     }
1954 
1955     /**
1956      * @throws Exception if an error occurs
1957      */
1958     @Test
1959     @Alerts("0")
1960     public void targetUnknown() throws Exception {
1961         final String html = DOCTYPE_HTML
1962             + "<html><head>\n"
1963             + "<script>\n"
1964             + LOG_TITLE_FUNCTION
1965             + "function test() {\n"
1966             + "  found = document.querySelectorAll(':target');\n"
1967             + "  log(found.length);\n"
1968             + "}\n"
1969             + "</script></head>\n"
1970             + "<body onload='test()'>\n"
1971             + "  <input id='id1' >\n"
1972             + "  <input id='id2'>\n"
1973             + "</body></html>";
1974 
1975         getMockWebConnection().setDefaultResponse(html);
1976         final WebDriver driver = loadPage2(UrlUtils.getUrlWithNewRef(URL_FIRST, "id3"), StandardCharsets.UTF_8);
1977         verifyTitle2(driver, getExpectedAlerts());
1978     }
1979 
1980     /**
1981      * @throws Exception if an error occurs
1982      */
1983     @Test
1984     @Alerts({"1", "[object HTMLHtmlElement]"})
1985     public void root() throws Exception {
1986         final String html = DOCTYPE_HTML
1987             + "<html><head>\n"
1988             + "<script>\n"
1989             + LOG_TITLE_FUNCTION
1990             + "function test() {\n"
1991             + "  var list = document.querySelectorAll(':root');\n"
1992             + "  log(list.length);\n"
1993             + "  log(list[0]);\n"
1994             + "}\n"
1995             + "</script></head>\n"
1996             + "<body onload='test()'>\n"
1997             + "</body></html>";
1998 
1999         loadPageVerifyTitle2(html);
2000     }
2001 
2002     /**
2003      * @throws Exception if an error occurs
2004      */
2005     @Test
2006     @Alerts({"1", "[object HTMLHeadingElement]"})
2007     public void has() throws Exception {
2008         final String html = DOCTYPE_HTML
2009             + "<html><head>\n"
2010             + "<script>\n"
2011             + LOG_TITLE_FUNCTION
2012             + "function test() {\n"
2013             + "  try {\n"
2014             + "    var list = document.querySelectorAll('h1:has(p)');\n"
2015             + "    log(list.length);\n"
2016             + "    log(list[0]);\n"
2017             + "  } catch(e) { logEx(e) }\n"
2018             + "}\n"
2019             + "</script></head>\n"
2020             + "<body onload='test()'>\n"
2021             + "<h1>abc</h1>\n"
2022             + "<h1><p>de</p></h1>\n"
2023             + "</body></html>";
2024 
2025         loadPageVerifyTitle2(html);
2026     }
2027 
2028     /**
2029      * @throws Exception if an error occurs
2030      */
2031     @Test
2032     @Alerts({"first", "second"})
2033     public void escapedAttributeValue() throws Exception {
2034         final String html = DOCTYPE_HTML
2035             + "<html><head>\n"
2036             + "</head><body>\n"
2037             + "  <input id='first' name='foo[bar]'>\n"
2038             + "  <input id='second' name='foo.bar'>\n"
2039             + "<script>\n"
2040             + LOG_TITLE_FUNCTION
2041             + "try {\n"
2042             + "  log(document.querySelectorAll('input[name=foo\\\\[bar\\\\]]')[0].id);\n"
2043             + "} catch(e) {log(e)}\n"
2044             + "try {\n"
2045             + "  log(document.querySelectorAll('input[name=foo\\\\.bar]')[0].id);\n"
2046             + "} catch(e) {log(e)}\n"
2047             + "</script></body></html>";
2048 
2049         loadPageVerifyTitle2(html);
2050     }
2051 
2052     /**
2053      * See issue #1685.
2054      *
2055      * @throws Exception if an error occurs
2056      */
2057     @Test
2058     @Alerts({"6", "3"})
2059     public void differentWhitespaceClassName() throws Exception {
2060         final String html = DOCTYPE_HTML
2061             + "<html><head>\n"
2062             + "</head><body>\n"
2063             + "  <input id='first' class='foo'>\n"
2064             + "  <input id='first' class='\tfoo\n'>\n"
2065             + "  <input id='first' class='foo bar'>\n"
2066             + "  <input id='second' class='foo\tbar'>\n"
2067             + "  <input id='third' class='foo\r\nbar'>\n"
2068 
2069             + "  <input id='third' class='foobar foo'>\n"
2070 
2071             + "  <input id='third' class='foobar'>\n"
2072             + "  <input id='third' class='abcfoobar'>\n"
2073             + "<script>\n"
2074             + LOG_TITLE_FUNCTION
2075             + "try {\n"
2076             + "  log(document.querySelectorAll('.foo').length);\n"
2077             + "  log(document.querySelectorAll('.bar').length);\n"
2078             + "} catch(e) { logEx(e) }\n"
2079             + "</script></body></html>";
2080 
2081         loadPageVerifyTitle2(html);
2082     }
2083 
2084     /**
2085      * @throws Exception if an error occurs
2086      */
2087     @Test
2088     @Alerts({"first", "second", "third"})
2089     public void escapedClassName() throws Exception {
2090         final String html = DOCTYPE_HTML
2091             + "<html><head>\n"
2092             + "</head><body>\n"
2093             + "  <input id='first' class='foo[bar]'>\n"
2094             + "  <input id='second' class='foo.bar'>\n"
2095             + "  <input id='third' class='foo:bar'>\n"
2096             + "<script>\n"
2097             + LOG_TITLE_FUNCTION
2098             + "try {\n"
2099             + "  log(document.querySelectorAll('.foo\\\\[bar\\\\]')[0].id);\n"
2100             + "  log(document.querySelectorAll('.foo\\\\.bar')[0].id);\n"
2101             + "  log(document.querySelectorAll('.foo\\\\:bar')[0].id);\n"
2102             + "} catch(e) { logEx(e) }\n"
2103             + "</script></body></html>";
2104 
2105         loadPageVerifyTitle2(html);
2106     }
2107 
2108     /**
2109      * @throws Exception if an error occurs
2110      */
2111     @Test
2112     @Alerts({"silly:id::with:colons", "silly:id::with:colons", "silly~id", "silly~id"})
2113     public void escapedId() throws Exception {
2114         final String html = DOCTYPE_HTML
2115             + "<html><head>\n"
2116             + "</head><body>\n"
2117             + "  <input id='silly:id::with:colons'>\n"
2118             + "  <input id='silly~id'>\n"
2119             + "<script>\n"
2120             + LOG_TITLE_FUNCTION
2121             + "try {\n"
2122             + "  log(document.querySelectorAll('#silly\\\\:id\\\\:\\\\:with\\\\:colons')[0].id);\n"
2123             + "  log(document.querySelectorAll(\"#silly\\\\:id\\\\:\\\\:with\\\\:colons\")[0].id);\n"
2124 
2125             + "  log(document.querySelectorAll('#silly\\\\~id')[0].id);\n"
2126             + "  log(document.querySelectorAll(\"#silly\\\\~id\")[0].id);\n"
2127             + "} catch(e) { logEx(e); }\n"
2128             + "</script></body></html>";
2129 
2130         loadPageVerifyTitle2(html);
2131     }
2132 
2133     /**
2134      * @throws Exception if an error occurs
2135      */
2136     @Test
2137     @Alerts("SyntaxError/DOMException")
2138     public void invalidSelectors() throws Exception {
2139         final String html = DOCTYPE_HTML
2140             + "<html><head>\n"
2141             + "<script>\n"
2142             + LOG_TITLE_FUNCTION
2143             + "function test() {\n"
2144             + "  try {\n"
2145             + "    var list = document.querySelectorAll('li:foo() ~ li');\n"
2146             + "    log(list.length);\n"
2147             + "  } catch(e) { logEx(e) }\n"
2148             + "}\n"
2149             + "</script></head>\n"
2150             + "<body onload='test()'>\n"
2151             + "<ul id='ul'>\n"
2152             + "  <li id='li1'></li>\n"
2153             + "  <li id='li2'></li>\n"
2154             + "</ul>\n"
2155             + "</body></html>";
2156 
2157         loadPageVerifyTitle2(html);
2158     }
2159 
2160     /**
2161      * @throws Exception if an error occurs
2162      */
2163     @Test
2164     @Alerts({"null", "null", "null"})
2165     public void activeEmptyDetached() throws Exception {
2166         emptyAndDetached("*:active");
2167         emptyAndDetached(":active");
2168     }
2169 
2170     /**
2171      * @throws Exception if an error occurs
2172      */
2173     @Test
2174     @Alerts({"null", "null", "null"})
2175     public void checkedEmptyDetached() throws Exception {
2176         emptyAndDetached("*:checked");
2177         emptyAndDetached(":checked");
2178     }
2179 
2180     /**
2181      * @throws Exception if an error occurs
2182      */
2183     @Test
2184     @Alerts({"null", "null", "null"})
2185     public void disabledEmptyDetached() throws Exception {
2186         emptyAndDetached("*:disabled");
2187         emptyAndDetached(":disabled");
2188     }
2189 
2190     /**
2191      * @throws Exception if an error occurs
2192      */
2193     @Test
2194     @Alerts({"null", "null", "[object HTMLSpanElement]"})
2195     public void emptyEmptyDetached() throws Exception {
2196         emptyAndDetached("*:empty");
2197         emptyAndDetached(":empty");
2198     }
2199 
2200     /**
2201      * @throws Exception if an error occurs
2202      */
2203     @Test
2204     @Alerts({"null", "null", "null"})
2205     public void enabledEmptyDetached() throws Exception {
2206         emptyAndDetached("*:enabled");
2207         emptyAndDetached(":enabled");
2208     }
2209 
2210     /**
2211      * @throws Exception if an error occurs
2212      */
2213     @Test
2214     @Alerts({"null", "null", "[object HTMLSpanElement]"})
2215     public void firstchildEmptyDetached() throws Exception {
2216         emptyAndDetached("*:first-child");
2217         emptyAndDetached(":first-child");
2218     }
2219 
2220     /**
2221      * @throws Exception if an error occurs
2222      */
2223     @Test
2224     @Alerts({"null", "null", "[object HTMLSpanElement]"})
2225     public void firstoftypeEmptyDetached() throws Exception {
2226         emptyAndDetached("*:first-of-type");
2227         emptyAndDetached(":first-of-type");
2228     }
2229 
2230     /**
2231      * @throws Exception if an error occurs
2232      */
2233     @Test
2234     @Alerts({"null", "null", "null"})
2235     public void focusEmptyDetached() throws Exception {
2236         emptyAndDetached("*:focus");
2237         emptyAndDetached(":focus");
2238     }
2239 
2240     /**
2241      * @throws Exception if an error occurs
2242      */
2243     @Test
2244     @Alerts({"null", "null", "null"})
2245     public void focusWithinEmptyDetached() throws Exception {
2246         emptyAndDetached("*:focus-within");
2247         emptyAndDetached(":focus-within");
2248     }
2249 
2250     /**
2251      * @throws Exception if an error occurs
2252      */
2253     @Test
2254     @Alerts({"null", "null", "null"})
2255     public void focusVisibleEmptyDetached() throws Exception {
2256         emptyAndDetached("*:focus-visible");
2257         emptyAndDetached(":focus-visible");
2258     }
2259 
2260     /**
2261      * @throws Exception if an error occurs
2262      */
2263     @Test
2264     @Alerts({"null", "null", "null"})
2265     public void hoverEmptyDetached() throws Exception {
2266         emptyAndDetached("*:hover");
2267         emptyAndDetached(":hover");
2268     }
2269 
2270     /**
2271      * @throws Exception if an error occurs
2272      */
2273     @Test
2274     @Alerts({"null", "null", "[object HTMLSpanElement]"})
2275     public void lastchildEmptyDetached() throws Exception {
2276         emptyAndDetached("*:last-child");
2277         emptyAndDetached(":last-child");
2278     }
2279 
2280     /**
2281      * @throws Exception if an error occurs
2282      */
2283     @Test
2284     @Alerts({"null", "null", "[object HTMLSpanElement]"})
2285     public void lastoftypeEmptyDetached() throws Exception {
2286         emptyAndDetached("*:last-of-type");
2287         emptyAndDetached(":last-of-type");
2288     }
2289 
2290     /**
2291      * @throws Exception if an error occurs
2292      */
2293     @Test
2294     @Alerts({"null", "null", "null"})
2295     public void linkEmptyDetached() throws Exception {
2296         emptyAndDetached("*:link");
2297         emptyAndDetached(":link");
2298     }
2299 
2300     /**
2301      * @throws Exception if an error occurs
2302      */
2303     @Test
2304     @Alerts({"null", "null", "[object HTMLSpanElement]"})
2305     public void notEmptyDetached() throws Exception {
2306         emptyAndDetached("*:not(p)");
2307         emptyAndDetached(":not(p)");
2308     }
2309 
2310     /**
2311      * @throws Exception if an error occurs
2312      */
2313     @Test
2314     @Alerts({"null", "null", "null"})
2315     public void nthchildEmptyDetached() throws Exception {
2316         emptyAndDetached("*:nth-child(2n)");
2317         emptyAndDetached(":nth-child(2n)");
2318     }
2319 
2320     /**
2321      * @throws Exception if an error occurs
2322      */
2323     @Test
2324     @Alerts({"null", "null", "null"})
2325     public void nthlastchildEmptyDetached() throws Exception {
2326         emptyAndDetached("*:nth-last-child(2n)");
2327         emptyAndDetached(":nth-last-child(2n)");
2328     }
2329 
2330     /**
2331      * @throws Exception if an error occurs
2332      */
2333     @Test
2334     @Alerts({"null", "null", "null"})
2335     public void nthoftypeEmptyDetached() throws Exception {
2336         emptyAndDetached("*:nth-of-type(2n)");
2337         emptyAndDetached(":nth-of-type(2n)");
2338     }
2339 
2340     /**
2341      * @throws Exception if an error occurs
2342      */
2343     @Test
2344     @Alerts({"null", "null", "[object HTMLSpanElement]"})
2345     public void onlychildEmptyDetached() throws Exception {
2346         emptyAndDetached("*:only-child");
2347         emptyAndDetached(":only-child");
2348     }
2349 
2350     /**
2351      * @throws Exception if an error occurs
2352      */
2353     @Test
2354     @Alerts({"null", "null", "[object HTMLSpanElement]"})
2355     public void onlyoftypeEmptyDetached() throws Exception {
2356         emptyAndDetached("*:only-of-type");
2357         emptyAndDetached(":only-of-type");
2358     }
2359 
2360     /**
2361      * @throws Exception if an error occurs
2362      */
2363     @Test
2364     @Alerts({"null", "null", "null"})
2365     public void rootEmptyDetached() throws Exception {
2366         emptyAndDetached("*:root");
2367         emptyAndDetached(":root");
2368     }
2369 
2370     /**
2371      * @throws Exception if an error occurs
2372      */
2373     @Test
2374     @Alerts({"null", "null", "null"})
2375     public void visitedEmptyDetached() throws Exception {
2376         emptyAndDetached("*:visited");
2377         emptyAndDetached(":visited");
2378     }
2379 
2380     private void emptyAndDetached(final String selector) throws Exception {
2381         final String html = DOCTYPE_HTML
2382             + "<html><head>\n"
2383             + "<script>\n"
2384             + LOG_TITLE_FUNCTION
2385             + "function test() {\n"
2386             + "  var div = document.getElementById('myDiv');\n"
2387             + "  try {\n"
2388             + "    found = div.querySelector('" + selector + "');\n"
2389             + "    log(found);\n"
2390             + "  } catch(e) { logEx(e) }\n"
2391 
2392             + "  div = document.createElement('div');\n"
2393             + "  try {\n"
2394             + "    found = div.querySelector('" + selector + "');\n"
2395             + "    log(found);\n"
2396             + "  } catch(e) { logEx(e) }\n"
2397 
2398             + "  var input = document.createElement('span');\n"
2399             + "  div.appendChild(input);\n"
2400             + "  try {\n"
2401             + "    found = div.querySelector('" + selector + "');\n"
2402             + "    log(found);\n"
2403             + "  } catch(e) { logEx(e) }\n"
2404             + "}\n"
2405             + "</script></head>\n"
2406             + "<body onload='test()'>\n"
2407             + "  <div id='myDiv'></myDiv>\n"
2408             + "</body></html>";
2409 
2410         loadPageVerifyTitle2(html);
2411     }
2412 
2413     /**
2414      * @throws Exception if an error occurs
2415      */
2416     @Test
2417     @Alerts({"2", "<nested>Three</nested>", "Four",
2418              "1", "Two", "0", "0"})
2419     public void xmlTagName() throws Exception {
2420         final String html = DOCTYPE_HTML
2421             + "<html><head>\n"
2422             + "</head><body>\n"
2423             + "<script>\n"
2424             + LOG_TITLE_FUNCTION
2425             + "  var xmlString = [\n"
2426             + "                 '<ResultSet>',\n"
2427             + "                 '<Result>One</Result>',\n"
2428             + "                 '<RESULT>Two</RESULT>',\n"
2429             + "                 '<result><nested>Three</nested></result>',\n"
2430             + "                 '<result>Four</result>',\n"
2431             + "                 '</ResultSet>'\n"
2432             + "                ].join('');\n"
2433             + "  var parser = new DOMParser();\n"
2434             + "  xml = parser.parseFromString(xmlString, 'text/xml');\n"
2435             + "  var xmlDoc = parser.parseFromString(xmlString, 'text/xml');\n"
2436             + "  var de = xmlDoc.documentElement;\n"
2437             + "  try {\n"
2438 
2439             + "    var res = de.querySelectorAll('result');\n"
2440             + "    log(res.length);\n"
2441             + "    log(res[0].innerHTML);\n"
2442             + "    log(res[1].innerHTML);\n"
2443 
2444             + "    res = de.querySelectorAll('RESULT');\n"
2445             + "    log(res.length);\n"
2446             + "    log(res[0].innerHTML);\n"
2447 
2448             + "    res = de.querySelectorAll('resulT');\n"
2449             + "    log(res.length);\n"
2450 
2451             + "    res = de.querySelectorAll('rEsulT');\n"
2452             + "    log(res.length);\n"
2453             + "  } catch(e) { logEx(e); }\n"
2454             + "</script></body></html>";
2455 
2456         loadPageVerifyTitle2(html);
2457     }
2458 
2459     /**
2460      * @throws Exception if an error occurs
2461      */
2462     @Test
2463     @Alerts({"2", "ONE", "<CHILD>Two</CHILD>",
2464              "0",
2465              "2", "ONE", "<CHILD>Two</CHILD>",
2466              "1", "ONE",
2467              "1", "Two"})
2468     public void xmlAttribute() throws Exception {
2469         final String html = DOCTYPE_HTML
2470             + "<html><head>\n"
2471             + "</head><body>\n"
2472             + "<script>\n"
2473             + LOG_TITLE_FUNCTION
2474             + "  var xmlString = [\n"
2475             + "                 '<ResultSet>',\n"
2476             + "                 '<RESULT thinger=\"blah\">ONE</RESULT>',\n"
2477             + "                 '<RESULT thinger=\"gadzooks\"><CHILD>Two</CHILD></RESULT>',\n"
2478             + "                 '</ResultSet>'\n"
2479             + "                ].join('');\n"
2480             + "  var parser = new DOMParser();\n"
2481             + "  xml = parser.parseFromString(xmlString, 'text/xml');\n"
2482             + "  var xmlDoc = parser.parseFromString(xmlString, 'text/xml');\n"
2483             + "  var de = xmlDoc.documentElement;\n"
2484             + "  try {\n"
2485 
2486             + "    var res = de.querySelectorAll('RESULT');\n"
2487             + "    log(res.length);\n"
2488             + "    log(res[0].innerHTML);\n"
2489             + "    log(res[1].innerHTML);\n"
2490 
2491             + "    res = de.querySelectorAll('RESULT[THINGER]');\n"
2492             + "    log(res.length);\n"
2493 
2494             + "    res = de.querySelectorAll('RESULT[thinger]');\n"
2495             + "    log(res.length);\n"
2496             + "    log(res[0].innerHTML);\n"
2497             + "    log(res[1].innerHTML);\n"
2498 
2499             + "    res = de.querySelectorAll('RESULT[thinger=blah]');\n"
2500             + "    log(res.length);\n"
2501             + "    log(res[0].innerHTML);\n"
2502 
2503             + "    res = de.querySelectorAll('RESULT > CHILD');\n"
2504             + "    log(res.length);\n"
2505             + "    log(res[0].innerHTML);\n"
2506 
2507             + "  } catch(e) { logEx(e); }\n"
2508             + "</script></body></html>";
2509 
2510         loadPageVerifyTitle2(html);
2511     }
2512 
2513     /**
2514      * @throws Exception if an error occurs
2515      */
2516     @Test
2517     @Alerts({"SyntaxError/DOMException", "SyntaxError/DOMException"})
2518     public void querySelector_invalid() throws Exception {
2519         final String html = DOCTYPE_HTML
2520             + "<html><head>\n"
2521             + "<script>\n"
2522             + LOG_TITLE_FUNCTION
2523             + "function test() {\n"
2524             + "  try {\n"
2525             + "    log(document.querySelectorAll('#foo > :not(:first)'));\n"
2526             + "  } catch(e) { logEx(e) }\n"
2527             + "  try {\n"
2528             + "    log(document.querySelector('#foo > :not(:first)'));\n"
2529             + "  } catch(e) { logEx(e) }\n"
2530             + "}\n"
2531             + "</script></head>\n"
2532             + "<body onload='test()'>\n"
2533             + "<ul id='foo'>\n"
2534             + "  <li id='li1'></li>\n"
2535             + "  <li id='li2'></li>\n"
2536             + "  <li id='li3'></li>\n"
2537             + "</ul>\n"
2538             + "</body></html>";
2539 
2540         loadPageVerifyTitle2(html);
2541     }
2542 
2543     /**
2544      * @throws Exception if an error occurs
2545      */
2546     @Test
2547     @Alerts({"2", "S1", "S2",
2548              "2", "S1", "S2",
2549              "2", "S1", "S2",
2550              "2", "S1", "S2"})
2551     public void typeSubmit() throws Exception {
2552         final String html = DOCTYPE_HTML
2553             + "<html><head>\n"
2554             + "<script>\n"
2555             + LOG_TITLE_FUNCTION
2556             + "function test() {\n"
2557             + "  var list = document.querySelectorAll('button[type=\"submit\"]');\n"
2558             + "  log(list.length);\n"
2559             + "  log(list[0].innerHTML);\n"
2560             + "  log(list[1].innerHTML );\n"
2561 
2562             + "  var list = document.querySelectorAll('button[type=\"SubMit\"]');\n"
2563             + "  log(list.length);\n"
2564             + "  log(list[0].innerHTML);\n"
2565             + "  log(list[1].innerHTML );\n"
2566 
2567             + "  var list = document.querySelectorAll('button[type=\"SUBmit\"]');\n"
2568             + "  log(list.length);\n"
2569             + "  log(list[0].innerHTML);\n"
2570             + "  log(list[1].innerHTML );\n"
2571 
2572             + "  var list = document.querySelectorAll('button[type=\"SUBmit\" i]');\n"
2573             + "  log(list.length);\n"
2574             + "  log(list[0].innerHTML);\n"
2575             + "  log(list[1].innerHTML );\n"
2576             + "}\n"
2577             + "</script>\n"
2578             + "</head>\n"
2579             + "<body onload='test()'>\n"
2580             + "  <button>None</button>\n"
2581             + "  <button type=''>Empty</button>\n"
2582             + "  <button type='submit'>S1</button>\n"
2583             + "  <button type='SubMit'>S2</button>\n"
2584             + "</body></html>";
2585 
2586         loadPageVerifyTitle2(html);
2587     }
2588 
2589     /**
2590      * @throws Exception if an error occurs
2591      */
2592     @Test
2593     @Alerts({"1", "I1"})
2594     public void buttonTypeInvalid() throws Exception {
2595         final String html = DOCTYPE_HTML
2596             + "<html><head>\n"
2597             + "<script>\n"
2598             + LOG_TITLE_FUNCTION
2599             + "function test() {\n"
2600             + "  var list = document.querySelectorAll('button[type=\"invalid\"]');\n"
2601             + "  log(list.length);\n"
2602             + "  log(list[0].innerHTML);\n"
2603             + "}\n"
2604             + "</script>\n"
2605             + "</head>\n"
2606             + "<body onload='test()'>\n"
2607             + "  <button>None</button>\n"
2608             + "  <button type=''>Empty</button>\n"
2609             + "  <button type='submit'>S1</button>\n"
2610             + "  <button type='invalid'>I1</button>\n"
2611             + "</body></html>";
2612 
2613         loadPageVerifyTitle2(html);
2614     }
2615 }