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.htmlunit.junit.annotation.BuggyWebDriver;
20  import org.htmlunit.junit.annotation.HtmlUnitNYI;
21  import org.junit.jupiter.api.Test;
22  import org.openqa.selenium.By;
23  import org.openqa.selenium.WebDriver;
24  import org.openqa.selenium.interactions.Actions;
25  
26  /**
27   * Tests for {@link HTMLOptionElement}.
28   *
29   * @author Marc Guillemot
30   * @author Ahmed Ashour
31   * @author Ronald Brill
32   * @author Frank Danek
33   */
34  public class HTMLOptionElement2Test extends WebDriverTestCase {
35  
36      /**
37       * @throws Exception if the test fails
38       */
39      @Test
40      @Alerts("SELECT")
41      @BuggyWebDriver(CHROME = {},
42              EDGE = {})
43      //https://bugs.chromium.org/p/chromedriver/issues/detail?id=1352
44      public void clickSelect() throws Exception {
45          final String html = DOCTYPE_HTML
46                  + "<html><head>\n"
47                  + "<title>foo</title>\n"
48                  + "<script>\n"
49                  + LOG_TEXTAREA_FUNCTION
50  
51                  + "  function init() {\n"
52                  + "    var s = document.getElementById('s');\n"
53                  + "    s.addEventListener('click', handle, false);\n"
54                  + "  }\n"
55  
56                  + "  function handle(event) {\n"
57                  + "    if (event.target) {\n"
58                  + "      log(event.target.nodeName);\n"
59                  + "    } else {\n"
60                  + "      log(event.srcElement.nodeName);\n"
61                  + "    }\n"
62                  + "  }\n"
63                  + "</script></head>\n"
64  
65                  + "<body onload='init()'>\n"
66                  + "<form>\n"
67                  + LOG_TEXTAREA
68                  + "  <select id='s' size='7'>\n"
69                  + "    <option value='opt-a'>A</option>\n"
70                  + "    <option id='opt-b' value='b'>B</option>\n"
71                  + "    <option value='opt-c'>C</option>\n"
72                  + "  </select>\n"
73                  + "</form>\n"
74                  + "</body></html>";
75  
76          final WebDriver driver = loadPage2(html);
77          driver.findElement(By.id("s")).click();
78  
79          verifyTextArea2(driver, getExpectedAlerts());
80      }
81  
82      /**
83       * @throws Exception if the test fails
84       */
85      @Test
86      @Alerts(DEFAULT = {"opt-a", "opt-b"},
87              CHROME = "opt-b")
88      @BuggyWebDriver({"opt-a", "b"})
89      @HtmlUnitNYI(CHROME = {"opt-a", "b"},
90              EDGE = {"opt-a", "b"},
91              FF = {"opt-a", "b"},
92              FF_ESR = {"opt-a", "b"})
93      // TODO: Needs further investigation of clicking an option without clicking the select
94      // See the first comment in http://code.google.com/p/selenium/issues/detail?id=2131#c1
95      // Additionally, FF and Chrome drivers look buggy as they don't allow to capture
96      // what happens when running the test manually in the browser.
97      public void click2() throws Exception {
98          final String html = DOCTYPE_HTML
99                  + "<html><head>\n"
100                 + "<title>foo</title>\n"
101                 + "<script>\n"
102                 + LOG_TEXTAREA_FUNCTION
103 
104                 + "  function init() {\n"
105                 + "    s = document.getElementById('s');\n"
106                 + "    s.addEventListener('click', handle, false);\n"
107                 + "  }\n"
108 
109                 + "  function handle(event) {\n"
110                 + "    log(s.options[s.selectedIndex].value);\n"
111                 + "  }\n"
112                 + "</script></head>\n"
113 
114                 + "<body onload='init()'>\n"
115                 + "<form>\n"
116                 + LOG_TEXTAREA
117                 + "  <select id='s'>\n"
118                 + "    <option value='opt-a'>A</option>\n"
119                 + "    <option id='opt-b' value='b'>B</option>\n"
120                 + "    <option value='opt-c'>C</option>\n"
121                 + "  </select>\n"
122                 + "</form>\n"
123                 + "</body></html>";
124 
125         final WebDriver driver = loadPage2(html);
126         driver.findElement(By.id("s")).click();
127         driver.findElement(By.id("opt-b")).click();
128 
129         verifyTextArea2(driver, getExpectedAlerts());
130     }
131 
132     /**
133      * Test for the right event sequence when clicking.
134      *
135      * @throws Exception if the test fails
136      */
137     @Test
138     @Alerts({"onchange-select", "onclick-option", "onclick-select"})
139     @BuggyWebDriver(CHROME = {"onchange-select", "onclick-select"},
140             EDGE = {"onchange-select", "onclick-select"},
141             FF = {"onchange-select", "onclick-select"},
142             FF_ESR = {"onchange-select", "onclick-select"})
143     public void clickOptionEventSequence1() throws Exception {
144         final String html = DOCTYPE_HTML
145                 + "<html><head>\n"
146                 + "<script>\n"
147                 + LOG_TEXTAREA_FUNCTION
148                 + "</script></head>\n"
149 
150                 + "<body>\n"
151                 + "<form>\n"
152                 + LOG_TEXTAREA
153                 + "  <select id='s' size='2' onclick=\"log('onclick-select')\""
154                         + " onchange=\"log('onchange-select')\">\n"
155                 + "    <option id='clickId' value='a' onclick=\"log('onclick-option')\""
156                         + " onchange=\"log('onchange-option')\">A</option>\n"
157                 + "  </select>\n"
158                 + "</form>\n"
159 
160                 + "</body></html>";
161 
162         final WebDriver driver = loadPage2(html);
163 
164         driver.findElement(By.id("clickId")).click();
165 
166         verifyTextArea2(driver, getExpectedAlerts());
167     }
168 
169     /**
170      * Test for the right event sequence when clicking.
171      *
172      * @throws Exception if the test fails
173      */
174     @Test
175     @Alerts({"change-SELECT", "click-OPTION", "click-OPTION"})
176     @BuggyWebDriver(CHROME = {"change-SELECT", "click-SELECT"},
177             EDGE = {"change-SELECT", "click-SELECT"},
178             FF = {"change-SELECT", "click-SELECT"},
179             FF_ESR = {"change-SELECT", "click-SELECT"})
180     public void clickOptionEventSequence2() throws Exception {
181         final String html = DOCTYPE_HTML
182                 + "<html><head>\n"
183                 + "<script>\n"
184                 + LOG_TEXTAREA_FUNCTION
185 
186                 + "  function init() {\n"
187                 + "    var s = document.getElementById('s');\n"
188                 + "    var o = document.getElementById('clickId');\n"
189                 + "    s.addEventListener('click', handle, false);\n"
190                 + "    s.addEventListener('change', handle, false);\n"
191                 + "    o.addEventListener('click', handle, false);\n"
192                 + "    o.addEventListener('change', handle, false);\n"
193                 + "  }\n"
194 
195                 + "  function handle(event) {\n"
196                 + "    if (event.target) {\n"
197                 + "      log(event.type + '-' + event.target.nodeName);\n"
198                 + "    } else {\n"
199                 + "      log(event.type + '-' + event.srcElement.nodeName);\n"
200                 + "    }\n"
201                 + "  }\n"
202                 + "</script></head>\n"
203 
204                 + "<body onload='init()'>\n"
205                 + "<form>\n"
206                 + LOG_TEXTAREA
207                 + "  <select id='s' size='2' >\n"
208                 + "    <option id='clickId' value='a' >A</option>\n"
209                 + "  </select>\n"
210                 + "</form>\n"
211 
212                 + "</body></html>";
213 
214         final WebDriver driver = loadPage2(html);
215 
216         driver.findElement(By.id("clickId")).click();
217 
218         verifyTextArea2(driver, getExpectedAlerts());
219     }
220 
221     /**
222      * Test for the right event sequence when clicking.
223      *
224      * @throws Exception if the test fails
225      */
226     @Test
227     @Alerts({"onchange-select", "change-SELECT", "onclick-option", "click-OPTION", "onclick-select", "click-OPTION"})
228     @BuggyWebDriver(CHROME = {"onchange-select", "change-SELECT", "onclick-select", "click-SELECT"},
229             EDGE = {"onchange-select", "change-SELECT", "onclick-select", "click-SELECT"},
230             FF = {"onchange-select", "change-SELECT", "onclick-select", "click-SELECT"},
231             FF_ESR = {"onchange-select", "change-SELECT", "onclick-select", "click-SELECT"})
232     public void clickOptionEventSequence3() throws Exception {
233         final String html = DOCTYPE_HTML
234                 + "<html><head>\n"
235                 + "<script>\n"
236                 + LOG_TEXTAREA_FUNCTION
237 
238                 + "  function init() {\n"
239                 + "    var s = document.getElementById('s');\n"
240                 + "    var o = document.getElementById('clickId');\n"
241                 + "    s.addEventListener('click', handle, false);\n"
242                 + "    s.addEventListener('change', handle, false);\n"
243                 + "    o.addEventListener('click', handle, false);\n"
244                 + "    o.addEventListener('change', handle, false);\n"
245                 + "  }\n"
246 
247                 + "  function handle(event) {\n"
248                 + "    if (event.target) {\n"
249                 + "      log(event.type + '-' + event.target.nodeName);\n"
250                 + "    } else {\n"
251                 + "      log(event.type + '-' + event.srcElement.nodeName);\n"
252                 + "    }\n"
253                 + "  }\n"
254                 + "</script></head>\n"
255 
256                 + "<body onload='init()'>\n"
257                 + "<form>\n"
258                 + LOG_TEXTAREA
259                 + "  <select id='s' size='2' onclick=\"log('onclick-select')\""
260                         + " onchange=\"log('onchange-select')\">\n"
261                 + "    <option id='clickId' value='a' onclick=\"log('onclick-option')\""
262                         + " onchange=\"log('onchange-option')\">A</option>\n"
263                 + "  </select>\n"
264                 + "</form>\n"
265 
266                 + "</body></html>";
267 
268         final WebDriver driver = loadPage2(html);
269 
270         driver.findElement(By.id("clickId")).click();
271 
272         verifyTextArea2(driver, getExpectedAlerts());
273     }
274 
275     /**
276      * Regression test for 3171569: unselecting the selected option should select the first one (FF)
277      * or have no effect (IE).
278      * @throws Exception if the test fails
279      */
280     @Test
281     @Alerts({"1", "option1", "0"})
282     public void unselectResetToFirstOption() throws Exception {
283         final String html = DOCTYPE_HTML
284             + "<html><head><script>\n"
285             + LOG_TITLE_FUNCTION
286             + "function doTest() {\n"
287             + "  var sel = document.form1.select1;\n"
288             + "  log(sel.selectedIndex);\n"
289             + "  sel.options[1].selected = false;\n"
290             + "  log(sel.value);\n"
291             + "  log(sel.selectedIndex);\n"
292             + "}</script></head><body onload='doTest()'>\n"
293             + "<form name='form1'>\n"
294             + "  <select name='select1'>\n"
295             + "    <option value='option1' name='option1'>One</option>\n"
296             + "    <option value='option2' name='option2' selected>Two</option>\n"
297             + "  </select>\n"
298             + "</form>\n"
299             + "</body></html>";
300 
301         loadPageVerifyTitle2(html);
302     }
303 
304     /**
305      * @throws Exception if an error occurs
306      */
307     @Test
308     @Alerts({"1", "", "-1"})
309     public void unselectResetToFirstOption1() throws Exception {
310         final String html = DOCTYPE_HTML
311             + "<html><head><script>\n"
312             + LOG_TITLE_FUNCTION
313             + "function doTest() {\n"
314             + "  var sel = document.form1.select1;\n"
315             + "  log(sel.selectedIndex);\n"
316             + "  sel.options[1].selected = false;\n"
317             + "  log(sel.value);\n"
318             + "  log(sel.selectedIndex);\n"
319             + "}</script></head><body onload='doTest()'>\n"
320             + "<form name='form1'>\n"
321             + "  <select name='select1' size='4'>\n"
322             + "    <option value='option1' name='option1'>One</option>\n"
323             + "    <option value='option2' name='option2' selected>Two</option>\n"
324             + "  </select>\n"
325             + "</form>\n"
326             + "</body></html>";
327 
328         loadPageVerifyTitle2(html);
329     }
330 
331     /**
332      * @throws Exception if the test fails
333      */
334     @Test
335     @Alerts("1")
336     public void selectFromJSTriggersNoFocusEvent() throws Exception {
337         final String html = DOCTYPE_HTML
338             + "<html><head><script>\n"
339             + LOG_TITLE_FUNCTION
340             + "function doTest() {\n"
341             + "  var sel = document.form1.select1;\n"
342             + "  sel.options[1].selected = true;\n"
343             + "  log(sel.selectedIndex);\n"
344             + "}\n"
345             + "</script></head><body onload='doTest()'>\n"
346             + "<form name='form1'>\n"
347             + "  <select name='select1' onfocus='log(\"focus\")'>\n"
348             + "    <option value='option1' name='option1'>One</option>\n"
349             + "    <option value='option2' name='option2'>Two</option>\n"
350             + "  </select>\n"
351             + "</form>\n"
352             + "</body></html>";
353 
354         loadPageVerifyTitle2(html);
355     }
356 
357     /**
358      * @throws Exception if the test fails
359      */
360     @Test
361     @Alerts({"false", "true", "true", "false", "true"})
362     public void disabledAttribute() throws Exception {
363         final String html = DOCTYPE_HTML
364             + "<html>\n"
365             + "  <head>\n"
366             + "    <script>\n"
367             + LOG_TITLE_FUNCTION
368             + "      function test() {\n"
369             + "        var test1 = document.getElementById('test1');\n"
370             + "        log(test1.disabled);\n"
371             + "        test1.disabled = true;\n"
372             + "        log(test1.disabled);\n"
373             + "        test1.disabled = true;\n"
374             + "        log(test1.disabled);\n"
375             + "        test1.disabled = false;\n"
376             + "        log(test1.disabled);\n"
377 
378             + "        var test2 = document.getElementById('test2');\n"
379             + "        log(test2.disabled);\n"
380             + "      }\n"
381             + "    </script>\n"
382             + "  </head>\n"
383             + "  <body onload='test()'>\n"
384             + "    <form name='form1'>\n"
385             + "      <select>\n"
386             + "        <option id='test1' value='option1'>Option1</option>\n"
387             + "        <option id='test2' value='option2' disabled>Option2</option>\n"
388             + "      </select>\n"
389             + "  </form>\n"
390             + "</body></html>";
391         loadPageVerifyTitle2(html);
392     }
393 
394     /**
395      * @throws Exception if the test fails
396      */
397     @Test
398     @Alerts({"some text", "some value", "false", "some other text", "some other value", "true"})
399     public void readPropsBeforeAdding() throws Exception {
400         final String html = DOCTYPE_HTML
401             + "<html><head><script>\n"
402             + LOG_TITLE_FUNCTION
403             + "function doTest() {\n"
404             + "  var oOption = new Option('some text', 'some value');\n"
405             + "  log(oOption.text);\n"
406             + "  log(oOption.value);\n"
407             + "  log(oOption.selected);\n"
408             + "  oOption.text = 'some other text';\n"
409             + "  oOption.value = 'some other value';\n"
410             + "  oOption.selected = true;\n"
411             + "  log(oOption.text);\n"
412             + "  log(oOption.value);\n"
413             + "  log(oOption.selected);\n"
414             + "}</script></head><body onload='doTest()'>\n"
415             + "<p>hello world</p>\n"
416             + "</body></html>";
417 
418         loadPageVerifyTitle2(html);
419     }
420 
421     /**
422      * Regression test for bug 313.
423      * See http://sourceforge.net/p/htmlunit/bugs/313/.
424      * @throws Exception if the test fails
425      */
426     @Test
427     public void selectingOrphanedOptionCreatedByDocument() throws Exception {
428         final String html = DOCTYPE_HTML
429             + "<html>\n"
430             + "<body>\n"
431             + "<form name='myform'/>\n"
432             + "<script>\n"
433             + "var select = document.createElement('select');\n"
434             + "var opt = document.createElement('option');\n"
435             + "opt.value = 'x';\n"
436             + "opt.selected = true;\n"
437             + "select.appendChild(opt);\n"
438             + "document.myform.appendChild(select);\n"
439             + "</script>\n"
440             + "</body></html>";
441 
442         loadPage2(html);
443     }
444 
445     /**
446      * Regression test for 1592728.
447      * @throws Exception if the test fails
448      */
449     @Test
450     @Alerts({"2", "2"})
451     public void setSelected() throws Exception {
452         final String html = DOCTYPE_HTML
453             + "<html><head><script>\n"
454             + LOG_TITLE_FUNCTION
455             + "function doTest() {\n"
456             + "  var sel = document.form1.select1;\n"
457             + "  log(sel.selectedIndex);\n"
458             + "  sel.options[0].selected = false;\n"
459             + "  log(sel.selectedIndex);\n"
460             + "}</script></head><body onload='doTest()'>\n"
461             + "<form name='form1'>\n"
462             + "  <select name='select1' onchange='this.form.submit()'>\n"
463             + "    <option value='option1' name='option1'>One</option>\n"
464             + "    <option value='option2' name='option2'>Two</option>\n"
465             + "    <option value='option3' name='option3' selected>Three</option>\n"
466             + "  </select>\n"
467             + "</form>\n"
468             + "</body></html>";
469 
470         loadPageVerifyTitle2(html);
471     }
472 
473     /**
474      * Regression test for 1672048.
475      * @throws Exception if the test fails
476      */
477     @Test
478     public void setAttribute() throws Exception {
479         final String html = DOCTYPE_HTML
480             + "<html>\n"
481             + "<head><title>foo</title>\n"
482             + "<script>\n"
483             + "  function doTest() {\n"
484             + "    document.getElementById('option1').setAttribute('class', 'bla bla');\n"
485             + "    var o = new Option('some text', 'some value');\n"
486             + "    o.setAttribute('class', 'myClass');\n"
487             + "  }\n"
488             + "</script>\n"
489             + "</head>\n"
490             + "<body onload='doTest()'>\n"
491             + "  <form name='form1'>\n"
492             + "    <select name='select1'>\n"
493             + "      <option value='option1' id='option1' name='option1'>One</option>\n"
494             + "    </select>\n"
495             + "  </form>\n"
496             + "</body></html>";
497 
498         loadPage2(html);
499     }
500 
501     /**
502      * @throws Exception if the test fails
503      */
504     @Test
505     @Alerts({"undefined", "undefined"})
506     public void optionIndexOutOfBound() throws Exception {
507         final String html = DOCTYPE_HTML
508             + "<html>\n"
509             + "<head>\n"
510             + "<script>\n"
511             + LOG_TITLE_FUNCTION
512             + "function doTest() {\n"
513             + "  var options = document.getElementById('testSelect').options;\n"
514             + "  log(options[55]);\n"
515             + "  try {\n"
516             + "    log(options[-55]);\n"
517             + "  } catch(e) { logEx(e); }\n"
518             + "}\n"
519             + "</script>\n"
520             + "</head>\n"
521             + "<body onload='doTest()'>\n"
522             + "  <form name='form1'>\n"
523             + "    <select name='select1' id='testSelect'>\n"
524             + "      <option value='option1' name='option1'>One</option>\n"
525             + "    </select>\n"
526             + "  </form>\n"
527             + "</body></html>";
528 
529         loadPageVerifyTitle2(html);
530     }
531 
532     /**
533      * @throws Exception if the test fails
534      */
535     @Test
536     @Alerts({"o2: text: Option 2, label: Option 2, value: 2, defaultSelected: false, selected: false",
537              "o3: text: Option 3, label: Option 3, value: 3, defaultSelected: true, selected: false",
538              "0", "1"})
539     public void constructor() throws Exception {
540         final String html = DOCTYPE_HTML
541             + "<html><head><script>\n"
542             + LOG_TITLE_FUNCTION
543             + "function dumpOption(_o) {\n"
544             + "  return 'text: ' + _o.text\n"
545             + " + ', label: ' + _o.label\n"
546             + " + ', value: ' + _o.value\n"
547             + " + ', defaultSelected: ' + _o.defaultSelected\n"
548             + " + ', selected: ' + _o.selected;\n"
549             + "}\n"
550             + "function doTest() {\n"
551             + "  var o2 = new Option('Option 2', '2');\n"
552             + "  log('o2: ' + dumpOption(o2));\n"
553             + "  var o3 = new Option('Option 3', '3', true, false);\n"
554             + "  log('o3: ' + dumpOption(o3));\n"
555             + "  document.form1.select1.appendChild(o3);\n"
556             + "  log(document.form1.select1.options.selectedIndex);\n"
557             + "  document.form1.reset();\n"
558             + "  log(document.form1.select1.options.selectedIndex);\n"
559             + "}\n"
560             + "</script></head><body onload='doTest()'>\n"
561             + "<form name='form1'>\n"
562             + "  <select name='select1' id='testSelect'>\n"
563             + "    <option value='option1' name='option1'>One</option>\n"
564             + "  </select>\n"
565             + "</form>\n"
566             + "</body></html>";
567 
568         loadPageVerifyTitle2(html);
569     }
570 
571     /**
572      * @throws Exception if the test fails
573      */
574     @Test
575     @Alerts("0")
576     public void insideBold() throws Exception {
577         final String html = DOCTYPE_HTML
578             + "<html><head><script>\n"
579             + LOG_TITLE_FUNCTION
580             + "function test() {\n"
581             + "  var sel = document.form1.select1;\n"
582             + "  sel.options[0] = null;\n"
583             + "  log(sel.options.length);\n"
584             + "}</script></head><body onload='test()'>\n"
585             + "<form name='form1'>\n"
586             + "  <b>\n"
587             + "    <select name='select1'>\n"
588             + "      <option>One</option>\n"
589             + "    </select>\n"
590             + "  </b>\n"
591             + "</form>\n"
592             + "</body></html>";
593 
594         loadPageVerifyTitle2(html);
595     }
596 
597     /**
598      * @throws Exception if the test fails
599      */
600     @Test
601     @Alerts({"null", "[object Attr]", "null", "null", "null",
602              "null", "null", "null", "null", "null"})
603     public void getAttributeNode() throws Exception {
604         final String html = DOCTYPE_HTML
605             + "<html><head><script>\n"
606             + LOG_TITLE_FUNCTION
607             + "function doTest() {\n"
608             + "  var s = document.getElementById('testSelect');\n"
609             + "  var o1 = s.options[0];\n"
610             + "  log(o1.getAttributeNode('id'));\n"
611             + "  log(o1.getAttributeNode('name'));\n"
612             + "  log(o1.getAttributeNode('value'));\n"
613             + "  log(o1.getAttributeNode('selected'));\n"
614             + "  log(o1.getAttributeNode('foo'));\n"
615             + "  var o2 = s.options[1];\n"
616             + "  log(o2.getAttributeNode('id'));\n"
617             + "  log(o2.getAttributeNode('name'));\n"
618             + "  log(o2.getAttributeNode('value'));\n"
619             + "  log(o2.getAttributeNode('selected'));\n"
620             + "  log(o2.getAttributeNode('foo'));\n"
621             + "}\n"
622             + "</script></head>\n"
623             + "<body onload='doTest()'>\n"
624             + "<form name='form1'>\n"
625             + "  <select name='select1' id='testSelect'>\n"
626             + "    <option name='option1'>One</option>\n"
627             + "    <option>Two</option>\n"
628             + "  </select>\n"
629             + "</form>\n"
630             + "</body></html>";
631 
632         loadPageVerifyTitle2(html);
633     }
634 
635     /**
636      * @throws Exception if the test fails
637      */
638     @Test
639     @Alerts({"false null null", "false null null", "true *selected selected",
640              "true null null", "false null null", "false *selected selected",
641              "false null null", "true null null", "false *selected selected",
642              "true null null", "false null null", "false *selected selected"})
643     public void selectedAttribute() throws Exception {
644         final String html = DOCTYPE_HTML
645             + "<html><head>\n"
646             + "<script>\n"
647             + LOG_TITLE_FUNCTION
648             + "  function info(opt) {\n"
649             + "    var attrNode = opt.getAttributeNode('selected');\n"
650             + "    if (attrNode) { attrNode = '*' + attrNode.value; }\n"
651             + "    log(opt.selected + ' ' + attrNode + ' ' + opt.getAttribute('selected'));\n"
652             + "  }\n"
653 
654             + "  function doTest() {\n"
655             + "    var s = document.getElementById('testSelect');\n"
656 
657             + "    var o1 = s.options[0];\n"
658             + "    var o2 = s.options[1];\n"
659             + "    var o3 = s.options[2];\n"
660 
661             + "    info(o1);info(o2);info(o3);\n"
662 
663             + "    o1.selected = true;\n"
664             + "    info(o1);info(o2);info(o3);\n"
665 
666             + "    o2.selected = true;\n"
667             + "    info(o1);info(o2);info(o3);\n"
668 
669             + "    o2.selected = false;\n"
670             + "    info(o1);info(o2);info(o3);\n"
671 
672             + "}\n"
673             + "</script></head>\n"
674             + "<body onload='doTest()'>\n"
675             + "<form name='form1'>\n"
676             + "  <select name='select1' id='testSelect'>\n"
677             + "    <option>One</option>\n"
678             + "    <option>Two</option>\n"
679             + "    <option selected='selected'>Three</option>\n"
680             + "  </select>\n"
681             + "</form>\n"
682             + "</body></html>";
683 
684         loadPageVerifyTitle2(html);
685     }
686 
687     /**
688      * @throws Exception if the test fails
689      */
690     @Test
691     @Alerts({"false null null", "false null null", "true *selected selected",
692              "true null null", "false null null", "true *selected selected",
693              "true null null", "true null null", "true *selected selected",
694              "true null null", "false null null", "true *selected selected"})
695     public void selectedAttributeMultiple() throws Exception {
696         final String html = DOCTYPE_HTML
697             + "<html><head>\n"
698             + "<script>\n"
699             + LOG_TITLE_FUNCTION
700             + "  function info(opt) {\n"
701             + "    var attrNode = opt.getAttributeNode('selected');\n"
702             + "    if (attrNode) { attrNode = '*' + attrNode.value; }\n"
703             + "    log(opt.selected + ' ' + attrNode + ' ' + opt.getAttribute('selected'));\n"
704             + "  }\n"
705 
706             + "  function doTest() {\n"
707             + "    var s = document.getElementById('testSelect');\n"
708 
709             + "    var o1 = s.options[0];\n"
710             + "    var o2 = s.options[1];\n"
711             + "    var o3 = s.options[2];\n"
712 
713             + "    info(o1);info(o2);info(o3);\n"
714 
715             + "    o1.selected = true;\n"
716             + "    info(o1);info(o2);info(o3);\n"
717 
718             + "    o2.selected = true;\n"
719             + "    info(o1);info(o2);info(o3);\n"
720 
721             + "    o2.selected = false;\n"
722             + "    info(o1);info(o2);info(o3);\n"
723 
724             + "}\n"
725             + "</script></head>\n"
726             + "<body onload='doTest()'>\n"
727             + "<form name='form1'>\n"
728             + "  <select name='select1' id='testSelect' multiple>\n"
729             + "    <option>One</option>\n"
730             + "    <option>Two</option>\n"
731             + "    <option selected='selected'>Three</option>\n"
732             + "  </select>\n"
733             + "</form>\n"
734             + "</body></html>";
735 
736         loadPageVerifyTitle2(html);
737     }
738 
739     /**
740      * @throws Exception if the test fails
741      */
742     @Test
743     @Alerts({"[object HTMLOptionsCollection]", "0", "1"})
744     public void with_new() throws Exception {
745         final String html = DOCTYPE_HTML
746             + "<html><head><script>\n"
747             + LOG_TITLE_FUNCTION
748             + "function doTest() {\n"
749             + "  var s = document.getElementById('testSelect');\n"
750             + "  log(s.options);\n"
751             + "  log(s.length);\n"
752             + "  try {\n"
753             + "    s.options[0] = new Option('one', 'two');\n"
754             + "  } catch(e) { log(e) }\n"
755             + "  log(s.length);\n"
756             + "}\n"
757             + "</script></head>\n"
758             + "<body onload='doTest()'>\n"
759             + "  <select id='testSelect'>\n"
760             + "  </select>\n"
761             + "</form>\n"
762             + "</body></html>";
763 
764         loadPageVerifyTitle2(html);
765     }
766 
767     /**
768      * @throws Exception if the test fails
769      */
770     @Test
771     @Alerts({"[object HTMLOptionsCollection]", "0", "TypeError", "0"})
772     public void without_new() throws Exception {
773         final String html = DOCTYPE_HTML
774             + "<html><head><script>\n"
775             + LOG_TITLE_FUNCTION
776             + "function doTest() {\n"
777             + "  var s = document.getElementById('testSelect');\n"
778             + "  log(s.options);\n"
779             + "  log(s.length);\n"
780             + "  try {\n"
781             + "    s.options[0] = Option('one', 'two');\n"
782             + "  } catch(e) { logEx(e) }\n"
783             + "  log(s.length);\n"
784             + "}\n"
785             + "</script></head>\n"
786             + "<body onload='doTest()'>\n"
787             + "  <select id='testSelect'>\n"
788             + "  </select>\n"
789             + "</form>\n"
790             + "</body></html>";
791 
792         loadPageVerifyTitle2(html);
793     }
794 
795     /**
796      * @throws Exception if the test fails
797      */
798     @Test
799     @Alerts({"text1", "New Text1", "", "New Text2", "text3", "New Text3", "text4", "New Text4"})
800     public void text() throws Exception {
801         final String html = DOCTYPE_HTML
802             + "<html>\n"
803             + "  <head>\n"
804             + "    <script>\n"
805             + LOG_TITLE_FUNCTION
806             + "      function test() {\n"
807             + "        var option = document.getElementsByTagName('option')[0];\n"
808             + "        log(option.text);\n"
809             + "        option.text = 'New Text1';\n"
810             + "        log(option.text);\n"
811 
812             + "        option = document.getElementsByTagName('option')[1];\n"
813             + "        log(option.text);\n"
814             + "        option.text = 'New Text2';\n"
815             + "        log(option.text);\n"
816 
817             + "        option = document.getElementsByTagName('option')[2];\n"
818             + "        log(option.text);\n"
819             + "        option.text = 'New Text3';\n"
820             + "        log(option.text);\n"
821 
822             + "        option = document.getElementsByTagName('option')[3];\n"
823             + "        log(option.text);\n"
824             + "        option.text = 'New Text4';\n"
825             + "        log(option.text);\n"
826             + "      }\n"
827             + "    </script>\n"
828             + "  </head>\n"
829             + "  <body onload='test()'>\n"
830             + "    <select>\n"
831             + "      <option value='value1' label='label1'>text1</option>\n"
832             + "      <option value='value2' label='label2'></option>\n"
833             + "      <option value='value3' label=''>text3</option>\n"
834             + "      <option value='value4' >text4</option>\n"
835             + "    </select>\n"
836             + "  </body>\n"
837             + "</html>";
838         loadPageVerifyTitle2(html);
839     }
840 
841     /**
842      * @throws Exception if the test fails
843      */
844     @Test
845     @Alerts({"null", "[object Text]", "null"})
846     public void setText() throws Exception {
847         final String html = DOCTYPE_HTML
848             + "<html><head><script>\n"
849             + LOG_TITLE_FUNCTION
850             + "function test() {\n"
851             + "  var s = document.getElementById('testSelect');\n"
852             + "  var lastIndex = s.length;\n"
853             + "  s.length += 1;\n"
854             + "  log(s[lastIndex].firstChild);\n"
855             + "  s[lastIndex].text  = 'text2';\n"
856             + "  log(s[lastIndex].firstChild);\n"
857             + "  s[lastIndex].text  = '';\n"
858             + "  log(s[lastIndex].firstChild);\n"
859             + "}\n"
860             + "</script></head><body onload='test()'>\n"
861             + "  <select id='testSelect'>\n"
862             + "    <option value='value1' label='label1'>text1</option>\n"
863             + "  </select>\n"
864             + "</form>\n"
865             + "</body></html>";
866 
867         loadPageVerifyTitle2(html);
868     }
869 
870     /**
871      * Visibility of elements should not impact the determination of the value of option
872      * without value attribute or the text of options. This tests for one part a regression
873      * introduced in rev. 4367 as well probably as a problem that exists since a long time.
874      * @throws Exception if the test fails
875      */
876     @Test
877     @Alerts({"text1", "text1b", "text2"})
878     public void text_when_not_displayed() throws Exception {
879         final String html = DOCTYPE_HTML
880             + "<html><head><script>\n"
881             + LOG_TITLE_FUNCTION
882             + "function test() {\n"
883             + "  var s = document.getElementById('testSelect1');\n"
884             + "  log(s.options[0].text);\n"
885             + "  log(s.options[1].text);\n"
886             + "  var s2 = document.getElementById('testSelect2');\n"
887             + "  log(s2.options[0].text);\n"
888             + "}\n"
889             + "</script></head><body onload='test()'>\n"
890             + "  <div style='display: none'>\n"
891             + "  <select id='testSelect1'>\n"
892             + "    <option>text1</option>\n"
893             + "    <option><strong>text1b</strong></option>\n"
894             + "  </select>\n"
895             + "  </div>\n"
896             + "  <div style='visibility: hidden'>\n"
897             + "  <select id='testSelect2'>\n"
898             + "    <option>text2</option>\n"
899             + "  </select>\n"
900             + "  </div>\n"
901             + "</form>\n"
902             + "</body></html>";
903 
904         loadPageVerifyTitle2(html);
905     }
906 
907     /**
908      * For IE nested nodes aren't used as default value attribute.
909      * @throws Exception if the test fails
910      */
911     @Test
912     @Alerts({"text0", "text1", "text1b", "text2"})
913     public void defaultValueFromNestedNodes() throws Exception {
914         final String html = DOCTYPE_HTML
915             + "<html><head><script>\n"
916             + LOG_TITLE_FUNCTION
917             + "function test() {\n"
918             + "  var s0 = document.getElementById('testSelect0');\n"
919             + "  log(s0.options[0].value);\n"
920             + "  var s = document.getElementById('testSelect1');\n"
921             + "  log(s.options[0].value);\n"
922             + "  log(s.options[1].value);\n"
923             + "  var s2 = document.getElementById('testSelect2');\n"
924             + "  log(s2.options[0].value);\n"
925             + "}\n"
926             + "</script></head><body onload='test()'>\n"
927             + "  <select id='testSelect0'>\n"
928             + "    <option>text0</option>\n"
929             + "  </select>\n"
930             + "  <div style='display: none'>\n"
931             + "  <select id='testSelect1'>\n"
932             + "    <option>text1</option>\n"
933             + "    <option><strong>text1b</strong></option>\n"
934             + "  </select>\n"
935             + "  </div>\n"
936             + "  <div style='visibility: hidden'>\n"
937             + "  <select id='testSelect2'>\n"
938             + "    <option>text2</option>\n"
939             + "  </select>\n"
940             + "  </div>\n"
941             + "</form>\n"
942             + "</body></html>";
943         loadPageVerifyTitle2(html);
944     }
945 
946     /**
947      * @throws Exception if the test fails
948      */
949     @Test
950     @Alerts("[object HTMLFormElement]")
951     public void form() throws Exception {
952         final String html = DOCTYPE_HTML
953             + "<html>\n"
954             + "<body>\n"
955             + "  <form>\n"
956             + "    <select id='s'>\n"
957             + "      <option>a</option>\n"
958             + "    </select>\n"
959             + "  </form>\n"
960             + "  <script>\n"
961             + LOG_TITLE_FUNCTION
962             + "    log(document.getElementById('s').options[0].form);\n"
963             + "  </script>\n"
964             + "</body></html>";
965         loadPageVerifyTitle2(html);
966     }
967 
968     /**
969      * @throws Exception if the test fails
970      */
971     @Test
972     @Alerts(DEFAULT = {"o2",
973                        "InvalidStateError: Failed to execute 'iterateNext' on 'XPathResult': "
974                             + "The document has mutated since the result was returned.",
975                        "1", "0", "o2",
976                        "InvalidStateError: Failed to execute 'iterateNext' on 'XPathResult': "
977                             + "The document has mutated since the result was returned."},
978             FF = {"o2",
979                   "InvalidStateError: XPathResult.iterateNext: "
980                         + "The document has been mutated since the result was returned",
981                   "1", "0", "o2",
982                   "InvalidStateError: XPathResult.iterateNext: "
983                         + "The document has been mutated since the result was returned"},
984             FF_ESR = {"o2",
985                       "InvalidStateError: XPathResult.iterateNext: "
986                             + "The document has been mutated since the result was returned",
987                       "1", "0", "o2",
988                       "InvalidStateError: XPathResult.iterateNext: "
989                             + "The document has been mutated since the result was returned"})
990     @HtmlUnitNYI(CHROME = {"o2", "1", "0", "o2"},
991             EDGE = {"o2", "1", "0", "o2"},
992             FF = {"o2", "1", "0", "o2"},
993             FF_ESR = {"o2", "1", "0", "o2"})
994     public void xpathSelected() throws Exception {
995         final String selectionChangeCode = "    sel.options[1].selected = false;\n";
996 
997         xpathSelected(selectionChangeCode, false);
998     }
999 
1000     /**
1001      * @throws Exception if the test fails
1002      */
1003     @Test
1004     @Alerts(DEFAULT = {"o2",
1005                        "InvalidStateError: Failed to execute 'iterateNext' on 'XPathResult': "
1006                             + "The document has mutated since the result was returned.",
1007                        "1", "1", "o2",
1008                        "InvalidStateError: Failed to execute 'iterateNext' on 'XPathResult': "
1009                             + "The document has mutated since the result was returned."},
1010             FF = {"o2",
1011                   "InvalidStateError: XPathResult.iterateNext: "
1012                         + "The document has been mutated since the result was returned",
1013                   "1", "1", "o2",
1014                   "InvalidStateError: XPathResult.iterateNext: "
1015                         + "The document has been mutated since the result was returned"},
1016             FF_ESR = {"o2",
1017                       "InvalidStateError: XPathResult.iterateNext: "
1018                         + "The document has been mutated since the result was returned",
1019                       "1", "1", "o2",
1020                       "InvalidStateError: XPathResult.iterateNext: "
1021                         + "The document has been mutated since the result was returned"})
1022     @HtmlUnitNYI(CHROME = {"o2", "1", "1", "o2"},
1023             EDGE = {"o2", "1", "1", "o2"},
1024             FF = {"o2", "1", "1", "o2"},
1025             FF_ESR = {"o2", "1", "1", "o2"})
1026     public void xpathSelectedSetAttribute() throws Exception {
1027         final String selectionChangeCode = "    sel.options[1].setAttribute('selected', false);\n";
1028 
1029         xpathSelected(selectionChangeCode, false);
1030     }
1031 
1032     /**
1033      * @throws Exception if the test fails
1034      */
1035     @Test
1036     @Alerts(DEFAULT = {"o2",
1037                        "InvalidStateError: Failed to execute 'iterateNext' on 'XPathResult': "
1038                             + "The document has mutated since the result was returned.",
1039                        "1", "-1", "o2",
1040                        "InvalidStateError: Failed to execute 'iterateNext' on 'XPathResult': "
1041                             + "The document has mutated since the result was returned."},
1042             FF = {"o2",
1043                   "InvalidStateError: XPathResult.iterateNext: "
1044                             + "The document has been mutated since the result was returned",
1045                   "1", "-1", "o2",
1046                   "InvalidStateError: XPathResult.iterateNext: "
1047                             + "The document has been mutated since the result was returned"},
1048             FF_ESR = {"o2",
1049                       "InvalidStateError: XPathResult.iterateNext: "
1050                             + "The document has been mutated since the result was returned",
1051                       "1", "-1", "o2",
1052                       "InvalidStateError: XPathResult.iterateNext: "
1053                             + "The document has been mutated since the result was returned"})
1054     @HtmlUnitNYI(CHROME = {"o2", "1", "-1", "o2"},
1055             EDGE = {"o2", "1", "-1", "o2"},
1056             FF = {"o2", "1", "-1", "o2"},
1057             FF_ESR = {"o2", "1", "-1", "o2"})
1058     public void xpathSelectedMultiple() throws Exception {
1059         final String selectionChangeCode = "    sel.options[1].selected = false;\n";
1060 
1061         xpathSelected(selectionChangeCode, true);
1062     }
1063 
1064     /**
1065      * @throws Exception if the test fails
1066      */
1067     @Test
1068     @Alerts(DEFAULT = {"o2",
1069                        "InvalidStateError: Failed to execute 'iterateNext' on 'XPathResult': "
1070                             + "The document has mutated since the result was returned.",
1071                        "1", "1", "o2",
1072                        "InvalidStateError: Failed to execute 'iterateNext' on 'XPathResult': "
1073                             + "The document has mutated since the result was returned."},
1074             FF = {"o2",
1075                   "InvalidStateError: XPathResult.iterateNext: "
1076                             + "The document has been mutated since the result was returned",
1077                   "1", "1", "o2",
1078                   "InvalidStateError: XPathResult.iterateNext: "
1079                             + "The document has been mutated since the result was returned"},
1080             FF_ESR = {"o2",
1081                       "InvalidStateError: XPathResult.iterateNext: "
1082                             + "The document has been mutated since the result was returned",
1083                       "1", "1", "o2",
1084                       "InvalidStateError: XPathResult.iterateNext: "
1085                             + "The document has been mutated since the result was returned"})
1086     @HtmlUnitNYI(CHROME = {"o2", "1", "1", "o2"},
1087             EDGE = {"o2", "1", "1", "o2"},
1088             FF = {"o2", "1", "1", "o2"},
1089             FF_ESR = {"o2", "1", "1", "o2"})
1090     public void xpathSelectedSetAttributeMultiple() throws Exception {
1091         final String selectionChangeCode = "    sel.options[1].setAttribute('selected', false);\n";
1092 
1093         xpathSelected(selectionChangeCode, false);
1094     }
1095 
1096     private void xpathSelected(final String selectionChangeCode, final boolean multiple) throws Exception {
1097         final String html = DOCTYPE_HTML
1098             + "<html>\n"
1099             + "<head>\n"
1100             + "<script>\n"
1101             + LOG_TITLE_FUNCTION
1102             + "  function test() {\n"
1103             + "    xpath();\n"
1104             + "    var sel = document.getElementById('s1');\n"
1105             + "    log(sel.selectedIndex);\n"
1106             + selectionChangeCode
1107             + "    log(sel.selectedIndex);\n"
1108             + "    xpath();\n"
1109             + "  }\n"
1110 
1111             + "  function xpath() {\n"
1112             + "    if (document.evaluate && XPathResult) {\n"
1113             + "      try {\n"
1114             + "        var result = document.evaluate('" + "//option[@selected]" + "', document.documentElement, "
1115                                             + "null, XPathResult.ANY_TYPE, null);\n"
1116 
1117             + "        var thisNode = result.iterateNext();\n"
1118             + "        while (thisNode) {\n"
1119             + "          log(thisNode.getAttribute('id'));\n"
1120             + "          thisNode = result.iterateNext();\n"
1121             + "        }\n"
1122             + "      } catch(e) { log(e); }\n"
1123             + "    } else {\n"
1124             + "      log('evaluate not supported');\n"
1125             + "    }\n"
1126             + "  }\n"
1127             + "</script>\n"
1128             + "</head>\n"
1129             + "<body onload='test()'>\n"
1130             + "  <form id='form1'>\n"
1131             + "    <select id='s1' name='select1' " + (multiple ? "multiple='multiple'" : "") + ">\n"
1132             + "      <option id='o1' value='option1'>Option1</option>\n"
1133             + "      <option id='o2' value='option2' selected='selected'>Option2</option>\n"
1134             + "      <option id='o3'value='option3'>Option3</option>\n"
1135             + "    </select>\n"
1136             + "  </form>\n"
1137             + "</body></html>";
1138 
1139         loadPageVerifyTitle2(html);
1140     }
1141 
1142     /**
1143      * @throws Exception if the test fails
1144      */
1145     @Test
1146     @Alerts({"value1", "text1", "label1", "value2", "text2", "text2"})
1147     public void label() throws Exception {
1148         final String html = DOCTYPE_HTML
1149             + "<html><head><script>\n"
1150             + LOG_TITLE_FUNCTION
1151             + "function test() {\n"
1152             + "  var s = document.getElementById('testSelect');\n"
1153             + "  var lastIndex = s.length;\n"
1154             + "  s.length += 1;\n"
1155             + "  s[lastIndex].value = 'value2';\n"
1156             + "  s[lastIndex].text  = 'text2';\n"
1157             + "  log(s[0].value);\n"
1158             + "  log(s[0].text);\n"
1159             + "  log(s[0].label);\n"
1160             + "  log(s[1].value);\n"
1161             + "  log(s[1].text);\n"
1162             + "  log(s[1].label);\n"
1163             + "}\n"
1164             + "</script></head><body onload='test()'>\n"
1165             + "  <select id='testSelect'>\n"
1166             + "    <option value='value1' label='label1'>text1</option>\n"
1167             + "  </select>\n"
1168             + "</form>\n"
1169             + "</body></html>";
1170 
1171         loadPageVerifyTitle2(html);
1172     }
1173 
1174     /**
1175      * @throws Exception if the test fails
1176      */
1177     @Test
1178     @Alerts({"", "", "", "", "text2", "text2", "text2", "label2"})
1179     public void setLabel() throws Exception {
1180         final String html = DOCTYPE_HTML
1181             + "<html><head><script>\n"
1182             + LOG_TITLE_FUNCTION
1183             + "function test() {\n"
1184             + "  var s = document.getElementById('testSelect');\n"
1185             + "  var lastIndex = s.length;\n"
1186             + "  s.length += 1;\n"
1187             + "  log(s[1].text);\n"
1188             + "  log(s[1].label);\n"
1189 
1190             + "  s[lastIndex].value = 'value2';\n"
1191             + "  log(s[1].text);\n"
1192             + "  log(s[1].label);\n"
1193 
1194             + "  s[lastIndex].text  = 'text2';\n"
1195             + "  log(s[1].text);\n"
1196             + "  log(s[1].label);\n"
1197 
1198             + "  s[lastIndex].label = 'label2';\n"
1199             + "  log(s[1].text);\n"
1200             + "  log(s[1].label);\n"
1201             + "}\n"
1202             + "</script></head><body onload='test()'>\n"
1203             + "  <select id='testSelect'>\n"
1204             + "    <option value='value1' label='label1'>text1</option>\n"
1205             + "  </select>\n"
1206             + "</form>\n"
1207             + "</body></html>";
1208 
1209         loadPageVerifyTitle2(html);
1210     }
1211 
1212     /**
1213      * @throws Exception if the test fails
1214      */
1215     @Test
1216     @Alerts({"0", "1", "2", "0"})
1217     public void index() throws Exception {
1218         final String html = DOCTYPE_HTML
1219             + "<html>\n"
1220             + "<head>\n"
1221             + "<script>\n"
1222             + LOG_TITLE_FUNCTION
1223             + "  function test() {\n"
1224             + "    var opt = document.getElementById('o1');\n"
1225             + "    log(opt.index);\n"
1226 
1227             + "    opt = document.getElementById('o2');\n"
1228             + "    log(opt.index);\n"
1229 
1230             + "    opt = document.getElementById('o3');\n"
1231             + "    log(opt.index);\n"
1232 
1233             + "    opt = document.createElement('option');\n"
1234             + "    log(opt.index);\n"
1235             + "  }\n"
1236             + "</script>\n"
1237             + "</head>\n"
1238             + "<body onload='test()'>\n"
1239             + "  <form id='form1'>\n"
1240             + "    <select id='s1'>\n"
1241             + "      <option id='o1' value='option1'>Option1</option>\n"
1242             + "      <option id='o2' value='option2' selected='selected'>Option2</option>\n"
1243             + "      <option id='o3'value='option3'>Option3</option>\n"
1244             + "    </select>\n"
1245             + "  </form>\n"
1246             + "</body></html>";
1247 
1248         loadPageVerifyTitle2(html);
1249     }
1250 
1251     /**
1252      * @throws Exception if the test fails
1253      */
1254     @Test
1255     @Alerts({"false-null", "true-selected", "false-null",
1256              "true-null", "false-selected", "false-null",
1257              "false-null", "false-selected", "false-null"})
1258     public void selectAndAttribute() throws Exception {
1259         final String html = DOCTYPE_HTML
1260             + "<html>\n"
1261             + "<head>\n"
1262             + "<script>\n"
1263             + LOG_TITLE_FUNCTION
1264             + "  function test() {\n"
1265             + "    var s1 = document.getElementById('select1');\n"
1266             + "    var o1 = document.getElementById('option1');\n"
1267             + "    var o2 = document.getElementById('option2');\n"
1268             + "    var o3 = document.getElementById('option3');\n"
1269 
1270             + "    log(o1.selected + '-' + o1.getAttribute('selected'));\n"
1271             + "    log(o2.selected + '-' + o2.getAttribute('selected'));\n"
1272             + "    log(o3.selected + '-' + o3.getAttribute('selected'));\n"
1273 
1274             + "    o1.selected = true;\n"
1275             + "    log(o1.selected + '-' + o1.getAttribute('selected'));\n"
1276             + "    log(o2.selected + '-' + o2.getAttribute('selected'));\n"
1277             + "    log(o3.selected + '-' + o3.getAttribute('selected'));\n"
1278 
1279             + "    s1.selectedIndex = 3;\n"
1280             + "    log(o1.selected + '-' + o1.getAttribute('selected'));\n"
1281             + "    log(o2.selected + '-' + o2.getAttribute('selected'));\n"
1282             + "    log(o3.selected + '-' + o3.getAttribute('selected'));\n"
1283             + "  }\n"
1284             + "</script>\n"
1285             + "</head>\n"
1286             + "<body onload='test()'>\n"
1287             + "  <form id='form1'>\n"
1288             + "    <select name='select1' id='select1'>\n"
1289             + "      <option value='option1' id='option1'>Option1</option>\n"
1290             + "      <option value='option2' id='option2' selected='selected'>Option2</option>\n"
1291             + "      <option value='option3' id='option3'>Option3</option>\n"
1292             + "    </select>\n"
1293             + "  </form>\n"
1294             + "</body></html>";
1295 
1296         loadPageVerifyTitle2(html);
1297     }
1298 
1299     /**
1300      * @throws Exception if the test fails
1301      */
1302     @Test
1303     @Alerts(DEFAULT = {"false-null", "true-true", "true-null",
1304                        "false-selected", "false-null", "true-true"},
1305             FF = {"false-null", "true-true", "true-null",
1306                   "false-selected", "false-null", "false-true"},
1307             FF_ESR = {"false-null", "true-true", "true-null",
1308                       "false-selected", "false-null", "false-true"})
1309     @HtmlUnitNYI(FF = {"false-null", "true-true", "true-null", "false-selected", "false-null", "true-true"},
1310             FF_ESR = {"false-null", "true-true", "true-null", "false-selected", "false-null", "true-true"})
1311     public void setSelectedAttribute() throws Exception {
1312         final String html = DOCTYPE_HTML
1313             + "<html>\n"
1314             + "<head>\n"
1315             + "<script>\n"
1316             + LOG_TITLE_FUNCTION
1317             + "  function test() {\n"
1318             + "    var o1 = document.getElementById('option1');\n"
1319             + "    log(o1.selected + '-' + o1.getAttribute('selected'));\n"
1320 
1321             + "    o1.setAttribute('selected', true);\n"
1322             + "    log(o1.selected + '-' + o1.getAttribute('selected'));\n"
1323 
1324             + "    o1.removeAttribute('selected');\n"
1325             + "    log(o1.selected + '-' + o1.getAttribute('selected'));\n"
1326 
1327             + "    var o2 = document.getElementById('option2');\n"
1328             + "    log(o2.selected + '-' + o2.getAttribute('selected'));\n"
1329 
1330             + "    o2.removeAttribute('selected');\n"
1331             + "    log(o2.selected + '-' + o2.getAttribute('selected'));\n"
1332 
1333             + "    o2.setAttribute('selected', true);\n"
1334             + "    log(o2.selected + '-' + o2.getAttribute('selected'));\n"
1335             + "  }\n"
1336             + "</script>\n"
1337             + "</head>\n"
1338             + "<body onload='test()'>\n"
1339             + "  <form id='form1'>\n"
1340             + "    <select name='select1' id='select1'>\n"
1341             + "      <option value='option1' id='option1'>Option1</option>\n"
1342             + "      <option value='option2' id='option2' selected='selected'>Option2</option>\n"
1343             + "    </select>\n"
1344             + "  </form>\n"
1345             + "</body></html>";
1346 
1347         loadPageVerifyTitle2(html);
1348     }
1349 
1350     /**
1351      * @throws Exception if the test fails
1352      */
1353     @Test
1354     @Alerts({"false-null", "true-true", "false-null",
1355              "false-null", "true-true", "false-null"})
1356     public void createOption() throws Exception {
1357         final String html = DOCTYPE_HTML
1358             + "<html>\n"
1359             + "<head>\n"
1360             + "<script>\n"
1361             + LOG_TITLE_FUNCTION
1362             + "  function test() {\n"
1363             + "    var o1 = document.createElement('option');\n"
1364 
1365             + "    log(o1.selected + '-' + o1.getAttribute('selected'));\n"
1366 
1367             + "    o1.setAttribute('selected', true);\n"
1368             + "    log(o1.selected + '-' + o1.getAttribute('selected'));\n"
1369 
1370             + "    o1.removeAttribute('selected');\n"
1371             + "    log(o1.selected + '-' + o1.getAttribute('selected'));\n"
1372 
1373             + "    var s1 = document.getElementById('select1');\n"
1374             + "    var o2 = document.createElement('option');\n"
1375             + "    s1.appendChild(o2);\n"
1376 
1377             + "    log(o2.selected + '-' + o2.getAttribute('selected'));\n"
1378 
1379             + "    o2.setAttribute('selected', true);\n"
1380             + "    log(o2.selected + '-' + o2.getAttribute('selected'));\n"
1381 
1382             + "    o2.removeAttribute('selected');\n"
1383             + "    log(o2.selected + '-' + o2.getAttribute('selected'));\n"
1384             + "  }\n"
1385             + "</script>\n"
1386             + "</head>\n"
1387             + "<body onload='test()'>\n"
1388             + "  <form id='form1'>\n"
1389             + "    <select name='select1' id='select1'>\n"
1390             + "      <option value='option1' id='option1'>Option1</option>\n"
1391             + "    </select>\n"
1392             + "  </form>\n"
1393             + "</body></html>";
1394 
1395         loadPageVerifyTitle2(html);
1396     }
1397 
1398     /**
1399      * @throws Exception if an error occurs
1400      */
1401     @Test
1402     @Alerts({"s-mouse over [select1]", "o-mouse over [option1]", "s-mouse over [option1]"})
1403     @BuggyWebDriver({"o-mouse over [option1]", "s-mouse over [option1]"})
1404     public void mouseOver() throws Exception {
1405         shutDownAll();
1406 
1407         final String html = DOCTYPE_HTML
1408             + "<html>\n"
1409             + "  <head>\n"
1410             + "    <script>\n"
1411             + LOG_TEXTAREA_FUNCTION
1412             + "    function dumpEvent(event, pre) {\n"
1413             + "      var eTarget;\n"
1414             + "      if (event.target) {\n"
1415             + "        eTarget = event.target;\n"
1416             + "      } else if (event.srcElement) {\n"
1417             + "        eTarget = event.srcElement;\n"
1418             + "      }\n"
1419             + "      // defeat Safari bug\n"
1420             + "      if (eTarget.nodeType == 3) {\n"
1421             + "        eTarget = eTarget.parentNode;\n"
1422             + "      }\n"
1423             + "      var msg = pre + '-mouse over';\n"
1424             + "      if (eTarget.name) {\n"
1425             + "        msg = msg + ' [' + eTarget.name + ']';\n"
1426             + "      } else {\n"
1427             + "        msg = msg + ' [' + eTarget.id + ']';\n"
1428             + "      }\n"
1429             + "      log(msg);\n"
1430             + "    }\n"
1431             + "    </script>\n"
1432             + "  </head>\n"
1433             + "<body>\n"
1434             + "  <form id='form1'>\n"
1435             + "    <select name='select1' id='select1' size='2' onmouseover='dumpEvent(event, \"s\");' >\n"
1436             + "      <option value='option1' id='option1' onmouseover='dumpEvent(event, \"o\");' >Option1</option>\n"
1437             + "      <option value='option2' id='option2'>Option2</option>\n"
1438             + "    </select>\n"
1439             + "  </form>\n"
1440             + LOG_TEXTAREA
1441             + "</body></html>";
1442 
1443         final WebDriver driver = loadPage2(html);
1444         final Actions actions = new Actions(driver);
1445         actions.moveToElement(driver.findElement(By.id("option1")));
1446         actions.perform();
1447 
1448         verifyTextArea2(driver, getExpectedAlerts());
1449     }
1450 
1451     /**
1452      * @throws Exception if an error occurs
1453      */
1454     @Test
1455     @Alerts({"s-mouse over [select1]", "o-mouse over [option1]", "s-mouse over [option1]"})
1456     @BuggyWebDriver({"o-mouse over [option1]", "s-mouse over [option1]"})
1457     public void mouseOverDisabledSelect() throws Exception {
1458         shutDownAll();
1459 
1460         final String html = DOCTYPE_HTML
1461             + "<html>\n"
1462             + "  <head>\n"
1463             + "    <script>\n"
1464             + LOG_TEXTAREA_FUNCTION
1465             + "    function dumpEvent(event, pre) {\n"
1466             + "      // target\n"
1467             + "      var eTarget;\n"
1468             + "      if (event.target) {\n"
1469             + "        eTarget = event.target;\n"
1470             + "      } else if (event.srcElement) {\n"
1471             + "        eTarget = event.srcElement;\n"
1472             + "      }\n"
1473             + "      // defeat Safari bug\n"
1474             + "      if (eTarget.nodeType == 3) {\n"
1475             + "        eTarget = eTarget.parentNode;\n"
1476             + "      }\n"
1477             + "      var msg = pre + '-mouse over';\n"
1478             + "      if (eTarget.name) {\n"
1479             + "        msg = msg + ' [' + eTarget.name + ']';\n"
1480             + "      } else {\n"
1481             + "        msg = msg + ' [' + eTarget.id + ']';\n"
1482             + "      }\n"
1483             + "      log(msg);\n"
1484             + "    }\n"
1485             + "    </script>\n"
1486             + "  </head>\n"
1487             + "<body>\n"
1488             + "  <form id='form1'>\n"
1489             + "    <select name='select1' id='select1' size='2' disabled='disabled' "
1490                             + "onmouseover='dumpEvent(event, \"s\");' >\n"
1491             + "      <option value='option1' id='option1' onmouseover='dumpEvent(event, \"o\");'>Option1</option>\n"
1492             + "      <option value='option2' id='option2'>Option2</option>\n"
1493             + "    </select>\n"
1494             + "  </form>\n"
1495             + LOG_TEXTAREA
1496             + "</body></html>";
1497 
1498         final WebDriver driver = loadPage2(html);
1499         final Actions actions = new Actions(driver);
1500         actions.moveToElement(driver.findElement(By.id("option1")));
1501         actions.perform();
1502 
1503         verifyTextArea2(driver, getExpectedAlerts());
1504     }
1505 
1506     /**
1507      * @throws Exception if an error occurs
1508      */
1509     @Test
1510     @Alerts({"s-mouse over [select1]", "o-mouse over [option1]", "s-mouse over [option1]"})
1511     @BuggyWebDriver({"o-mouse over [option1]", "s-mouse over [option1]"})
1512     public void mouseOverDisabledOption() throws Exception {
1513         shutDownAll();
1514 
1515         final String html = DOCTYPE_HTML
1516             + "<html>\n"
1517             + "  <head>\n"
1518             + "    <script>\n"
1519             + LOG_TEXTAREA_FUNCTION
1520             + "    function dumpEvent(event, pre) {\n"
1521             + "      // target\n"
1522             + "      var eTarget;\n"
1523             + "      if (event.target) {\n"
1524             + "        eTarget = event.target;\n"
1525             + "      } else if (event.srcElement) {\n"
1526             + "        eTarget = event.srcElement;\n"
1527             + "      }\n"
1528             + "      // defeat Safari bug\n"
1529             + "      if (eTarget.nodeType == 3) {\n"
1530             + "        eTarget = eTarget.parentNode;\n"
1531             + "      }\n"
1532             + "      var msg = pre + '-mouse over';\n"
1533             + "      if (eTarget.name) {\n"
1534             + "        msg = msg + ' [' + eTarget.name + ']';\n"
1535             + "      } else {\n"
1536             + "        msg = msg + ' [' + eTarget.id + ']';\n"
1537             + "      }\n"
1538             + "      if (msg.length == 0) { msg = '-' };\n"
1539             + "      log(msg);\n"
1540             + "    }\n"
1541             + "    </script>\n"
1542             + "  </head>\n"
1543             + "<body>\n"
1544             + "  <form id='form1'>\n"
1545             + "    <select name='select1' id='select1' size='2' onmouseover='dumpEvent(event, \"s\");' >\n"
1546             + "      <option value='option1' id='option1' onmouseover='dumpEvent(event, \"o\");' "
1547                                 + "disabled='disabled'>Option1</option>\n"
1548             + "      <option value='option2' id='option2'>Option2</option>\n"
1549             + "    </select>\n"
1550             + "  </form>\n"
1551             + LOG_TEXTAREA
1552             + "</body></html>";
1553 
1554         final WebDriver driver = loadPage2(html);
1555         final Actions actions = new Actions(driver);
1556         actions.moveToElement(driver.findElement(By.id("option1")));
1557         actions.perform();
1558 
1559         verifyTextArea2(driver, getExpectedAlerts());
1560     }
1561 }