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.html;
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 HTMLOptionsCollection}.
23   *
24   * @author Ronald Brill
25   */
26  public class HTMLOptionsCollectionTest extends WebDriverTestCase {
27  
28      /**
29       * @throws Exception if the test fails
30       */
31      @Test
32      @Alerts({"0", "1", "foo*"})
33      public void addNoPosEmpty() throws Exception {
34          add("", true, false);
35      }
36  
37      /**
38       * @throws Exception if the test fails
39       */
40      @Test
41      @Alerts({"0", "1", "foo"})
42      public void addNoPosEmptyMulti() throws Exception {
43          add("", true, true);
44      }
45  
46      /**
47       * @throws Exception if the test fails
48       */
49      @Test
50      @Alerts({"3", "4", "One", "Two*", "Three", "foo"})
51      public void addNoPos() throws Exception {
52          add("", false, false);
53      }
54  
55      /**
56       * @throws Exception if the test fails
57       */
58      @Test
59      @Alerts({"3", "4", "One", "Two*", "Three*", "foo"})
60      public void addNoPosMulti() throws Exception {
61          add("", false, true);
62      }
63  
64      /**
65       * @throws Exception if the test fails
66       */
67      @Test
68      @Alerts({"0", "1", "foo*"})
69      public void addPosMinusOneEmpty() throws Exception {
70          add(", -1", true, false);
71      }
72  
73      /**
74       * @throws Exception if the test fails
75       */
76      @Test
77      @Alerts({"0", "1", "foo"})
78      public void addPosMinusOneEmptyMulti() throws Exception {
79          add(", -1", true, true);
80      }
81  
82      /**
83       * @throws Exception if the test fails
84       */
85      @Test
86      @Alerts({"3", "4", "One", "Two*", "Three", "foo"})
87      public void addPosMinusOne() throws Exception {
88          add(", -1", false, false);
89      }
90  
91      /**
92       * @throws Exception if the test fails
93       */
94      @Test
95      @Alerts({"3", "4", "One", "Two*", "Three*", "foo"})
96      public void addPosMinusOneMulti() throws Exception {
97          add(", -1", false, true);
98      }
99  
100     /**
101      * @throws Exception if the test fails
102      */
103     @Test
104     @Alerts({"0", "1", "foo*"})
105     public void addPosZeroEmpty() throws Exception {
106         add(", 0", true, false);
107     }
108 
109     /**
110      * @throws Exception if the test fails
111      */
112     @Test
113     @Alerts({"0", "1", "foo"})
114     public void addPosZeroEmptyMulti() throws Exception {
115         add(", 0", true, true);
116     }
117 
118     /**
119      * @throws Exception if the test fails
120      */
121     @Test
122     @Alerts({"3", "4", "foo", "One", "Two*", "Three"})
123     public void addPosZero() throws Exception {
124         add(", 0", false, false);
125     }
126 
127     /**
128      * @throws Exception if the test fails
129      */
130     @Test
131     @Alerts({"3", "4", "foo", "One", "Two*", "Three*"})
132     public void addPosZeroMulti() throws Exception {
133         add(", 0", false, true);
134     }
135 
136     /**
137      * @throws Exception if the test fails
138      */
139     @Test
140     @Alerts({"0", "1", "foo*"})
141     public void addPosOneEmpty() throws Exception {
142         add(", 1", true, false);
143     }
144 
145     /**
146      * @throws Exception if the test fails
147      */
148     @Test
149     @Alerts({"0", "1", "foo"})
150     public void addPosOneEmptyMulti() throws Exception {
151         add(", 1", true, true);
152     }
153 
154     /**
155      * @throws Exception if the test fails
156      */
157     @Test
158     @Alerts({"3", "4", "One", "foo", "Two*", "Three"})
159     public void addPosOne() throws Exception {
160         add(", 1", false, false);
161     }
162 
163     /**
164      * @throws Exception if the test fails
165      */
166     @Test
167     @Alerts({"3", "4", "One", "foo", "Two*", "Three*"})
168     public void addPosOneMulti() throws Exception {
169         add(", 1", false, true);
170     }
171 
172     /**
173      * @throws Exception if the test fails
174      */
175     @Test
176     @Alerts({"0", "1", "foo*"})
177     public void addPosThreeEmpty() throws Exception {
178         add(", 3", true, false);
179     }
180 
181     /**
182      * @throws Exception if the test fails
183      */
184     @Test
185     @Alerts({"0", "1", "foo"})
186     public void addPosThreeEmptyMulti() throws Exception {
187         add(", 3", true, true);
188     }
189 
190     /**
191      * @throws Exception if the test fails
192      */
193     @Test
194     @Alerts({"3", "4", "One", "Two*", "Three", "foo"})
195     public void addPosThree() throws Exception {
196         add(", 3", false, false);
197     }
198 
199     /**
200      * @throws Exception if the test fails
201      */
202     @Test
203     @Alerts({"3", "4", "One", "Two*", "Three*", "foo"})
204     public void addPosThreeMulti() throws Exception {
205         add(", 3", false, true);
206     }
207 
208     /**
209      * @throws Exception if the test fails
210      */
211     @Test
212     @Alerts({"0", "1", "foo*"})
213     public void addPosTenEmpty() throws Exception {
214         add(", 10", true, false);
215     }
216 
217     /**
218      * @throws Exception if the test fails
219      */
220     @Test
221     @Alerts({"0", "1", "foo"})
222     public void addPosTenEmptyMulti() throws Exception {
223         add(", 10", true, true);
224     }
225 
226     /**
227      * @throws Exception if the test fails
228      */
229     @Test
230     @Alerts({"3", "4", "One", "Two*", "Three", "foo"})
231     public void addPosTen() throws Exception {
232         add(", 10", false, false);
233     }
234 
235     /**
236      * @throws Exception if the test fails
237      */
238     @Test
239     @Alerts({"3", "4", "One", "Two*", "Three*", "foo"})
240     public void addPosTenMulti() throws Exception {
241         add(", 10", false, true);
242     }
243 
244     /**
245      * @throws Exception if the test fails
246      */
247     @Test
248     @Alerts({"0", "1", "foo*"})
249     public void addBeforeNullEmpty() throws Exception {
250         add(", null", true, false);
251     }
252 
253     /**
254      * @throws Exception if the test fails
255      */
256     @Test
257     @Alerts({"0", "1", "foo"})
258     public void addBeforeNullEmptyMulti() throws Exception {
259         add(", null", true, true);
260     }
261 
262     /**
263      * @throws Exception if the test fails
264      */
265     @Test
266     @Alerts({"3", "4", "One", "Two*", "Three", "foo"})
267     public void addBeforeNull() throws Exception {
268         add(", null", false, false);
269     }
270 
271     /**
272      * @throws Exception if the test fails
273      */
274     @Test
275     @Alerts({"3", "4", "One", "Two*", "Three*", "foo"})
276     public void addBeforeNullMulti() throws Exception {
277         add(", null", false, true);
278     }
279 
280     /**
281      * @throws Exception if the test fails
282      */
283     @Test
284     @Alerts({"0", "NotFoundError/DOMException"})
285     public void addBeforeUnknownEmpty() throws Exception {
286         add(", new Option('foo', '123')", true, false);
287     }
288 
289     /**
290      * @throws Exception if the test fails
291      */
292     @Test
293     @Alerts({"0", "NotFoundError/DOMException"})
294     public void addBeforeUnknownEmptyMulti() throws Exception {
295         add(", new Option('foo', '123')", true, true);
296     }
297 
298     /**
299      * @throws Exception if the test fails
300      */
301     @Test
302     @Alerts({"3", "NotFoundError/DOMException"})
303     public void addBeforeUnknown() throws Exception {
304         add(", new Option('foo', '123')", false, false);
305     }
306 
307     /**
308      * @throws Exception if the test fails
309      */
310     @Test
311     @Alerts({"3", "NotFoundError/DOMException"})
312     public void addBeforeUnknownMulti() throws Exception {
313         add(", new Option('foo', '123')", false, true);
314     }
315 
316     /**
317      * @throws Exception if the test fails
318      */
319     @Test
320     @Alerts({"3", "4", "foo", "One", "Two*", "Three"})
321     public void addBeforeFirst() throws Exception {
322         add(", oSelect.options[0]", false, false);
323     }
324 
325     /**
326      * @throws Exception if the test fails
327      */
328     @Test
329     @Alerts({"3", "4", "foo", "One", "Two*", "Three*"})
330     public void addBeforeFirstMulti() throws Exception {
331         add(", oSelect.options[0]", false, true);
332     }
333 
334     /**
335      * @throws Exception if the test fails
336      */
337     @Test
338     @Alerts({"3", "4", "One", "foo", "Two*", "Three"})
339     public void addBeforeSecond() throws Exception {
340         add(", oSelect.options[1]", false, false);
341     }
342 
343     /**
344      * @throws Exception if the test fails
345      */
346     @Test
347     @Alerts({"3", "4", "One", "foo", "Two*", "Three*"})
348     public void addBeforeSecondMulti() throws Exception {
349         add(", oSelect.options[1]", false, true);
350     }
351 
352     /**
353      * @throws Exception if the test fails
354      */
355     @Test
356     @Alerts({"3", "4", "One", "Two*", "foo", "Three"})
357     public void addBeforeLast() throws Exception {
358         add(", oSelect.options[2]", false, false);
359     }
360 
361     /**
362      * @throws Exception if the test fails
363      */
364     @Test
365     @Alerts({"3", "4", "One", "Two*", "foo", "Three*"})
366     public void addBeforeLastMulti() throws Exception {
367         add(", oSelect.options[2]", false, true);
368     }
369 
370     private void add(final String param, final boolean empty, final boolean multi) throws Exception {
371         String html = DOCTYPE_HTML
372             + "<html>\n"
373             + "<head>\n"
374             + "  <script>\n"
375             + LOG_TITLE_FUNCTION
376             + "    function doTest() {\n"
377             + "      try {\n"
378             + "        var oSelect = document.forms.testForm.select1;\n"
379             + "        log(oSelect.length);\n"
380             + "        var opt = new Option('foo', '123');\n"
381             + "        oSelect.options.add(opt" + param + ");\n"
382 
383             + "        log(oSelect.options.length);\n"
384             + "        for (var i = 0; i < oSelect.options.length; i++) {\n"
385             + "          log(oSelect.options[i].text + (oSelect.options[i].selected ? '*' : ''));\n"
386             + "        }\n"
387             + "      } catch(e) { logEx(e); }\n"
388             + "    }\n"
389             + "  </script>\n"
390             + "</head>\n"
391             + "<body onload='doTest()'>\n"
392             + "  <form name='testForm'>\n"
393             + "    <select name='select1' " + (multi ? "multiple" : "") + ">\n";
394         if (!empty) {
395             html = html
396                     + "      <option name='option1' value='value1'>One</option>\n"
397                     + "      <option name='option2' value='value2' selected>Two</option>\n"
398                     + "      <option name='option3' value='value3'" + (multi ? "selected" : "") + ">Three</option>\n";
399         }
400         html = html
401             + "    </select>\n"
402             + "  </form>\n"
403             + "</body></html>";
404 
405         loadPageVerifyTitle2(html);
406     }
407 
408     /**
409      * @throws Exception if the test fails
410      */
411     @Test
412     @Alerts("undefined")
413     public void getMinusOneEmpty() throws Exception {
414         get("-1", true);
415     }
416 
417     /**
418      * @throws Exception if the test fails
419      */
420     @Test
421     @Alerts("undefined")
422     public void getMinusOne() throws Exception {
423         get("-1", false);
424     }
425 
426     /**
427      * @throws Exception if the test fails
428      */
429     @Test
430     @Alerts("One")
431     public void getZero() throws Exception {
432         get("0", false);
433     }
434 
435     /**
436      * @throws Exception if the test fails
437      */
438     @Test
439     @Alerts("Two*")
440     public void getOne() throws Exception {
441         get("1", false);
442     }
443 
444     /**
445      * @throws Exception if the test fails
446      */
447     @Test
448     @Alerts("Three")
449     public void getTwo() throws Exception {
450         get("2", false);
451     }
452 
453     /**
454      * @throws Exception if the test fails
455      */
456     @Test
457     @Alerts("undefined")
458     public void getThree() throws Exception {
459         get("3", false);
460     }
461 
462     /**
463      * @throws Exception if the test fails
464      */
465     @Test
466     @Alerts("undefined")
467     public void getTenEmpty() throws Exception {
468         get("10", true);
469     }
470 
471     /**
472      * @throws Exception if the test fails
473      */
474     @Test
475     @Alerts("undefined")
476     public void getTen() throws Exception {
477         get("10", false);
478     }
479 
480     private void get(final String pos, final boolean empty) throws Exception {
481         String html = DOCTYPE_HTML
482             + "<html>\n"
483             + "<head>\n"
484             + "  <script>\n"
485             + LOG_TITLE_FUNCTION
486             + "    function doTest() {\n"
487             + "      try {\n"
488             + "        var oSelect = document.forms.testForm.select1;\n"
489             + "        var opt = oSelect.options[" + pos + "];\n"
490             + "        log(opt ? opt.text + (opt.selected ? '*' : '') : opt);\n"
491             + "      } catch(e) { logEx(e); }\n"
492             + "    }\n"
493             + "  </script>\n"
494             + "</head>\n"
495             + "<body onload='doTest()'>\n"
496             + "  <form name='testForm'>\n"
497             + "    <select name='select1' >\n";
498         if (!empty) {
499             html = html
500                     + "      <option name='option1' value='value1'>One</option>\n"
501                     + "      <option name='option2' value='value2' selected>Two</option>\n"
502                     + "      <option name='option3' value='value3'>Three</option>\n";
503         }
504         html = html
505             + "    </select>\n"
506             + "  </form>\n"
507             + "</body></html>";
508 
509         loadPageVerifyTitle2(html);
510     }
511 
512     /**
513      * @throws Exception if the test fails
514      */
515     @Test
516     @Alerts({"0", "0"})
517     public void putMinusOneNullEmpty() throws Exception {
518         put("-1", "null", true, false);
519     }
520 
521     /**
522      * @throws Exception if the test fails
523      */
524     @Test
525     @Alerts({"0", "0"})
526     public void putMinusOneNullEmptyMulti() throws Exception {
527         put("-1", "null", true, true);
528     }
529 
530     /**
531      * @throws Exception if the test fails
532      */
533     @Test
534     @Alerts({"3", "3", "One", "Two*", "Three"})
535     public void putMinusOneNull() throws Exception {
536         put("-1", "null", false, false);
537     }
538 
539     /**
540      * @throws Exception if the test fails
541      */
542     @Test
543     @Alerts({"3", "3", "One", "Two*", "Three*"})
544     public void putMinusOneNullMulti() throws Exception {
545         put("-1", "null", false, true);
546     }
547 
548     /**
549      * @throws Exception if the test fails
550      */
551     @Test
552     @Alerts({"3", "3", "One", "Two*", "Three"})
553     public void putMinusOneEmpty() throws Exception {
554         put("-1", "opt", false, false);
555     }
556 
557     /**
558      * @throws Exception if the test fails
559      */
560     @Test
561     @Alerts({"3", "3", "One", "Two*", "Three*"})
562     public void putMinusOneEmptyMulti() throws Exception {
563         put("-1", "opt", false, true);
564     }
565 
566     /**
567      * @throws Exception if the test fails
568      */
569     @Test
570     @Alerts({"3", "3", "One", "Two*", "Three"})
571     public void putMinusOne() throws Exception {
572         put("-1", "opt", false, false);
573     }
574 
575     /**
576      * @throws Exception if the test fails
577      */
578     @Test
579     @Alerts({"3", "3", "One", "Two*", "Three*"})
580     public void putMinusOneMulti() throws Exception {
581         put("-1", "opt", false, true);
582     }
583 
584     /**
585      * @throws Exception if the test fails
586      */
587     @Test
588     @Alerts({"0", "1", "foo*"})
589     public void putZeroEmpty() throws Exception {
590         put("0", "opt", true, false);
591     }
592 
593     /**
594      * @throws Exception if the test fails
595      */
596     @Test
597     @Alerts({"0", "1", "foo"})
598     public void putZeroEmptyMulti() throws Exception {
599         put("0", "opt", true, true);
600     }
601 
602     /**
603      * @throws Exception if the test fails
604      */
605     @Test
606     @Alerts({"3", "3", "foo", "Two*", "Three"})
607     public void putZero() throws Exception {
608         put("0", "opt", false, false);
609     }
610 
611     /**
612      * @throws Exception if the test fails
613      */
614     @Test
615     @Alerts({"3", "3", "foo", "Two*", "Three*"})
616     public void putZeroMulti() throws Exception {
617         put("0", "opt", false, true);
618     }
619 
620     /**
621      * @throws Exception if the test fails
622      */
623     @Test
624     @Alerts({"3", "3", "One*", "foo", "Three"})
625     public void putOne() throws Exception {
626         put("1", "opt", false, false);
627     }
628 
629     /**
630      * @throws Exception if the test fails
631      */
632     @Test
633     @Alerts({"3", "3", "One", "foo", "Three*"})
634     public void putOneMulit() throws Exception {
635         put("1", "opt", false, true);
636     }
637 
638     /**
639      * @throws Exception if the test fails
640      */
641     @Test
642     @Alerts({"3", "3", "One", "Two*", "foo"})
643     public void putTwo() throws Exception {
644         put("2", "opt", false, false);
645     }
646 
647     /**
648      * @throws Exception if the test fails
649      */
650     @Test
651     @Alerts({"3", "3", "One", "Two*", "foo"})
652     public void putTwoMulti() throws Exception {
653         put("2", "opt", false, true);
654     }
655 
656     /**
657      * @throws Exception if the test fails
658      */
659     @Test
660     @Alerts({"3", "4", "One", "Two*", "Three", "foo"})
661     public void putThree() throws Exception {
662         put("3", "opt", false, false);
663     }
664 
665     /**
666      * @throws Exception if the test fails
667      */
668     @Test
669     @Alerts({"3", "4", "One", "Two*", "Three*", "foo"})
670     public void putThreeMulti() throws Exception {
671         put("3", "opt", false, true);
672     }
673 
674     /**
675      * @throws Exception if the test fails
676      */
677     @Test
678     @Alerts({"3", "11", "One", "Two*", "Three", "", "", "", "", "", "", "", "foo"})
679     public void putTen() throws Exception {
680         put("10", "opt", false, false);
681     }
682 
683     /**
684      * @throws Exception if the test fails
685      */
686     @Test
687     @Alerts({"3", "11", "One", "Two*", "Three*", "", "", "", "", "", "", "", "foo"})
688     public void putTenMulti() throws Exception {
689         put("10", "opt", false, true);
690     }
691 
692     private void put(final String pos, final String param, final boolean empty, final boolean multi) throws Exception {
693         String html = DOCTYPE_HTML
694             + "<html>\n"
695             + "<head>\n"
696             + "  <script>\n"
697             + LOG_TITLE_FUNCTION
698             + "    function doTest() {\n"
699             + "      try {\n"
700             + "        var oSelect = document.forms.testForm.select1;\n"
701             + "        log(oSelect.length);\n"
702             + "        var opt = new Option('foo', '123');\n"
703             + "        oSelect.options[" + pos + "] = " + param + ";\n"
704 
705             + "        log(oSelect.options.length);\n"
706             + "        for (var i = 0; i < oSelect.options.length; i++) {\n"
707             + "          log(oSelect.options[i].text + (oSelect.options[i].selected ? '*' : ''));\n"
708             + "        }\n"
709             + "      } catch(e) { logEx(e); }\n"
710             + "    }\n"
711             + "  </script>\n"
712             + "</head>\n"
713             + "<body onload='doTest()'>\n"
714             + "  <form name='testForm'>\n"
715             + "    <select name='select1' " + (multi ? "multiple" : "") + ">\n";
716         if (!empty) {
717             html = html
718                     + "      <option name='option1' value='value1'>One</option>\n"
719                     + "      <option name='option2' value='value2' selected>Two</option>\n"
720                     + "      <option name='option3' value='value3'" + (multi ? "selected" : "") + ">Three</option>\n";
721         }
722         html = html
723             + "    </select>\n"
724             + "  </form>\n"
725             + "</body></html>";
726 
727         loadPageVerifyTitle2(html);
728     }
729 
730     /**
731      * @throws Exception if the test fails
732      */
733     @Test
734     @Alerts("0")
735     public void removeMinusOneEmpty() throws Exception {
736         remove("-1", true, false);
737     }
738 
739     /**
740      * @throws Exception if the test fails
741      */
742     @Test
743     @Alerts("0")
744     public void removeMinusOneEmptyMulti() throws Exception {
745         remove("-1", true, true);
746     }
747 
748     /**
749      * @throws Exception if the test fails
750      */
751     @Test
752     @Alerts({"3", "One", "Two*", "Three"})
753     public void removeMinusOne() throws Exception {
754         remove("-1", false, false);
755     }
756 
757     /**
758      * @throws Exception if the test fails
759      */
760     @Test
761     @Alerts({"3", "One", "Two*", "Three*"})
762     public void removeMinusOneMulti() throws Exception {
763         remove("-1", false, true);
764     }
765 
766     /**
767      * @throws Exception if the test fails
768      */
769     @Test
770     @Alerts({"2", "Two*", "Three"})
771     public void removeZero() throws Exception {
772         remove("0", false, false);
773     }
774 
775     /**
776      * @throws Exception if the test fails
777      */
778     @Test
779     @Alerts({"2", "Two*", "Three*"})
780     public void removeZeroMulti() throws Exception {
781         remove("0", false, true);
782     }
783 
784     /**
785      * @throws Exception if the test fails
786      */
787     @Test
788     @Alerts({"2", "One*", "Three"})
789     public void removeOne() throws Exception {
790         remove("1", false, false);
791     }
792 
793     /**
794      * @throws Exception if the test fails
795      */
796     @Test
797     @Alerts({"2", "One", "Three*"})
798     public void removeOneMulti() throws Exception {
799         remove("1", false, true);
800     }
801 
802     /**
803      * @throws Exception if the test fails
804      */
805     @Test
806     @Alerts({"2", "One", "Two*"})
807     public void removeTwo() throws Exception {
808         remove("2", false, false);
809     }
810 
811     /**
812      * @throws Exception if the test fails
813      */
814     @Test
815     @Alerts({"2", "One", "Two*"})
816     public void removeTwoMulti() throws Exception {
817         remove("2", false, true);
818     }
819 
820     /**
821      * @throws Exception if the test fails
822      */
823     @Test
824     @Alerts({"3", "One", "Two*", "Three"})
825     public void removeThree() throws Exception {
826         remove("3", false, false);
827     }
828 
829     /**
830      * @throws Exception if the test fails
831      */
832     @Test
833     @Alerts({"3", "One", "Two*", "Three*"})
834     public void removeThreeMulti() throws Exception {
835         remove("3", false, true);
836     }
837 
838     /**
839      * @throws Exception if the test fails
840      */
841     @Test
842     @Alerts("0")
843     public void removeTenEmpty() throws Exception {
844         remove("10", true, false);
845     }
846 
847     /**
848      * @throws Exception if the test fails
849      */
850     @Test
851     @Alerts("0")
852     public void removeTenEmptyMulti() throws Exception {
853         remove("10", true, true);
854     }
855 
856     /**
857      * @throws Exception if the test fails
858      */
859     @Test
860     @Alerts({"3", "One", "Two*", "Three"})
861     public void removeTen() throws Exception {
862         remove("10", false, false);
863     }
864 
865     /**
866      * @throws Exception if the test fails
867      */
868     @Test
869     @Alerts({"3", "One", "Two*", "Three*"})
870     public void removeTenMuti() throws Exception {
871         remove("10", false, true);
872     }
873 
874     private void remove(final String pos, final boolean empty, final boolean multi) throws Exception {
875         String html = DOCTYPE_HTML
876             + "<html>\n"
877             + "<head>\n"
878             + "  <script>\n"
879             + LOG_TITLE_FUNCTION
880             + "    function doTest() {\n"
881             + "      try {\n"
882             + "        var oSelect = document.forms.testForm.select1;\n"
883             + "        oSelect.options.remove(" + pos + ");\n"
884 
885             + "        log(oSelect.options.length);\n"
886             + "        for (var i = 0; i < oSelect.options.length; i++) {\n"
887             + "          log(oSelect.options[i].text + (oSelect.options[i].selected ? '*' : ''));\n"
888             + "        }\n"
889             + "      } catch(e) { logEx(e); }\n"
890             + "    }\n"
891             + "  </script>\n"
892             + "</head>\n"
893             + "<body onload='doTest()'>\n"
894             + "  <form name='testForm'>\n"
895             + "    <select name='select1' " + (multi ? "multiple" : "") + ">\n";
896         if (!empty) {
897             html = html
898                     + "      <option name='option1' value='value1'>One</option>\n"
899                     + "      <option name='option2' value='value2' selected>Two</option>\n"
900                     + "      <option name='option3' value='value3'" + (multi ? "selected" : "") + ">Three</option>\n";
901         }
902         html = html
903             + "    </select>\n"
904             + "  </form>\n"
905             + "</body></html>";
906 
907         loadPageVerifyTitle2(html);
908     }
909 
910     /**
911      * @throws Exception if the test fails
912      */
913     @Test
914     @Alerts({"0", "1", "3"})
915     public void length() throws Exception {
916         final String html = DOCTYPE_HTML
917             + "<html><head><script>\n"
918             + LOG_TITLE_FUNCTION
919             + "function test() {\n"
920             + "  var sel = document.form1.select0;\n"
921             + "  log(sel.options.length);\n"
922             + "  sel = document.form1.select1;\n"
923             + "  log(sel.options.length);\n"
924             + "  sel = document.form1.select3;\n"
925             + "  log(sel.options.length);\n"
926             + "}</script></head>\n"
927 
928             + "<body onload='test()'>\n"
929             + "<form name='form1'>\n"
930             + "  <select name='select0'></select>\n"
931 
932             + "  <select name='select1'>\n"
933             + "    <option>One</option>\n"
934             + "  </select>\n"
935 
936             + "  <select name='select3'>\n"
937             + "    <option>One</option>\n"
938             + "    <option>Two</option>\n"
939             + "    <option>Three</option>\n"
940             + "  </select>\n"
941             + "</form>\n"
942             + "</body></html>";
943 
944         loadPageVerifyTitle2(html);
945     }
946 
947     /**
948      * @throws Exception if the test fails
949      */
950     @Test
951     @Alerts({"0", "1", "One", "3", "One", "Two", "Three"})
952     public void setLengthMinusOne() throws Exception {
953         setLength("-1");
954     }
955 
956     /**
957      * @throws Exception if the test fails
958      */
959     @Test
960     @Alerts({"0", "0", "0"})
961     public void setLengthZero() throws Exception {
962         setLength("0");
963     }
964 
965     /**
966      * @throws Exception if the test fails
967      */
968     @Test
969     @Alerts({"1", "", "1", "One", "1", "One"})
970     public void setLengthOne() throws Exception {
971         setLength("1");
972     }
973 
974     /**
975      * @throws Exception if the test fails
976      */
977     @Test
978     @Alerts({"2", "", "", "2", "One", "", "2", "One", "Two"})
979     public void setLengthTwo() throws Exception {
980         setLength("2");
981     }
982 
983     /**
984      * @throws Exception if the test fails
985      */
986     @Test
987     @Alerts({"3", "", "", "", "3", "One", "", "", "3", "One", "Two", "Three"})
988     public void setLengthThree() throws Exception {
989         setLength("3");
990     }
991 
992     /**
993      * @throws Exception if the test fails
994      */
995     @Test
996     @Alerts({"10", "", "", "", "", "", "", "", "", "", "",
997              "10", "One", "", "", "", "", "", "", "", "", "",
998              "10", "One", "Two", "Three", "", "", "", "", "", "", ""})
999     public void setLengthTen() throws Exception {
1000         setLength("10");
1001     }
1002 
1003     private void setLength(final String lenght) throws Exception {
1004         final String html = DOCTYPE_HTML
1005             + "<html><head><script>\n"
1006             + LOG_TITLE_FUNCTION
1007             + "function test() {\n"
1008             + "  var sel = document.form1.select0;\n"
1009             + "  try {\n"
1010             + "    sel.options.length = " + lenght + ";\n"
1011             + "    log(sel.options.length);\n"
1012             + "    for (var i = 0; i < sel.options.length; i++) {\n"
1013             + "      log(sel.options[i].text);\n"
1014             + "    }\n"
1015             + "  } catch(e) { logEx(e); }\n"
1016 
1017             + "  var sel = document.form1.select1;\n"
1018             + "  try {\n"
1019             + "    sel.options.length = " + lenght + ";\n"
1020             + "    log(sel.options.length);\n"
1021             + "    for (var i = 0; i < sel.options.length; i++) {\n"
1022             + "      log(sel.options[i].text);\n"
1023             + "    }\n"
1024             + "  } catch(e) { logEx(e); }\n"
1025 
1026             + "  var sel = document.form1.select3;\n"
1027             + "  try {\n"
1028             + "    sel.options.length = " + lenght + ";\n"
1029             + "    log(sel.options.length);\n"
1030             + "    for (var i = 0; i < sel.options.length; i++) {\n"
1031             + "      log(sel.options[i].text);\n"
1032             + "    }\n"
1033             + "  } catch(e) { logEx(e); }\n"
1034             + "}</script></head>\n"
1035 
1036             + "<body onload='test()'>\n"
1037             + "  <form name='form1'>\n"
1038             + "    <select name='select0'></select>\n"
1039 
1040             + "    <select name='select1'>\n"
1041             + "      <option>One</option>\n"
1042             + "    </select>\n"
1043 
1044             + "    <select name='select3'>\n"
1045             + "      <option>One</option>\n"
1046             + "      <option>Two</option>\n"
1047             + "      <option>Three</option>\n"
1048             + "    </select>\n"
1049             + "  </form>\n"
1050             + "</body></html>";
1051 
1052         loadPageVerifyTitle2(html);
1053     }
1054 
1055     /**
1056      * @throws Exception if the test fails
1057      */
1058     @Test
1059     @Alerts({"1", "", "4", "One", "1", "", "0"})
1060     public void setLength_increase() throws Exception {
1061         final String html = DOCTYPE_HTML
1062             + "<html><head><script>\n"
1063             + LOG_TITLE_FUNCTION
1064             + "function test() {\n"
1065             + "  var sel = document.form1.select0;\n"
1066             + "  try {\n"
1067             + "    sel.options.length = 1;\n"
1068             + "    log(sel.options.length);\n"
1069             + "    log(sel.options[0].text);\n"
1070             + "  } catch(e) { log(e); }\n"
1071 
1072             + "  sel = document.form1.select1;\n"
1073             + "  try {\n"
1074             + "    sel.options.length = 4;\n"
1075             + "    log(sel.options.length);\n"
1076             + "    log(sel.options[0].text);\n"
1077             + "    log(sel.options[0].childNodes.length);\n"
1078             + "    log(sel.options[1].text);\n"
1079             + "    log(sel.options[1].childNodes.length);\n"
1080             + "  } catch(e) { log(e); }\n"
1081             + "}</script></head>\n"
1082 
1083             + "<body onload='test()'>\n"
1084             + "<form name='form1'>\n"
1085             + "  <select name='select0'></select>\n"
1086 
1087             + "  <select name='select1'>\n"
1088             + "    <option>One</option>\n"
1089             + "  </select>\n"
1090             + "</form>\n"
1091             + "</body></html>";
1092 
1093         loadPageVerifyTitle2(html);
1094     }
1095 
1096     /**
1097      * @throws Exception if the test fails
1098      */
1099     @Test
1100     @Alerts({"1", "false", "true", "false", "false"})
1101     public void in() throws Exception {
1102         final String html = DOCTYPE_HTML
1103             + "<html><head><script>\n"
1104             + LOG_TITLE_FUNCTION
1105             + "function test() {\n"
1106             + "  var opts = document.form1.select.options;\n"
1107             + "  log(opts.length);\n"
1108             + "  log(-1 in opts);\n"
1109             + "  log(0 in opts);\n"
1110             + "  log(1 in opts);\n"
1111             + "  log(42 in opts);\n"
1112             + "}</script></head>\n"
1113 
1114             + "<body onload='test()'>\n"
1115             + "  <form name='form1'>\n"
1116             + "    <select name='select'>\n"
1117             + "      <option>One</option>\n"
1118             + "    </select>\n"
1119             + "  </form>\n"
1120             + "</body></html>";
1121 
1122         loadPageVerifyTitle2(html);
1123     }
1124 
1125     /**
1126      * @throws Exception if the test fails
1127      */
1128     @Test
1129     @Alerts({"1", "undefined", "[object HTMLOptionElement]", "undefined", "undefined"})
1130     public void index() throws Exception {
1131         final String html = DOCTYPE_HTML
1132             + "<html><head><script>\n"
1133             + LOG_TITLE_FUNCTION
1134             + "function test() {\n"
1135             + "  var opts = document.form1.select.options;\n"
1136             + "  log(opts.length);\n"
1137             + "  log(opts[-1]);\n"
1138             + "  log(opts[0]);\n"
1139             + "  log(opts[1]);\n"
1140             + "  log(opts[42]);\n"
1141             + "}</script></head>\n"
1142 
1143             + "<body onload='test()'>\n"
1144             + "  <form name='form1'>\n"
1145             + "    <select name='select'>\n"
1146             + "      <option>One</option>\n"
1147             + "    </select>\n"
1148             + "  </form>\n"
1149             + "</body></html>";
1150 
1151         loadPageVerifyTitle2(html);
1152     }
1153 
1154     /**
1155      * @throws Exception if the test fails
1156      */
1157     @Test
1158     @Alerts({"1", "null", "[object HTMLOptionElement]", "null", "null"})
1159     public void item() throws Exception {
1160         final String html = DOCTYPE_HTML
1161             + "<html><head><script>\n"
1162             + LOG_TITLE_FUNCTION
1163             + "function test() {\n"
1164             + "  var opts = document.form1.select.options;\n"
1165             + "  log(opts.length);\n"
1166             + "  log(opts.item(-1));\n"
1167             + "  log(opts.item(0));\n"
1168             + "  log(opts.item(1));\n"
1169             + "  log(opts.item(42));\n"
1170             + "}</script></head>\n"
1171 
1172             + "<body onload='test()'>\n"
1173             + "  <form name='form1'>\n"
1174             + "    <select name='select'>\n"
1175             + "      <option>One</option>\n"
1176             + "    </select>\n"
1177             + "  </form>\n"
1178             + "</body></html>";
1179 
1180         loadPageVerifyTitle2(html);
1181     }
1182 }