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.html;
16  
17  import static java.nio.charset.StandardCharsets.UTF_8;
18  
19  import java.io.File;
20  import java.util.ArrayList;
21  import java.util.Arrays;
22  import java.util.Collections;
23  import java.util.List;
24  
25  import org.apache.commons.io.FileUtils;
26  import org.htmlunit.HttpMethod;
27  import org.htmlunit.MockWebConnection;
28  import org.htmlunit.Page;
29  import org.htmlunit.SimpleWebTestCase;
30  import org.htmlunit.junit.BrowserRunner;
31  import org.junit.Rule;
32  import org.junit.Test;
33  import org.junit.rules.TemporaryFolder;
34  import org.junit.runner.RunWith;
35  
36  /**
37   * Tests for {@link HtmlSelect}.
38   *
39   * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
40   * @author Mike Williams
41   * @author Marc Guillemot
42   * @author Ahmed Ashour
43   */
44  @RunWith(BrowserRunner.class)
45  public class HtmlSelectTest extends SimpleWebTestCase {
46  
47      /** JUnit rule must be public fields :-(. */
48      @Rule
49      public TemporaryFolder tmpFolderProvider_ = new TemporaryFolder();
50  
51      /**
52       * Test the good path of submitting a select.
53       * @exception Exception If the test fails
54       */
55      @Test
56      public void select() throws Exception {
57          final String htmlContent = DOCTYPE_HTML
58              + "<html><head><title>foo</title></head><body>\n"
59              + "<form id='form1'><select name='select1'>\n"
60              + "<option value='option1'>Option1</option>\n"
61              + "<option value='option2' selected='selected'>Option2</option>\n"
62              + "<option value='option3'>Option3</option>\n"
63              + "</select>\n"
64              + "<input type='submit' name='button' value='foo'/>\n"
65              + "</form></body></html>";
66          final HtmlPage page = loadPage(htmlContent);
67          final MockWebConnection webConnection = getMockConnection(page);
68  
69          final HtmlForm form = page.getHtmlElementById("form1");
70  
71          final HtmlSelect select = form.getSelectsByName("select1").get(0);
72          final HtmlSubmitInput button = form.getInputByName("button");
73  
74          // Test that the select is being correctly identified as a submittable element
75          assertEquals(Arrays.asList(new Object[] {select, button}), form.getSubmittableElements(button));
76  
77          // Test that the correct value is being passed back up to the server
78          final HtmlPage secondPage = button.click();
79  
80          assertEquals("url", URL_FIRST + "?select1=option2&button=foo", secondPage.getUrl());
81          assertSame("method", HttpMethod.GET, webConnection.getLastMethod());
82          assertNotNull(secondPage);
83      }
84  
85      /**
86       * Tests submitting the select with no options selected.
87       * @exception Exception If the test fails
88       */
89      @Test
90      public void select_MultipleSelectNoneSelected() throws Exception {
91          final String htmlContent = DOCTYPE_HTML
92              + "<html><head><title>foo</title></head><body>\n"
93              + "<form id='form1'><select name='select1' multiple>\n"
94              + "<option value='option1'>Option1</option>\n"
95              + "<option value='option2'>Option2</option>\n"
96              + "<option value='option3'>Option3</option>\n"
97              + "</select>\n"
98              + "<input type='submit' name='button' value='foo'/>\n"
99              + "</form></body></html>";
100         final HtmlPage page = loadPage(htmlContent);
101         final MockWebConnection webConnection = getMockConnection(page);
102 
103         final HtmlForm form = page.getHtmlElementById("form1");
104 
105         final HtmlSelect select = form.getSelectsByName("select1").get(0);
106         assertNotNull(select);
107 
108         final HtmlSubmitInput button = form.getInputByName("button");
109 
110         // Test that the correct value is being passed back up to the server
111         final HtmlPage secondPage = button.click();
112 
113         assertEquals("url", URL_FIRST + "?button=foo", secondPage.getUrl());
114         assertSame("method", HttpMethod.GET, webConnection.getLastMethod());
115         assertNotNull(secondPage);
116     }
117 
118     /**
119      * Tests changing the selected option.
120      * @exception Exception If the test fails
121      */
122     @Test
123     public void select_ChangeSelectedOption_SingleSelect() throws Exception {
124         final String htmlContent = DOCTYPE_HTML
125             + "<html><head><title>foo</title></head><body>\n"
126             + "<form id='form1'><select name='select1'>\n"
127             + "<option value='option1' selected='selected'>Option1</option>\n"
128             + "<option value='option2'>Option2</option>\n"
129             + "<option value='option3'>Option3</option>\n"
130             + "</select>\n"
131             + "<input type='submit' name='button' value='foo'/>\n"
132             + "</form></body></html>";
133         final HtmlPage page = loadPage(htmlContent);
134         final MockWebConnection webConnection = getMockConnection(page);
135 
136         final HtmlForm form = page.getHtmlElementById("form1");
137 
138         final HtmlSelect select = form.getSelectsByName("select1").get(0);
139         final HtmlSubmitInput button = form.getInputByName("button");
140 
141         // Change the value
142         select.setSelectedAttribute("option3", true);
143 
144         // Test that the correct value is being passed back up to the server
145         final HtmlPage secondPage = button.click();
146 
147         assertEquals("url", URL_FIRST + "?select1=option3&button=foo", secondPage.getUrl());
148         assertSame("method", HttpMethod.GET, webConnection.getLastMethod());
149         assertNotNull(secondPage);
150     }
151 
152     /**
153      * Tests changing the selected option.
154      * @exception Exception If the test fails
155      */
156     @Test
157     public void select_ChangeSelectedOption_MultipleSelect() throws Exception {
158         final String htmlContent = DOCTYPE_HTML
159             + "<html><head><title>foo</title></head><body>\n"
160             + "<form id='form1'><select name='select1' multiple='multiple'>\n"
161             + "<option value='option1' selected='selected'>Option1</option>\n"
162             + "<option value='option2'>Option2</option>\n"
163             + "<option value='option3'>Option3</option>\n"
164             + "</select>\n"
165             + "<input type='submit' name='button' value='foo'/>\n"
166             + "</form></body></html>";
167         final HtmlPage page = loadPage(htmlContent);
168         final MockWebConnection webConnection = getMockConnection(page);
169 
170         final HtmlForm form = page.getHtmlElementById("form1");
171 
172         final HtmlSelect select = form.getSelectsByName("select1").get(0);
173         final HtmlSubmitInput button = form.getInputByName("button");
174 
175         // Change the value
176         select.setSelectedAttribute("option3", true);
177         select.setSelectedAttribute("option2", true);
178 
179         // Test that the correct value is being passed back up to the server
180         final HtmlPage secondPage = button.click();
181 
182         assertEquals("url", URL_FIRST + "?select1=option1&select1=option2&select1=option3&button=foo",
183                 secondPage.getUrl());
184         assertSame("method", HttpMethod.GET, webConnection.getLastMethod());
185         assertNotNull(secondPage);
186     }
187 
188     /**
189      * Tests multiple selected options on multiple select lists.
190      * @exception Exception If the test fails
191      */
192     @Test
193     public void select_MultipleSelectMultipleSelected() throws Exception {
194         final String htmlContent = DOCTYPE_HTML
195             + "<html><head><title>foo</title></head><body>\n"
196             + "<form id='form1'><select name='select1' multiple>\n"
197             + "<option value='option1' selected='selected'>Option1</option>\n"
198             + "<option value='option2'>Option2</option>\n"
199             + "<option value='option3' selected='selected'>Option3</option>\n"
200             + "</select>\n"
201             + "<input type='submit' name='button' value='foo'/>\n"
202             + "</form></body></html>";
203         final HtmlPage page = loadPage(htmlContent);
204 
205         final HtmlForm form = page.getHtmlElementById("form1");
206 
207         final HtmlSelect select = form.getSelectsByName("select1").get(0);
208         final List<HtmlOption> expected = new ArrayList<>();
209         expected.add(select.getOptionByValue("option1"));
210         expected.add(select.getOptionByValue("option3"));
211 
212         assertEquals(expected, select.getSelectedOptions());
213     }
214 
215     /**
216      * Test multiple selected options on single select lists. This is erroneous HTML, but
217      * browsers simply use the last option.
218      *
219      * @exception Exception If the test fails
220      */
221     @Test
222     public void select_SingleSelectMultipleSelected() throws Exception {
223         final String htmlContent = DOCTYPE_HTML
224             + "<html><head><title>foo</title></head><body>\n"
225             + "<form id='form1'><select name='select1'>\n"
226             + "<option value='option1' selected='selected'>Option1</option>\n"
227             + "<option value='option2'>Option2</option>\n"
228             + "<option value='option3' selected='selected'>Option3</option>\n"
229             + "</select>\n"
230             + "<input type='submit' name='button' value='foo'/>\n"
231             + "</form></body></html>";
232         final HtmlPage page = loadPage(htmlContent);
233 
234         final HtmlForm form = page.getHtmlElementById("form1");
235 
236         final HtmlSelect select = form.getSelectsByName("select1").get(0);
237         final List<HtmlOption> expected = new ArrayList<>();
238         expected.add(select.getOptionByValue("option3"));
239 
240         assertEquals(expected, select.getSelectedOptions());
241     }
242 
243     /**
244      * Test no selected options on single select lists. This is erroneous HTML, but
245      * browsers simply assume the first one to be selected
246      *
247      * @exception Exception If the test fails
248      */
249     @Test
250     public void select_SingleSelectNoneSelected() throws Exception {
251         final String htmlContent = DOCTYPE_HTML
252             + "<html><head><title>foo</title></head><body>\n"
253             + "<form id='form1'><select name='select1'>\n"
254             + "<option value='option1'>Option1</option>\n"
255             + "<option value='option2'>Option2</option>\n"
256             + "<option value='option3'>Option3</option>\n"
257             + "</select>\n"
258             + "<input type='submit' name='button' value='foo'/>\n"
259             + "</form></body></html>";
260         final HtmlPage page = loadPage(htmlContent);
261 
262         final HtmlForm form = page.getHtmlElementById("form1");
263 
264         final HtmlSelect select = form.getSelectsByName("select1").get(0);
265         final List<HtmlOption> expected = new ArrayList<>();
266         expected.add(select.getOptionByValue("option1"));
267 
268         assertEquals(expected, select.getSelectedOptions());
269     }
270 
271     /**
272      * Tests no selected options on single select lists with a size more than 1.
273      *
274      * @exception Exception If the test fails
275      */
276     @Test
277     public void select_SingleSelectNoneSelectedButSizeGreaterThanOne() throws Exception {
278         final String htmlContent = DOCTYPE_HTML
279             + "<html><head><title>foo</title></head><body>\n"
280             + "<form>\n"
281             + "<select name='select1' size='2' id='mySelect'>\n"
282             + "<option value='option1'>Option1</option>\n"
283             + "<option value='option2'>Option2</option>\n"
284             + "<option value='option3'>Option3</option>\n"
285             + "</select>\n"
286             + "</form></body></html>";
287 
288         final HtmlPage page = loadPage(htmlContent);
289 
290         final HtmlSelect select = page.getHtmlElementById("mySelect");
291 
292         assertEquals(Collections.EMPTY_LIST, select.getSelectedOptions());
293     }
294 
295     /**
296      * Tests changing the selected option.
297      * @exception Exception If the test fails
298      */
299     @Test
300     public void setSelected_IllegalValue() throws Exception {
301         final String htmlContent = DOCTYPE_HTML
302             + "<html><head><title>foo</title></head><body>\n"
303             + "<form id='form1'><select name='select1'>\n"
304             + "<option value='option1' selected='selected'>Option1</option>\n"
305             + "<option value='option2'>Option2</option>\n"
306             + "<option value='option3'>Option3</option>\n"
307             + "</select>\n"
308             + "<select name='select2'>\n"
309             + "</select>\n"
310             + "<input type='submit' name='button' value='foo'/>\n"
311             + "</form></body></html>";
312 
313         final HtmlPage page = loadPage(htmlContent);
314         final HtmlForm form = page.getHtmlElementById("form1");
315         final HtmlSelect select = form.getSelectByName("select1");
316 
317         select.setSelectedAttribute("missingOption", true);
318     }
319 
320     /**
321      * @throws Exception if the test fails
322      */
323     @Test
324     public void getOptions() throws Exception {
325         final String htmlContent = DOCTYPE_HTML
326             + "<html><head><title>foo</title></head><body>\n"
327             + "<form id='form1'><select name='select1'>\n"
328             + "<option value='option1' selected='selected'>Option1</option>\n"
329             + "<option value='option2'>Option2</option>\n"
330             + "<optgroup label='group1'>\n"
331             + "  <option value='option3'>Option3</option>\n"
332             + "</optgroup>\n"
333             + "</select>\n"
334             + "<input type='submit' name='button' value='foo'/>\n"
335             + "</form></body></html>";
336         final HtmlPage page = loadPage(htmlContent);
337 
338         final HtmlForm form = page.getHtmlElementById("form1");
339 
340         final HtmlSelect select = form.getSelectsByName("select1").get(0);
341 
342         final List<HtmlOption> expectedOptions = new ArrayList<>();
343         expectedOptions.add(select.getOptionByValue("option1"));
344         expectedOptions.add(select.getOptionByValue("option2"));
345         expectedOptions.add(select.getOptionByValue("option3"));
346 
347         assertEquals(expectedOptions, select.getOptions());
348     }
349 
350     /**
351      * @throws Exception if the test fails
352      */
353     @Test
354     public void select_OptionMultiple_NoValueOnAttribute() throws Exception {
355         final String htmlContent = DOCTYPE_HTML
356             + "<html><head><title>foo</title></head><body>\n"
357             + "<form id='form1'><select name='select1' id='select1' multiple>\n"
358             + "<option value='option1'>Option1</option>\n"
359             + "<option value='option2' >Option2</option>\n"
360             + "<option value='option3'>Option3</option>\n"
361             + "</select>\n"
362             + "<input type='submit' name='button' value='foo'/>\n"
363             + "</form></body></html>";
364         final HtmlPage page = loadPage(htmlContent);
365 
366         final HtmlSelect select = page.getHtmlElementById("select1");
367         assertTrue(select.isMultipleSelectEnabled());
368     }
369 
370     /**
371      * @throws Exception if the test fails
372      */
373     @Test
374     public void getOptionByValue() throws Exception {
375         final String htmlContent = DOCTYPE_HTML
376             + "<html><head><title>foo</title></head><body><form id='form1'>\n"
377             + "<select name='select1'>\n"
378             + "  <option value='option1'>s1o1</option>\n"
379             + "  <option value='option2'>s1o2</option>\n"
380             + "</select>\n"
381             + "<select name='select2'>\n"
382             + "  <option value='option1'>s2o1</option>\n"
383             + "  <option value='option2'>s2o2</option>\n"
384             + "  <option>s2o3</option>\n"
385             + "</select>\n"
386             + "<input type='submit' name='button' value='foo'/>\n"
387             + "</form></body></html>";
388         final HtmlPage page = loadPage(htmlContent);
389 
390         final HtmlForm form = page.getHtmlElementById("form1");
391 
392         final HtmlSelect select = form.getSelectsByName("select2").get(0);
393         assertEquals("s2o2", select.getOptionByValue("option2").asNormalizedText());
394 
395         assertEquals(select.getOption(2), select.getOptionByValue("s2o3"));
396     }
397 
398     /**
399      * @throws Exception if the test fails
400      */
401     @Test
402     public void select_SetSelected_OnChangeHandler() throws Exception {
403         final String htmlContent = DOCTYPE_HTML
404             + "<html><head><title>foo</title></head><body>\n"
405             + "<form id='form1'><select name='select1' onChange='alert(\"changing\")'>\n"
406             + "<option value='option1' selected='selected'>Option1</option>\n"
407             + "<option value='option2'>Option2</option>\n"
408             + "<option value='option3'>Option3</option>\n"
409             + "</select>\n"
410             + "<input type='submit' name='button' value='foo'/>\n"
411             + "</form></body></html>";
412         final List<String> collectedAlerts = new ArrayList<>();
413         final HtmlPage page = loadPage(htmlContent, collectedAlerts);
414 
415         final HtmlForm form = page.getHtmlElementById("form1");
416 
417         final HtmlSelect select = form.getSelectsByName("select1").get(0);
418 
419         // Change the value
420         select.setSelectedAttribute("option3", true);
421 
422         final String[] expectedAlerts = {"changing"};
423         assertEquals(expectedAlerts, collectedAlerts);
424     }
425 
426     /**
427      * @throws Exception if the test fails
428      */
429     @Test
430     public void setSelectionOnOptionWithNoName() throws Exception {
431         final String htmlContent = DOCTYPE_HTML
432             + "<html><body><form name='form' method='GET' action='action.html'>\n"
433             + "<select name='select' multiple size='5'>\n"
434             + "<option value='1'>111</option>\n"
435             + "<option id='option2'>222</option>\n"
436             + "</select>\n"
437             + "</form></body></html>";
438         final List<String> collectedAlerts = new ArrayList<>();
439         final HtmlPage page = loadPage(htmlContent, collectedAlerts);
440 
441         final HtmlOption option = page.getHtmlElementById("option2");
442         option.setSelected(true);
443     }
444 
445     private static void checkOptions(final HtmlSelect select) {
446         final List<HtmlOption> options = select.getOptions();
447         if (options.isEmpty()) {
448             assertNull(select.getFirstChild());
449             assertNull(select.getLastChild());
450         }
451         else {
452             assertEquals(options.get(0), select.getFirstChild());
453             assertEquals(options.get(options.size() - 1), select.getLastChild());
454         }
455     }
456 
457     /**
458      * @throws Exception if the test fails
459      */
460     @Test
461     public void removeOptionsFromSelect() throws Exception {
462         final String htmlContent = DOCTYPE_HTML
463             + "<html><body><form name='form' method='GET' action='action.html'>\n"
464             + "<select name='select' id='theSelect'>"
465             + "<option value='a'>111</option>"
466             + "<option value='b'>222</option>"
467             + "<option value='c'>333</option>"
468             + "<option value='d'>444</option>"
469             + "</select>\n"
470             + "</form></body></html>";
471         final HtmlPage page = loadPage(htmlContent);
472 
473         final HtmlSelect theSelect = page.getHtmlElementById("theSelect");
474         assertNotNull(theSelect);
475 
476         assertEquals(4, theSelect.getOptions().size());
477         assertEquals("a", theSelect.getOption(0).getValueAttribute());
478         assertEquals("b", theSelect.getOption(1).getValueAttribute());
479         assertEquals("c", theSelect.getOption(2).getValueAttribute());
480         assertEquals("d", theSelect.getOption(3).getValueAttribute());
481 
482         // remove from the middle
483         theSelect.getOption(1).remove();
484         checkOptions(theSelect);
485         assertEquals(3, theSelect.getOptions().size());
486         assertEquals("a", theSelect.getOption(0).getValueAttribute());
487         assertEquals("c", theSelect.getOption(1).getValueAttribute());
488         assertEquals("d", theSelect.getOption(2).getValueAttribute());
489 
490         // remove from the end
491         theSelect.getOption(2).remove();
492         checkOptions(theSelect);
493         assertEquals(2, theSelect.getOptions().size());
494         assertEquals("a", theSelect.getOption(0).getValueAttribute());
495         assertEquals("c", theSelect.getOption(1).getValueAttribute());
496 
497         // remove from the front
498         theSelect.getOption(0).remove();
499         checkOptions(theSelect);
500         assertEquals(1, theSelect.getOptions().size());
501         assertEquals("c", theSelect.getOption(0).getValueAttribute());
502 
503         // remove from the last one
504         theSelect.getOption(0).remove();
505         checkOptions(theSelect);
506         assertEquals(0, theSelect.getOptions().size());
507     }
508 
509     /**
510      * @throws Exception if the test fails
511      */
512     @Test
513     public void editOptions() throws Exception {
514         final String htmlContent = DOCTYPE_HTML
515             + "<html><body><form name='form' method='GET' action='action.html'>\n"
516             + "<select name='select' id='theSelect'>\n"
517             + "<option value='a'>111</option>\n"
518             + "<option value='b'>222</option>\n"
519             + "<option value='c'>333</option>\n"
520             + "</select>\n"
521             + "</form></body></html>";
522         final HtmlPage page = loadPage(htmlContent);
523 
524         final HtmlSelect theSelect = page.getHtmlElementById("theSelect");
525 
526         assertNotNull(theSelect);
527         assertEquals(3, theSelect.getOptions().size());
528 
529         appendOption(theSelect, "d");
530         assertEquals(4, theSelect.getOptions().size());
531         assertEquals("d", theSelect.getOption(3).getValueAttribute());
532 
533         theSelect.setOptionSize(1);
534         assertEquals(1, theSelect.getOptions().size());
535         assertEquals("a", theSelect.getOption(0).getValueAttribute());
536 
537         appendOption(theSelect, "x");
538         assertEquals(2, theSelect.getOptions().size());
539         assertEquals("x", theSelect.getOption(1).getValueAttribute());
540     }
541 
542     void appendOption(final HtmlSelect select, final String value) {
543         final HtmlOption option = (HtmlOption) select.getPage().getWebClient().getPageCreator().getHtmlParser()
544                     .getFactory(HtmlOption.TAG_NAME).createElement(select.getPage(), HtmlOption.TAG_NAME, null);
545         option.setValueAttribute(value);
546         option.setLabelAttribute(value);
547         select.appendOption(option);
548     }
549 
550     /**
551      * Test that asNormalizedText() returns a blank string if nothing is selected.
552      *
553      * @exception Exception If the test fails
554      */
555     @Test
556     public void asNormalizedTextWhenNothingSelected() throws Exception {
557         final String htmlContent = DOCTYPE_HTML
558             + "<html><head><title>foo</title></head><body>\n"
559             + "<form>\n"
560             + "<select name='select1' size='1' id='mySelect'>\n"
561             + "</select>\n"
562             + "</form></body></html>";
563 
564         final HtmlPage page = loadPage(htmlContent);
565 
566         final HtmlSelect select = page.getHtmlElementById("mySelect");
567 
568         assertEquals("", select.asNormalizedText());
569     }
570 
571     /**
572      * Verifies that asNormalizedText() returns all options when multiple options are selectable, instead of just
573      * the selected ones.
574      * @throws Exception if an error occurs
575      */
576     @Test
577     public void asNormalizedTextWithMultipleSelect() throws Exception {
578         final String html = DOCTYPE_HTML
579             + "<html><body><form>\n"
580             + "<select name='a' multiple>\n"
581             + "<option value='1'selected>foo</option>\n"
582             + "<option value='2'>bar</option>\n"
583             + "<option value='3' selected>baz</option>\n"
584             + "</select>\n"
585             + "</form></body></html>";
586         final HtmlPage page = loadPage(html);
587         final HtmlSelect select = (HtmlSelect) page.getDocumentElement().getElementsByTagName("select").get(0);
588         assertEquals("foo\nbaz", select.asNormalizedText());
589     }
590 
591     /**
592      * Test that setSelectedAttribute returns the right page.
593      *
594      * @exception Exception If the test fails
595      */
596     @Test
597     public void setSelectedAttributeReturnedPage() throws Exception {
598         final String content = DOCTYPE_HTML
599             + "<html><head><title>foo</title>\n"
600             + "<script>\n"
601             + "function test() {\n"
602             + "  document.getElementById('iframe').src = 'about:blank';\n"
603             + "}\n"
604             + "</script>\n"
605             + "</head><body>\n"
606             + "<form>\n"
607             + "<select name='select1' size='1' id='mySelect' onchange='test()'>\n"
608             + "<option value='option1'>option 1</option>\n"
609             + "<option value='option2'>option 2</option>\n"
610             + "</select>\n"
611             + "</form>\n"
612             + "<iframe id='iframe' src='about:blank'></iframe>\n"
613             + "</body></html>";
614 
615         final HtmlPage page = loadPage(content);
616 
617         final HtmlSelect select = page.getHtmlElementById("mySelect");
618         final HtmlOption option = select.getOptionByValue("option2");
619         final Page page2 = select.setSelectedAttribute(option, true);
620         assertEquals(page, page2);
621     }
622 
623     /**
624      * @throws Exception if the test fails
625      */
626     @Test
627     public void onChangeResultPage() throws Exception {
628         final String htmlContent = DOCTYPE_HTML
629             + "<html><head><title>foo</title></head><body>\n"
630             + "<form id='form1'>\n"
631             + "<select name='select1' id='select1' onchange='location=\"about:blank\"'>\n"
632             + "  <option id='option1'>Option1</option>\n"
633             + "  <option id='option2' selected>Number Two</option>\n"
634             + "</select>\n"
635             + "</form></body></html>";
636 
637         final HtmlPage page = loadPage(htmlContent);
638 
639         final HtmlOption option1 = page.getHtmlElementById("option1");
640         final HtmlPage page2 = option1.click();
641         assertEquals("about:blank", page2.getUrl());
642     }
643 
644     /**
645      * @throws Exception if the test fails
646      */
647     @Test
648     public void onChange_resultPage_newCurrentWindow() throws Exception {
649         final String htmlContent = DOCTYPE_HTML
650             + "<html><head><title>foo</title></head><body>\n"
651             + "<form id='form1'>\n"
652             + "<select name='select1' id='select1' onchange='window.open(\"about:blank\", \"_blank\")'>\n"
653             + "  <option id='option1'>Option1</option>\n"
654             + "  <option id='option2' selected>Number Two</option>\n"
655             + "</select>\n"
656             + "</form></body></html>";
657 
658         final HtmlPage page = loadPage(htmlContent);
659 
660         final HtmlSelect select = page.getHtmlElementById("select1");
661         final HtmlOption option1 = page.getHtmlElementById("option1");
662         final HtmlPage page2 = select.setSelectedAttribute(option1, true);
663         assertEquals("about:blank", page2.getUrl());
664     }
665 
666     /**
667      * @throws Exception if the test fails
668      */
669     @Test
670     public void asXml_size() throws Exception {
671         final String content = DOCTYPE_HTML
672             + "<html><head><title>foo</title></head>\n"
673             + "<body>\n"
674             + "<select/>\n"
675             + "</body></html>";
676 
677         final HtmlPage page = loadPage(content);
678         assertEquals(-1, page.asXml().indexOf("size"));
679     }
680 
681     /**
682      * @throws Exception if the test fails
683      */
684     @Test
685     public void select_focus() throws Exception {
686         final String htmlContent = DOCTYPE_HTML
687             + "<html><head><title>foo</title></head><body>\n"
688             + "<form id='form1'>\n"
689             + "<select name='select1' id='select1' multiple onfocus='alert(\"focus\")'>\n"
690             + "<option value='option1'>Option1</option>\n"
691             + "<option value='option2'>Option2</option>\n"
692             + "<option value='option3' selected>Option3</option>\n"
693             + "</select>\n"
694             + "<input type='submit' name='button' value='foo'/>\n"
695             + "</form></body></html>";
696 
697         final List<String> collectedAlerts = new ArrayList<>();
698         final HtmlPage page = loadPage(htmlContent, collectedAlerts);
699         assertEquals(Collections.emptyList(), collectedAlerts);
700 
701         final HtmlSelect select = page.getHtmlElementById("select1");
702         assertNotSame(select, page.getFocusedElement());
703         select.getOption(0).setSelected(true);
704         assertSame(select, page.getFocusedElement());
705 
706         final String[] expectedAlerts = {"focus"};
707         assertEquals(expectedAlerts, collectedAlerts);
708     }
709 
710     /**
711      * @throws Exception if the test fails
712      */
713     @Test
714     public void getOptionByText() throws Exception {
715         final String html = DOCTYPE_HTML
716             + "<html><head><title>foo</title></head><body><form id='form1'>\n"
717             + "<select name='select1'>\n"
718             + "  <option value='option1'>s1o1</option>\n"
719             + "  <option value='option2'>s1o2</option>\n"
720             + "</select>\n"
721             + "<select name='select2'>\n"
722             + "  <option value='option1'>s2o1</option>\n"
723             + "  <option value='option2'>s2o2</option>\n"
724             + "  <option>s2o3</option>\n"
725             + "</select>\n"
726             + "<input type='submit' name='button' value='foo'/>\n"
727             + "</form></body></html>";
728         final HtmlPage page = loadPage(html);
729 
730         final HtmlForm form = page.getHtmlElementById("form1");
731 
732         final HtmlSelect select = form.getSelectsByName("select2").get(0);
733         assertEquals("s2o2", select.getOptionByText("s2o2").asNormalizedText());
734 
735         assertEquals(select.getOption(2), select.getOptionByText("s2o3"));
736     }
737 
738     /**
739      * @throws Exception if the test fails
740      */
741     @Test
742     public void savePageSavesSelectedOption() throws Exception {
743         final String content = DOCTYPE_HTML
744             + "<html><body>\n"
745             + "<form action=''>\n"
746             + "  <select id='main'>\n"
747             + "    <option value='1'>option 1</option>\n"
748             + "    <option value='2'>option 2</option>\n"
749             + "    <option value='3' selected>option 3</option>\n"
750             + "  </select>\n"
751             + "</form>\n"
752             + "<script>\n"
753             + "var oSelect = document.getElementById('main');\n"
754             + "oSelect.options[1].selected = true;\n"
755             + "alert(oSelect.options[1].getAttribute('selected'));\n"
756             + "</script>\n"
757             + "</body></html>";
758 
759         final HtmlPage page = loadPage(content);
760         final HtmlSelect select = (HtmlSelect) page.getElementById("main");
761         assertEquals("option 2", select.getSelectedOptions().get(0).getText());
762 
763         // save the file and reload it
764         final File file = new File(tmpFolderProvider_.newFolder("tmp"), "test.html");
765         page.save(file);
766         final String html2 = FileUtils.readFileToString(file, UTF_8);
767         final HtmlPage page2 = loadPage(html2);
768         final HtmlSelect select2 = (HtmlSelect) page2.getElementById("main");
769         assertEquals("option 2", select2.getSelectedOptions().get(0).getText());
770     }
771 }