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