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 java.net.URL;
18  import java.util.ArrayList;
19  import java.util.Collections;
20  import java.util.List;
21  
22  import org.htmlunit.MockWebConnection;
23  import org.htmlunit.Page;
24  import org.htmlunit.SimpleWebTestCase;
25  import org.htmlunit.WebClient;
26  import org.htmlunit.html.HtmlForm;
27  import org.htmlunit.html.HtmlOption;
28  import org.htmlunit.html.HtmlPage;
29  import org.htmlunit.html.HtmlSelect;
30  import org.junit.jupiter.api.Test;
31  
32  /**
33   * Tests for {@link HTMLSelectElement}.
34   *
35   * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
36   * @author David K. Taylor
37   * @author Marc Guillemot
38   * @author Bruce Faulkner
39   * @author Ahmed Ashour
40   * @author Daniel Gredler
41   */
42  public class HTMLSelectElement2Test extends SimpleWebTestCase {
43  
44      /**
45       * Changes made through JS should not trigger an onchange event.
46       * @throws Exception if the test fails
47       */
48      @Test
49      public void noOnchangeFromJS() throws Exception {
50          final String html = DOCTYPE_HTML
51              + "<html><head><title>Test infinite loop on js onchange</title></head>\n"
52              + "<body><form name='myForm'>\n"
53              + "<select name='a' onchange='this.form.b.selectedIndex=0'>\n"
54              + "<option value='1'>one</option>\n"
55              + "<option value='2'>two</option>\n"
56              + "</select>\n"
57              + "<select name='b' onchange='alert(\"b changed\")'>\n"
58              + "<option value='G'>green</option>\n"
59              + "<option value='R' selected>red</option>\n"
60              + "</select>\n"
61              + "</form>\n"
62              + "</body>\n"
63              + "</html>";
64          final List<String> collectedAlerts = new ArrayList<>();
65          final HtmlPage page = loadPage(html, collectedAlerts);
66          final HtmlSelect selectA = page.getFormByName("myForm").getSelectByName("a");
67          final HtmlOption optionA2 = selectA.getOption(1);
68  
69          assertEquals("two", optionA2.asNormalizedText());
70  
71          final HtmlSelect selectB = page.getFormByName("myForm").getSelectByName("b");
72          assertEquals(1, selectB.getSelectedOptions().size());
73          assertEquals("red", selectB.getSelectedOptions().get(0).asNormalizedText());
74  
75           // changed selection in first select
76          optionA2.setSelected(true);
77          assertTrue(optionA2.isSelected());
78          assertEquals(1, selectB.getSelectedOptions().size());
79          assertEquals("green", selectB.getSelectedOptions().get(0).asNormalizedText());
80  
81          assertEquals(Collections.EMPTY_LIST, collectedAlerts);
82      }
83  
84      /**
85       * Test for bug 1159709.
86       * @throws Exception if the test fails
87       */
88      @Test
89      public void rightPageAfterOnchange() throws Exception {
90          final String html = DOCTYPE_HTML
91              + "<html><body>\n"
92              + "<iframe src='fooIFrame.html'></iframe>\n"
93              + "<form name='form1' action='http://first' method='post'>\n"
94              + "  <select name='select1' onchange='this.form.submit()'>\n"
95              + "    <option value='option1' selected='true' name='option1'>One</option>\n"
96              + "    <option value='option2' name='option2'>Two</option>\n"
97              + "  </select>\n"
98              + "</form>\n"
99              + "</body></html>";
100 
101         final WebClient webClient = getWebClient();
102         final MockWebConnection webConnection = new MockWebConnection();
103 
104         webConnection.setDefaultResponse("<html><body></body></html>");
105         webConnection.setResponse(URL_FIRST, html);
106         webClient.setWebConnection(webConnection);
107 
108         final HtmlPage page = webClient.getPage(URL_FIRST);
109         final HtmlForm form = page.getFormByName("form1");
110         final HtmlSelect select = form.getSelectByName("select1");
111         final Page page2 = select.setSelectedAttribute("option2", true);
112         assertEquals("http://first/", page2.getUrl());
113     }
114 
115     /**
116      * Tests that select delegates submit to the containing form.
117      * @throws Exception if the test fails
118      */
119     @Test
120     public void onChangeCallsFormSubmit() throws Exception {
121         final String html = DOCTYPE_HTML
122             + "<html><head>\n"
123             + "</head>\n"
124             + "<body>\n"
125             + "<form name='test' action='foo'>\n"
126             + "<select name='select1' onchange='submit()'>\n"
127             + "<option>a</option>\n"
128             + "<option selected='selected'>b</option>\n"
129             + "</select></form>\n"
130             + "</body></html>";
131 
132         final WebClient webClient = getWebClient();
133         final MockWebConnection webConnection = new MockWebConnection();
134 
135         webConnection.setDefaultResponse(DOCTYPE_HTML + "<html><title>page 2</title><body></body></html>");
136         webConnection.setResponse(URL_FIRST, html);
137         webClient.setWebConnection(webConnection);
138 
139         final HtmlPage page = webClient.getPage(URL_FIRST);
140         final HtmlPage page2 = page.getFormByName("test").getSelectByName("select1").getOption(0).click();
141         assertEquals("page 2", page2.getTitleText());
142     }
143 
144     /**
145      * Test for bug 1684652.
146      * @throws Exception if the test fails
147      */
148     @Test
149     public void selectedIndexReset() throws Exception {
150         final String html = DOCTYPE_HTML
151             + "<html><head><title>first</title></head>\n"
152             + "<body onload='document.forms[0].testSelect.selectedIndex = -1; "
153             + "  document.forms[0].testSelect.options[0].selected = true;'>\n"
154             + "<form>\n"
155             + "<select name='testSelect'>\n"
156             + "<option value='testValue'>value</option>\n"
157             + "</select>\n"
158             + "<input id='testButton' type='submit'>\n"
159             + "</form>\n"
160             + "</body></html>";
161 
162         final HtmlPage page = loadPage(html);
163         final Page page2 = page.getHtmlElementById("testButton").click();
164         final URL url2 = page2.getUrl();
165         assertTrue("Select in URL " + url2, url2.toExternalForm().contains("testSelect=testValue"));
166     }
167 
168 }