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