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