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