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 java.util.ArrayList;
18  import java.util.List;
19  
20  import org.htmlunit.MockWebConnection;
21  import org.htmlunit.SimpleWebTestCase;
22  import org.htmlunit.WebClient;
23  import org.htmlunit.junit.annotation.Alerts;
24  import org.junit.jupiter.api.Test;
25  
26  /**
27   * Tests for {@link HtmlRadioButtonInput}.
28   *
29   * @author Mike Bresnahan
30   * @author Marc Guillemot
31   * @author Bruce Faulkner
32   * @author Ahmed Ashour
33   */
34  public class HtmlRadioButtonInputTest extends SimpleWebTestCase {
35  
36      /**
37       * Verifies that asNormalizedText() returns "checked" or "unchecked" according to the state of the radio.
38       * @throws Exception if the test fails
39       */
40      @Test
41      public void asTextWhenNotChecked() throws Exception {
42          final String html = DOCTYPE_HTML
43              + "<html><head></head><body>\n"
44              + "<form id='form1'>\n"
45              + "  <input type='radio' name='radio' id='radio'>Check me</input>\n"
46              + "</form></body></html>";
47  
48          final HtmlPage page = loadPage(html);
49  
50          final HtmlRadioButtonInput radio = page.getHtmlElementById("radio");
51          assertEquals("unchecked", radio.asNormalizedText());
52          assertEquals("uncheckedCheck me", page.asNormalizedText());
53          radio.setChecked(true);
54          assertEquals("checked", radio.asNormalizedText());
55      }
56  
57      /**
58       * @throws Exception if the test fails
59       */
60      @Test
61      @Alerts("newtrue")
62      public void onchangeHandlerInvoked() throws Exception {
63          final String html = DOCTYPE_HTML
64              + "<html><head><title>foo</title></head><body>\n"
65              + "<form id='form1'>\n"
66              + "  <input type='radio' name='radio' id='radio'"
67              + "onchange='this.value=\"new\" + this.checked'>Check me</input>\n"
68              + "</form></body></html>";
69  
70          final HtmlPage page = loadPage(html);
71          final HtmlRadioButtonInput radio = page.getHtmlElementById("radio");
72  
73          assertFalse(radio.isChecked());
74  
75          radio.setChecked(true);
76  
77          assertTrue(radio.isChecked());
78          assertEquals(getExpectedAlerts()[0], radio.getValueAttribute());
79          assertEquals(getExpectedAlerts()[0], radio.getValue());
80      }
81  
82      /**
83       * @throws Exception if the test fails
84       */
85      @Test
86      public void onchangeHandlerNotInvokedIfNotChanged() throws Exception {
87          final String html = DOCTYPE_HTML
88              + "<html><head><title>foo</title></head><body>\n"
89              + "<form id='form1'>\n"
90              + "  <input type='radio' name='radio' id='radio'"
91              + "onchange='this.value=\"new\" + this.checked'>Check me</input>\n"
92              + "</form></body></html>";
93  
94          final HtmlPage page = loadPage(html);
95          final HtmlRadioButtonInput radio = page.getHtmlElementById("radio");
96  
97          assertFalse(radio.isChecked());
98  
99          radio.setChecked(false);
100 
101         assertFalse(radio.isChecked());
102 
103         assertEquals("", radio.getValueAttribute());
104         assertEquals("on", radio.getValue());
105     }
106 
107     /**
108      * @throws Exception if the test fails
109      */
110     @Test
111     @Alerts({"oneItem.checked: false twoItems.checked: true", "oneItem.checked: true twoItems.checked: false"})
112     public void updateStateFirstForOnclickHandler() throws Exception {
113         final String html = DOCTYPE_HTML
114             + "<html><head><title>foo</title></head><body>\n"
115             + "<script type='text/javascript'>\n"
116             + "  function itemOnClickHandler() {\n"
117             + "    var oneItem = document.getElementById('oneItem');\n"
118             + "    var twoItems = document.getElementById('twoItems');\n"
119             + "    alert('oneItem.checked: ' + oneItem.checked + ' twoItems.checked: ' + twoItems.checked);\n"
120             + "  }\n"
121             + "</script>\n"
122             + "<form name='testForm'>\n"
123             + "Number of items:"
124             + "<input type='radio' name='numOfItems' value='1' checked='checked' "
125             + "  onclick='itemOnClickHandler()' id='oneItem'>\n"
126             + "<label for='oneItem'>1</label>\n"
127             + "<input type='radio' name='numOfItems' value='2' onclick='itemOnClickHandler()' id='twoItems'>\n"
128             + "<label for='twoItems'>2</label>\n"
129             + "</form></body></html>";
130 
131         final List<String> collectedAlerts = new ArrayList<>();
132         final HtmlPage page = loadPage(html, collectedAlerts);
133 
134         final HtmlRadioButtonInput oneItem = page.getHtmlElementById("oneItem");
135         final HtmlRadioButtonInput twoItems = page.getHtmlElementById("twoItems");
136 
137         assertTrue(oneItem.isChecked());
138         assertFalse(twoItems.isChecked());
139 
140         twoItems.click();
141 
142         assertTrue(twoItems.isChecked());
143         assertFalse(oneItem.isChecked());
144 
145         oneItem.click();
146 
147         assertTrue(oneItem.isChecked());
148         assertFalse(twoItems.isChecked());
149 
150         assertEquals(getExpectedAlerts(), collectedAlerts);
151     }
152 
153     /**
154      * @throws Exception if the test fails
155      */
156     @Test
157     @Alerts("Second")
158     public void setChecked() throws Exception {
159         final String firstHtml = DOCTYPE_HTML
160             + "<html><head><title>First</title></head><body>\n"
161             + "<form>\n"
162             + "<input id='myRadio' type='radio' onchange=\"window.location.href='" + URL_SECOND + "'\">\n"
163             + "</form>\n"
164             + "</body></html>";
165         final String secondHtml = DOCTYPE_HTML
166             + "<html><head><title>Second</title></head><body></body></html>";
167 
168         final WebClient client = getWebClient();
169 
170         final MockWebConnection webConnection = new MockWebConnection();
171         webConnection.setResponse(URL_FIRST, firstHtml);
172         webConnection.setResponse(URL_SECOND, secondHtml);
173         client.setWebConnection(webConnection);
174 
175         final HtmlPage page = client.getPage(URL_FIRST);
176         final HtmlRadioButtonInput radio = page.getHtmlElementById("myRadio");
177 
178         final HtmlPage secondPage = (HtmlPage) radio.setChecked(true);
179         assertEquals(getExpectedAlerts()[0], secondPage.getTitleText());
180     }
181 
182     /**
183      * Regression test for bug #851.
184      * Clicking an element should force the enclosing window to become the current one.
185      * @throws Exception if the test fails
186      */
187     @Test
188     public void clickResponse() throws Exception {
189         final String html = DOCTYPE_HTML
190             + "<html><head>\n"
191             + "</head>\n"
192             + "<body>\n"
193             + "<form name='myForm'>\n"
194             + "  <input type='radio' name='myRadio' id='radio1' value=v1>\n"
195             + "  <input type='radio' name='myRadio' value=v2>\n"
196             + "  <button onclick='openPopup();' type='button' id='clickMe'>click me</button>\n"
197             + "</form>\n"
198             + "<script>\n"
199             + "function doSomething() {\n"
200             + "  // nothing\n"
201             + "}\n"
202             + "function openPopup() {\n"
203             + "  window.open('popup.html');\n"
204             + "}\n"
205             + "</script>\n"
206             + "</body></html>";
207 
208         final HtmlPage page = loadPage(html);
209         final WebClient webClient = page.getWebClient();
210         assertSame(page.getEnclosingWindow(), webClient.getCurrentWindow());
211 
212         // open popup
213         final HtmlPage page2 = page.getHtmlElementById("clickMe").click();
214         assertNotSame(page, page2);
215         assertSame(page2.getEnclosingWindow(), webClient.getCurrentWindow());
216 
217         // click radio buttons in the original page
218         final HtmlPage page3 = page.getHtmlElementById("radio1").click();
219         assertSame(page, page3);
220         assertSame(page3.getEnclosingWindow(), webClient.getCurrentWindow());
221     }
222 }