View Javadoc
1   /*
2    * Copyright (c) 2002-2025 Gargoyle Software Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * https://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  package org.htmlunit.javascript.host.dom;
16  
17  import org.htmlunit.WebDriverTestCase;
18  import org.htmlunit.junit.annotation.Alerts;
19  import org.junit.jupiter.api.Test;
20  
21  /**
22   * Tests for {@link NodeList}.
23   *
24   * @author Ahmed Ashour
25   * @author Ronald Brill
26   * @author Lai Quang Duong
27   */
28  public class NodeListTest extends WebDriverTestCase {
29  
30      /**
31       * @throws Exception on test failure
32       */
33      @Test
34      @Alerts("[object NodeList]")
35      public void defaultValue() throws Exception {
36          final String html = DOCTYPE_HTML
37                  + "<html><head>\n"
38                  + "<script>\n"
39                  + LOG_TITLE_FUNCTION
40                  + "  function test() {\n"
41                  + "    log(document.getElementById('myId').firstChild.childNodes);\n"
42                  + "  }\n"
43                  + "</script>\n"
44                  + "</head><body onload='test()'>\n"
45                  + "  <div id='myId'>abcd</div>\n"
46                  + "</body></html>";
47  
48          loadPageVerifyTitle2(html);
49      }
50  
51      /**
52       * @throws Exception on test failure
53       */
54      @Test
55      @Alerts({"true", "true", "false", "true", "true", "true", "true", "true", "true"})
56      public void has() throws Exception {
57          final String html = DOCTYPE_HTML
58                  + "<html><head>\n"
59                  + "<script>\n"
60                  + LOG_TITLE_FUNCTION
61                  + "  function test() {\n"
62                  + "    var nodeList = document.querySelectorAll('*');\n"
63                  + "    log(0 in nodeList);\n"
64                  + "    log(3 in nodeList);\n"
65                  + "    log(4 in nodeList);\n"
66  
67                  + "    log('entries' in nodeList);\n"
68                  + "    log('forEach' in nodeList);\n"
69                  + "    log('item' in nodeList);\n"
70                  + "    log('keys' in nodeList);\n"
71                  + "    log('length' in nodeList);\n"
72                  + "    log('values' in nodeList);\n"
73                  + "  }\n"
74                  + "</script>\n"
75                  + "</head><body onload='test()'>\n"
76                  + "</body></html>";
77  
78          loadPageVerifyTitle2(html);
79      }
80  
81      /**
82       * @throws Exception on test failure
83       */
84      @Test
85      @Alerts({"4", "true", "undefined"})
86      public void length() throws Exception {
87          final String html = DOCTYPE_HTML
88                  + "<html><head>\n"
89                  + "<script>\n"
90                  + LOG_TITLE_FUNCTION
91                  + "  function test() {\n"
92                  + "    var nodeList = document.querySelectorAll('*');\n"
93                  + "    log(nodeList.length);\n"
94  
95                  + "    log('length' in nodeList);\n"
96                  + "    log(Object.getOwnPropertyDescriptor(nodeList, 'length'));\n"
97                  + "  }\n"
98                  + "</script>\n"
99                  + "</head><body onload='test()'>\n"
100                 + "</body></html>";
101 
102         loadPageVerifyTitle2(html);
103     }
104 
105     /**
106      * @throws Exception on test failure
107      */
108     @Test
109     @Alerts({"[object HTMLHtmlElement]", "[object HTMLScriptElement]", "null", "null"})
110     public void item() throws Exception {
111         final String html = DOCTYPE_HTML
112                 + "<html><head>\n"
113                 + "<script>\n"
114                 + LOG_TITLE_FUNCTION
115                 + "  function test() {\n"
116                 + "    var nodeList = document.querySelectorAll('*');\n"
117                 + "    log(nodeList.item(0));\n"
118                 + "    log(nodeList.item(2));\n"
119                 + "    log(nodeList.item(17));\n"
120                 + "    log(nodeList.item(-1));\n"
121                 + "  }\n"
122                 + "</script>\n"
123                 + "</head><body onload='test()'>\n"
124                 + "  <div></div>\n"
125                 + "</body></html>";
126 
127         loadPageVerifyTitle2(html);
128     }
129 
130     /**
131      * @throws Exception on test failure
132      */
133     @Test
134     @Alerts({"[object HTMLHtmlElement]", "[object HTMLScriptElement]", "undefined", "undefined"})
135     public void itemBracketed() throws Exception {
136         final String html = DOCTYPE_HTML
137                 + "<html><head>\n"
138                 + "<script>\n"
139                 + LOG_TITLE_FUNCTION
140                 + "  function test() {\n"
141                 + "    var nodeList = document.querySelectorAll('*');\n"
142                 + "    log(nodeList[0]);\n"
143                 + "    log(nodeList[2]);\n"
144                 + "    log(nodeList[17]);\n"
145                 + "    log(nodeList[-1]);\n"
146                 + "  }\n"
147                 + "</script>\n"
148                 + "</head><body onload='test()'>\n"
149                 + "  <div></div>\n"
150                 + "</body></html>";
151 
152         loadPageVerifyTitle2(html);
153     }
154 
155     /**
156      * @throws Exception on test failure
157      */
158     @Test
159     @Alerts("0,1,2,3,4,entries,forEach,item,keys,length,values")
160     public void forIn() throws Exception {
161         final String html = DOCTYPE_HTML
162                 + "<html><head>\n"
163                 + "<script>\n"
164                 + LOG_TITLE_FUNCTION
165                 + "  function test() {\n"
166                 + "    var all = [];\n"
167                 + "    for (var i in document.querySelectorAll('*')) {\n"
168                 + "      all.push(i);\n"
169                 + "    }\n"
170                 + "    all.sort(sortFunction);\n"
171                 + "    log(all);\n"
172                 + "  }\n"
173                 + "  function sortFunction(s1, s2) {\n"
174                 + "    return s1.toLowerCase() > s2.toLowerCase() ? 1 : -1;\n"
175                 + "  }\n"
176                 + "</script>\n"
177                 + "</head><body onload='test()'>\n"
178                 + "  <div></div>\n"
179                 + "</body></html>";
180 
181         loadPageVerifyTitle2(html);
182     }
183 
184     /**
185      * @throws Exception on test failure
186      */
187     @Test
188     @Alerts("entries,forEach,item,keys,length,values")
189     public void forInEmptyList() throws Exception {
190         final String html = DOCTYPE_HTML
191                 + "<html><head>\n"
192                 + "<script>\n"
193                 + LOG_TITLE_FUNCTION
194                 + "  function test() {\n"
195                 + "    var all = [];\n"
196                 + "    for (var i in document.querySelectorAll('.notThere')) {\n"
197                 + "      all.push(i);\n"
198                 + "    }\n"
199                 + "    all.sort(sortFunction);\n"
200                 + "    log(all);\n"
201                 + "  }\n"
202                 + "  function sortFunction(s1, s2) {\n"
203                 + "    return s1.toLowerCase() > s2.toLowerCase() ? 1 : -1;\n"
204                 + "  }\n"
205                 + "</script>\n"
206                 + "</head><body onload='test()'>\n"
207                 + "  <div></div>\n"
208                 + "</body></html>";
209 
210         loadPageVerifyTitle2(html);
211     }
212 
213     /**
214      * @throws Exception on test failure
215      */
216     @Test
217     @Alerts({"true", "[object HTMLHtmlElement]", "[object HTMLHeadElement]",
218              "[object HTMLScriptElement]", "[object HTMLBodyElement]",
219              "[object HTMLDivElement]"})
220     public void iterator() throws Exception {
221         final String html = DOCTYPE_HTML
222                 + "<html><head>\n"
223                 + "<script>\n"
224                 + LOG_TITLE_FUNCTION
225                 + "  function test() {\n"
226                 + "    var nodeList = document.querySelectorAll('*');\n"
227 
228                 + "    if (typeof Symbol != 'undefined') {\n"
229                 + "      log(nodeList[Symbol.iterator] === nodeList.values);\n"
230                 + "    }\n"
231 
232                 + "    if (!nodeList.forEach) {\n"
233                 + "      log('no for..of');\n"
234                 + "      return;\n"
235                 + "    }\n"
236 
237                 + "    for (var i of nodeList) {\n"
238                 + "      log(i);\n"
239                 + "    }\n"
240                 + "  }\n"
241                 + "</script>\n"
242                 + "</head><body onload='test()'>\n"
243                 + "  <div></div>\n"
244                 + "</body></html>";
245 
246         loadPageVerifyTitle2(html);
247     }
248 
249     /**
250      * @throws Exception if an error occurs
251      */
252     @Test
253     @Alerts({"[object HTMLHtmlElement] 0 [object NodeList] undefined",
254              "[object HTMLHeadElement] 1 [object NodeList] undefined",
255              "[object HTMLScriptElement] 2 [object NodeList] undefined",
256              "[object HTMLBodyElement] 3 [object NodeList] undefined",
257              "[object HTMLDivElement] 4 [object NodeList] undefined"})
258     public void forEach() throws Exception {
259         final String html = DOCTYPE_HTML
260             + "<html><head>\n"
261             + "<script>\n"
262             + LOG_TITLE_FUNCTION
263             + "  function test() {\n"
264             + "    var nodeList = document.querySelectorAll('*');\n"
265             + "    if (nodeList.forEach) {\n"
266             + "      nodeList.forEach(myFunction, 'something');\n"
267             + "    } else {\n"
268             + "      log('no forEach');\n"
269             + "    }\n"
270             + "  }\n"
271             + "  function myFunction(value, index, list, arg) {\n"
272             + "    log(value + ' ' + index + ' ' + list + ' ' + arg);\n"
273             + "  }\n"
274             + "</script>\n"
275             + "</head><body onload='test()'>\n"
276             + "  <div></div>\n"
277             + "</body></html>";
278 
279         loadPageVerifyTitle2(html);
280     }
281 
282     /**
283      * @throws Exception if an error occurs
284      */
285     @Test
286     @Alerts({"4", "4",
287              "[object HTMLElement]/0", "3", "3",
288              "[object HTMLElement]/1", "2", "2",
289              "2", "2"})
290     public void forEachRemove() throws Exception {
291         final String html = DOCTYPE_HTML
292                 + "<html><head>\n"
293                 + "<script>\n"
294                 + LOG_TITLE_FUNCTION
295                 + "  function test() {\n"
296                 + "    var nodeList = document.getElementById('myId').childNodes;\n"
297                 + "    if (nodeList.forEach) {\n"
298                 + "      log(document.getElementById('myId').childNodes.length);\n"
299                 + "      log(nodeList.length);\n"
300 
301                 + "      nodeList.forEach(myFunction);\n"
302 
303                 + "      log(document.getElementById('myId').childNodes.length);\n"
304                 + "      log(nodeList.length);\n"
305                 + "    } else {\n"
306                 + "      log('no forEach');\n"
307                 + "    }\n"
308                 + "  }\n"
309 
310                 + "  function myFunction(value, index, list, arg) {\n"
311                 + "    log(value + '/' + index);\n"
312                 + "    document.getElementById('myId').removeChild(value);\n"
313                 + "    log(document.getElementById('myId').childNodes.length);\n"
314                 + "    log(list.length);\n"
315                 + "  }\n"
316                 + "</script>\n"
317                 + "</head><body onload='test()'>\n"
318                 + "  <div id='myId'><strong>a</strong>b<b>d</b>e</div>\n"
319                 + "</body></html>";
320 
321         loadPageVerifyTitle2(html);
322     }
323 
324     /**
325      * @throws Exception if an error occurs
326      */
327     @Test
328     @Alerts({"4", "4",
329              "[object HTMLElement]/0", "5", "5",
330              "[object Text]/1", "6", "6",
331              "[object HTMLElement]/2", "7", "7",
332              "[object Text]/3", "8", "8",
333              "8", "8"})
334     public void forEachAppend() throws Exception {
335         final String html = DOCTYPE_HTML
336                 + "<html><head>\n"
337                 + "<script>\n"
338                 + LOG_TITLE_FUNCTION
339                 + "  function test() {\n"
340                 + "    var nodeList = document.getElementById('myId').childNodes;\n"
341                 + "    if (nodeList.forEach) {\n"
342                 + "      log(document.getElementById('myId').childNodes.length);\n"
343                 + "      log(nodeList.length);\n"
344 
345                 + "      nodeList.forEach(myFunction);\n"
346 
347                 + "      log(document.getElementById('myId').childNodes.length);\n"
348                 + "      log(nodeList.length);\n"
349                 + "    } else {\n"
350                 + "      log('no forEach');\n"
351                 + "    }\n"
352                 + "  }\n"
353 
354                 + "  function myFunction(value, index, list, arg) {\n"
355                 + "    log(value + '/' + index);\n"
356                 + "    if (index < 4) {\n"
357                 + "      document.getElementById('myId').appendChild(document.createElement('p'));\n"
358                 + "    }\n"
359                 + "    log(document.getElementById('myId').childNodes.length);\n"
360                 + "    log(list.length);\n"
361                 + "  }\n"
362                 + "</script>\n"
363                 + "</head><body onload='test()'>\n"
364                 + "  <div id='myId'><strong>a</strong>b<b>d</b>e</div>\n"
365                 + "</body></html>";
366 
367         loadPageVerifyTitle2(html);
368     }
369 
370     /**
371      * @throws Exception if an error occurs
372      */
373     @Test
374     @Alerts({"4", "4",
375              "[object HTMLElement]/0", "5", "5",
376              "[object HTMLElement]/1", "6", "6",
377              "[object HTMLElement]/2", "7", "7",
378              "[object HTMLElement]/3", "8", "8",
379              "8", "8"})
380     public void forEachInsert() 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 nodeList = document.getElementById('myId').childNodes;\n"
387                 + "    if (nodeList.forEach) {\n"
388                 + "      log(document.getElementById('myId').childNodes.length);\n"
389                 + "      log(nodeList.length);\n"
390 
391                 + "      nodeList.forEach(myFunction);\n"
392 
393                 + "      log(document.getElementById('myId').childNodes.length);\n"
394                 + "      log(nodeList.length);\n"
395                 + "    } else {\n"
396                 + "      log('no forEach');\n"
397                 + "    }\n"
398                 + "  }\n"
399 
400                 + "  function myFunction(value, index, list, arg) {\n"
401                 + "    log(value + '/' + index);\n"
402                 + "    if (index < 4) {\n"
403                 + "      document.getElementById('myId').insertBefore(document.createElement('p'), value);\n"
404                 + "    }\n"
405                 + "    log(document.getElementById('myId').childNodes.length);\n"
406                 + "    log(list.length);\n"
407                 + "  }\n"
408                 + "</script>\n"
409                 + "</head><body onload='test()'>\n"
410                 + "  <div id='myId'><strong>a</strong>b<b>d</b>e</div>\n"
411                 + "</body></html>";
412 
413         loadPageVerifyTitle2(html);
414     }
415 
416     /**
417      * @throws Exception if the test fails
418      */
419     @Test
420     @Alerts({"TypeError", "TypeError"})
421     public void forEachWrongParam() throws Exception {
422         final String html = DOCTYPE_HTML
423                 + "<html><head><script>\n"
424                 + LOG_TITLE_FUNCTION
425                 + "function test() {\n"
426                 + "  var nodeList = document.querySelectorAll('*');\n"
427                 + "  try {\n"
428                 + "    nodeList.forEach();\n"
429                 + "  } catch(e) { logEx(e); }\n"
430                 + "  try {\n"
431                 + "    nodeList.forEach('wrong');\n"
432                 + "  } catch(e) { logEx(e); }\n"
433                 + "}\n"
434                 + "</script></head><body onload='test()'>\n"
435                 + "  <div id='d1' class=' a b \t c \n d \u000B e \u000C f \r g'></div>\n"
436                 + "</body></html>";
437 
438         loadPageVerifyTitle2(html);
439     }
440 
441     /**
442      * @throws Exception if an error occurs
443      */
444     @Test
445     @Alerts({"value", "done", "object", "0", "[object HTMLHtmlElement]"})
446     public void entries() throws Exception {
447         final String html = DOCTYPE_HTML
448             + "<html><head>\n"
449             + "<script>\n"
450             + LOG_TITLE_FUNCTION
451             + "  function test() {\n"
452             + "    var nodeList = document.querySelectorAll('*');\n"
453             + "    if (!nodeList.entries) {\n"
454             + "      log('not defined');\n"
455             + "      return;\n"
456             + "    }\n"
457             + "    var i = nodeList.entries().next();\n"
458             + "    for (var x in i) {\n"
459             + "      log(x);\n"
460             + "    }\n"
461             + "    var v = i.value;\n"
462             + "    log(typeof v);\n"
463             + "    log(v[0]);\n"
464             + "    log(v[1]);\n"
465             + "  }\n"
466             + "</script>\n"
467             + "</head><body onload='test()'>\n"
468             + "</body></html>\n";
469 
470         loadPageVerifyTitle2(html);
471     }
472 
473     /**
474      * @throws Exception if an error occurs
475      */
476     @Test
477     @Alerts({"true", "undefined", "function", "undefined", "undefined", "true", "true", "true"})
478     public void entriesPropertyDescriptor() throws Exception {
479         final String html = DOCTYPE_HTML
480             + "<html><head>\n"
481             + "<script>\n"
482             + LOG_TITLE_FUNCTION
483             + "  function test() {\n"
484             + "    var nodeList = document.querySelectorAll('*');\n"
485 
486             + "    log('entries' in nodeList);\n"
487             + "    log(Object.getOwnPropertyDescriptor(nodeList, 'entries'));\n"
488 
489             + "    var desc = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(nodeList), 'entries');\n"
490             + "    if (desc === undefined) { log('no entries'); return; }\n"
491             + "    log(typeof desc.value);\n"
492             + "    log(desc.get);\n"
493             + "    log(desc.set);\n"
494             + "    log(desc.writable);\n"
495             + "    log(desc.enumerable);\n"
496             + "    log(desc.configurable);\n"
497             + "  }\n"
498             + "</script>\n"
499             + "</head><body onload='test()'>\n"
500             + "</body></html>\n";
501 
502         loadPageVerifyTitle2(html);
503     }
504 
505     /**
506      * @throws Exception if an error occurs
507      */
508     @Test
509     @Alerts({"0,[object HTMLHtmlElement]", "1,[object HTMLHeadElement]",
510              "2,[object HTMLScriptElement]", "3,[object HTMLBodyElement]"})
511     public void entriesForOf() throws Exception {
512         final String html = DOCTYPE_HTML
513             + "<html><head>\n"
514             + "<script>\n"
515             + LOG_TITLE_FUNCTION
516             + "  function test() {\n"
517             + "    var nodeList = document.querySelectorAll('*');\n"
518             + "    if (!nodeList.entries) {\n"
519             + "      log('not defined');\n"
520             + "      return;\n"
521             + "    }\n"
522             + "    for (var i of nodeList.entries()) {\n"
523             + "      log(i);\n"
524             + "    }\n"
525             + "  }\n"
526             + "</script>\n"
527             + "</head><body onload='test()'>\n"
528             + "</body></html>\n";
529 
530         loadPageVerifyTitle2(html);
531     }
532 
533     /**
534      * @throws Exception if an error occurs
535      */
536     @Test
537     @Alerts({"value", "done", "number", "0"})
538     public void keys() throws Exception {
539         final String html = DOCTYPE_HTML
540             + "<html><head>\n"
541             + "<script>\n"
542             + LOG_TITLE_FUNCTION
543             + "  function test() {\n"
544             + "    var nodeList = document.querySelectorAll('*');\n"
545             + "    if (!nodeList.keys) {\n"
546             + "      log('not defined');\n"
547             + "      return;\n"
548             + "    }\n"
549             + "    var i = nodeList.keys().next();\n"
550             + "    for (var x in i) {\n"
551             + "      log(x);\n"
552             + "    }\n"
553             + "    var v = i.value;\n"
554             + "    log(typeof v);\n"
555             + "    log(v);\n"
556             + "  }\n"
557             + "</script>\n"
558             + "</head><body onload='test()'>\n"
559             + "</body></html>\n";
560 
561         loadPageVerifyTitle2(html);
562     }
563 
564     /**
565      * @throws Exception if an error occurs
566      */
567     @Test
568     @Alerts({"true", "undefined", "function", "undefined", "undefined", "true", "true", "true"})
569     public void keysPropertyDescriptor() throws Exception {
570         final String html = DOCTYPE_HTML
571             + "<html><head>\n"
572             + "<script>\n"
573             + LOG_TITLE_FUNCTION
574             + "  function test() {\n"
575             + "    var nodeList = document.querySelectorAll('*');\n"
576 
577             + "    log('keys' in nodeList);\n"
578             + "    log(Object.getOwnPropertyDescriptor(nodeList, 'keys'));\n"
579 
580             + "    var desc = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(nodeList), 'keys');\n"
581             + "    if (desc === undefined) { log('no keys'); return; }\n"
582             + "    log(typeof desc.value);\n"
583             + "    log(desc.get);\n"
584             + "    log(desc.set);\n"
585             + "    log(desc.writable);\n"
586             + "    log(desc.enumerable);\n"
587             + "    log(desc.configurable);\n"
588             + "  }\n"
589             + "</script>\n"
590             + "</head><body onload='test()'>\n"
591             + "</body></html>\n";
592 
593         loadPageVerifyTitle2(html);
594     }
595 
596     /**
597      * @throws Exception if an error occurs
598      */
599     @Test
600     @Alerts({"0", "1", "2", "3"})
601     public void keysForOf() throws Exception {
602         final String html = DOCTYPE_HTML
603             + "<html><head>\n"
604             + "<script>\n"
605             + LOG_TITLE_FUNCTION
606             + "  function test() {\n"
607             + "    var nodeList = document.querySelectorAll('*');\n"
608             + "    if (!nodeList.keys) {\n"
609             + "      log('not defined');\n"
610             + "      return;\n"
611             + "    }\n"
612             + "    for (var i of nodeList.keys()) {\n"
613             + "      log(i);\n"
614             + "    }\n"
615             + "  }\n"
616             + "</script>\n"
617             + "</head><body onload='test()'>\n"
618             + "</body></html>\n";
619 
620         loadPageVerifyTitle2(html);
621     }
622 
623     /**
624      * @throws Exception if an error occurs
625      */
626     @Test
627     @Alerts({"0,1,2,3", ""})
628     public void objectKeys() throws Exception {
629         final String html = DOCTYPE_HTML
630             + "<html><head>\n"
631             + "<script>\n"
632             + LOG_TITLE_FUNCTION
633             + "  function test() {\n"
634             + "    var nodeList = document.querySelectorAll('*');\n"
635             + "    log(Object.keys(nodeList));\n"
636 
637             + "    nodeList = document.querySelectorAll('.notThere');\n"
638             + "    log(Object.keys(nodeList));\n"
639             + "  }\n"
640             + "</script>\n"
641             + "</head><body onload='test()'>\n"
642             + "</body></html>\n";
643 
644         loadPageVerifyTitle2(html);
645     }
646 
647     /**
648      * @throws Exception if an error occurs
649      */
650     @Test
651     @Alerts({"value", "done", "object", "[object HTMLHtmlElement]"})
652     public void values() 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 nodeList = document.querySelectorAll('*');\n"
659             + "    if (!nodeList.values) {\n"
660             + "      log('not defined');\n"
661             + "      return;\n"
662             + "    }\n"
663             + "    var i = nodeList.values().next();\n"
664             + "    for (var x in i) {\n"
665             + "      log(x);\n"
666             + "    }\n"
667             + "    var v = i.value;\n"
668             + "    log(typeof v);\n"
669             + "    log(v);\n"
670             + "  }\n"
671             + "</script>\n"
672             + "</head><body onload='test()'>\n"
673             + "</body></html>\n";
674 
675         loadPageVerifyTitle2(html);
676     }
677 
678     /**
679      * @throws Exception if an error occurs
680      */
681     @Test
682     @Alerts({"true", "undefined", "function", "undefined", "undefined", "true", "true", "true"})
683     public void valuesPropertyDescriptor() throws Exception {
684         final String html = DOCTYPE_HTML
685             + "<html><head>\n"
686             + "<script>\n"
687             + LOG_TITLE_FUNCTION
688             + "  function test() {\n"
689             + "    var nodeList = document.querySelectorAll('*');\n"
690 
691             + "    log('values' in nodeList);\n"
692             + "    log(Object.getOwnPropertyDescriptor(nodeList, 'values'));\n"
693 
694             + "    var desc = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(nodeList), 'values');\n"
695             + "    if (desc === undefined) { log('no values'); return; }\n"
696             + "    log(typeof desc.value);\n"
697             + "    log(desc.get);\n"
698             + "    log(desc.set);\n"
699             + "    log(desc.writable);\n"
700             + "    log(desc.enumerable);\n"
701             + "    log(desc.configurable);\n"
702             + "  }\n"
703             + "</script>\n"
704             + "</head><body onload='test()'>\n"
705             + "</body></html>\n";
706 
707         loadPageVerifyTitle2(html);
708     }
709 
710     /**
711      * @throws Exception if an error occurs
712      */
713     @Test
714     @Alerts({"[object HTMLHtmlElement]", "[object HTMLHeadElement]",
715              "[object HTMLScriptElement]", "[object HTMLBodyElement]"})
716     public void valuesForOf() throws Exception {
717         final String html = DOCTYPE_HTML
718             + "<html><head>\n"
719             + "<script>\n"
720             + LOG_TITLE_FUNCTION
721             + "  function test() {\n"
722             + "    var nodeList = document.querySelectorAll('*');\n"
723             + "    if (!nodeList.values) {\n"
724             + "      log('not defined');\n"
725             + "      return;\n"
726             + "    }\n"
727             + "    for (var i of nodeList.values()) {\n"
728             + "      log(i);\n"
729             + "    }\n"
730             + "  }\n"
731             + "</script>\n"
732             + "</head><body onload='test()'>\n"
733             + "</body></html>\n";
734 
735         loadPageVerifyTitle2(html);
736     }
737 
738     /**
739      * @throws Exception on failure
740      */
741     @Test
742     @Alerts({"0", "4", "0", "1", "2", "3"})
743     public void getOwnPropertySymbols() throws Exception {
744         final String html = DOCTYPE_HTML
745                 + "<html><body>\n"
746                 + "<script>\n"
747                 + LOG_TITLE_FUNCTION
748                 + "  if (Object.getOwnPropertySymbols) {\n"
749 
750                 + "    var nodeList = document.querySelectorAll('*');\n"
751 
752                 + "    var objectSymbols = Object.getOwnPropertySymbols(nodeList);\n"
753                 + "    log(objectSymbols.length);\n"
754 
755                 + "    var objectNames = Object.getOwnPropertyNames(nodeList);\n"
756                 + "    log(objectNames.length);\n"
757                 + "    log(objectNames[0]);\n"
758                 + "    log(objectNames[1]);\n"
759                 + "    log(objectNames[2]);\n"
760                 + "    log(objectNames[3]);\n"
761 
762                 + "  } else { log('not defined'); }\n"
763                 + "</script>\n"
764                 + "</body>\n"
765                 + "</html>\n";
766 
767         loadPageVerifyTitle2(html);
768     }
769 
770     /**
771      * @throws Exception on failure
772      */
773     @Test
774     @Alerts({"0", "0"})
775     public void getOwnPropertySymbolsEmptyList() throws Exception {
776         final String html = DOCTYPE_HTML
777                 + "<html><body>\n"
778                 + "<script>\n"
779                 + LOG_TITLE_FUNCTION
780                 + "  if (Object.getOwnPropertySymbols) {\n"
781 
782                 + "    var nodeList = document.querySelectorAll('.notThere');\n"
783 
784                 + "    var objectSymbols = Object.getOwnPropertySymbols(nodeList);\n"
785                 + "    log(objectSymbols.length);\n"
786 
787                 + "    var objectNames = Object.getOwnPropertyNames(nodeList);\n"
788                 + "    log(objectNames.length);\n"
789 
790                 + "  } else { log('not defined'); }\n"
791                 + "</script>\n"
792                 + "</body>\n"
793                 + "</html>\n";
794 
795         loadPageVerifyTitle2(html);
796     }
797 
798     /**
799      * @throws Exception if an error occurs
800      */
801     @Test
802     @Alerts({"[object HTMLHeadElement]", "[object HTMLHeadElement]"})
803     public void setItem() throws Exception {
804         final String html = DOCTYPE_HTML
805             + "<html><head>\n"
806             + "<script>\n"
807             + LOG_TITLE_FUNCTION
808             + "  function test() {\n"
809             + "    var nodeList = document.querySelectorAll('*');\n"
810             + "    log(nodeList.item(1));\n"
811             + "    nodeList[1] = nodeList.item(0);\n"
812             + "    log(nodeList.item(1));\n"
813             + "  }\n"
814             + "</script>\n"
815             + "</head><body onload='test()'>\n"
816             + "</body></html>\n";
817 
818         loadPageVerifyTitle2(html);
819     }
820 }