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