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 org.junit.Assert.fail;
18  
19  import java.net.URL;
20  import java.util.ArrayList;
21  import java.util.Arrays;
22  import java.util.Collections;
23  import java.util.List;
24  
25  import org.htmlunit.CollectingAlertHandler;
26  import org.htmlunit.ElementNotFoundException;
27  import org.htmlunit.HttpMethod;
28  import org.htmlunit.MockWebConnection;
29  import org.htmlunit.Page;
30  import org.htmlunit.SimpleWebTestCase;
31  import org.htmlunit.WebClient;
32  import org.htmlunit.WebRequest;
33  import org.htmlunit.WebWindow;
34  import org.htmlunit.junit.BrowserRunner;
35  import org.htmlunit.junit.annotation.Alerts;
36  import org.htmlunit.util.MimeType;
37  import org.htmlunit.util.NameValuePair;
38  import org.junit.Test;
39  import org.junit.runner.RunWith;
40  
41  /**
42   * Tests for {@link HtmlForm}.
43   *
44   * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
45   * @author <a href="mailto:chen_jun@users.sourceforge.net">Jun Chen</a>
46   * @author George Murnock
47   * @author Marc Guillemot
48   * @author Ahmed Ashour
49   * @author Philip Graf
50   * @author Ronald Brill
51   */
52  @RunWith(BrowserRunner.class)
53  public class HtmlFormTest extends SimpleWebTestCase {
54  
55      /**
56       * Tests the good case for setCheckedRatdioButton().
57       * @exception Exception If the test fails
58       */
59      @Test
60      public void setSelectedRadioButton_ValueExists() throws Exception {
61          final String html = DOCTYPE_HTML
62              + "<html><head><title>foo</title></head><body>\n"
63              + "<form id='form1'>\n"
64              + "<input type='radio' name='foo' value='1' selected='selected' id='input1'/>\n"
65              + "<input type='radio' name='foo' value='2' id='input2'/>\n"
66              + "<input type='radio' name='foo' value='3'/>\n"
67              + "<input type='submit' name='button' value='foo'/>\n"
68              + "</form></body></html>";
69          final HtmlPage page = loadPage(html);
70          final MockWebConnection webConnection = getMockConnection(page);
71  
72          final HtmlForm form = page.getHtmlElementById("form1");
73  
74          final HtmlSubmitInput pushButton = form.getInputByName("button");
75  
76          form.<HtmlRadioButtonInput>getFirstByXPath(
77                  "//input[@type='radio' and @name='foo' and @value='2']").setChecked(true);
78  
79          assertFalse(page.<HtmlRadioButtonInput>getHtmlElementById("input1").isChecked());
80          assertTrue(page.<HtmlRadioButtonInput>getHtmlElementById("input2").isChecked());
81  
82          // Test that only one value for the radio button is being passed back to the server
83          final HtmlPage secondPage = (HtmlPage) pushButton.click();
84  
85          assertEquals("url", URL_FIRST + "?foo=2&button=foo", secondPage.getUrl());
86          assertSame("method", HttpMethod.GET, webConnection.getLastMethod());
87      }
88  
89      /**
90       * Tests setCheckedRadioButton() with a value that doesn't exist.
91       * @exception Exception If the test fails
92       */
93      @Test
94      public void setSelectedRadioButton_ValueDoesNotExist_DoNotForceSelection() throws Exception {
95          final String html = DOCTYPE_HTML
96              + "<html><head><title>foo</title></head><body>\n"
97              + "<form id='form1'>\n"
98              + "<input type='radio' name='foo' value='1' selected='selected'/>\n"
99              + "<input type='radio' name='foo' value='2'/>\n"
100             + "<input type='radio' name='foo' value='3'/>\n"
101             + "<input type='submit' name='button' value='foo'/>\n"
102             + "</form></body></html>";
103         final HtmlPage page = loadPage(html);
104 
105         final HtmlForm form = page.getHtmlElementById("form1");
106 
107         final HtmlInput pushButton = form.getInputByName("button");
108         assertNotNull(pushButton);
109 
110         assertNull(form.getFirstByXPath("//input[@type='radio' and @name='foo' and @value='4']"));
111     }
112 
113     /**
114      * @throws Exception if the test fails
115      */
116     @Test
117     public void submit_String() throws Exception {
118         final String html = DOCTYPE_HTML
119             + "<html><head><title>foo</title></head><body>\n"
120             + "<form id='form1'>\n"
121             + "<input id='submitButton' type='submit' name='button' value='foo'/>\n"
122             + "</form></body></html>";
123         final HtmlPage page = loadPage(html);
124 
125         final HtmlForm form = page.getHtmlElementById("form1");
126 
127         // Regression test: this used to blow up
128         form.submit((HtmlSubmitInput) page.getHtmlElementById("submitButton"));
129     }
130 
131     /**
132      * @throws Exception if the test fails
133      */
134     @Test
135     public void submit_ExtraParameters() throws Exception {
136         final String html = DOCTYPE_HTML
137             + "<html><head><title>foo</title></head><body>\n"
138             + "<form id='form1' method='post'>\n"
139             + "  <input type='text' name='textfield' value='*'/>\n"
140             + "  <input type='submit' name='button' value='foo'/>\n"
141             + "</form></body></html>";
142         final HtmlPage page = loadPage(html);
143         final MockWebConnection webConnection = getMockConnection(page);
144 
145         final HtmlForm form = page.getHtmlElementById("form1");
146 
147         final HtmlSubmitInput button = form.getInputByName("button");
148         button.click();
149 
150         final List<NameValuePair> expectedParameters = Arrays.asList(new NameValuePair[]{
151             new NameValuePair("textfield", "*"), new NameValuePair("button", "foo")
152         });
153         final List<NameValuePair> collectedParameters = webConnection.getLastParameters();
154 
155         assertEquals(expectedParameters, collectedParameters);
156     }
157 
158     /**
159      * @throws Exception if the test fails
160      */
161     @Test
162     public void submit_BadSubmitMethod() throws Exception {
163         final String html = DOCTYPE_HTML
164             + "<html><head><title>foo</title></head><body>\n"
165             + "<form id='form1' method='put'>\n"
166             + "  <input type='text' name='textfield' value='*'/>\n"
167             + "  <input type='submit' name='button' id='button' value='foo'/>\n"
168             + "</form></body></html>";
169         final HtmlPage page = loadPage(html);
170         final MockWebConnection webConnection = getMockConnection(page);
171         page.getHtmlElementById("button").click();
172         assertSame(HttpMethod.GET, webConnection.getLastMethod());
173     }
174 
175     /**
176      * @throws Exception if the test fails
177      */
178     @Test
179     public void submit_onSubmitHandler() throws Exception {
180         final String firstHtml = DOCTYPE_HTML
181             + "<html><head><title>First</title></head><body>\n"
182             + "<form method='get' action='" + URL_SECOND + "' onSubmit='alert(\"clicked\")'>\n"
183             + "<input name='button' type='submit' value='PushMe' id='button'/></form>\n"
184             + "</body></html>";
185         final String secondHtml = DOCTYPE_HTML + "<html><head><title>Second</title></head><body></body></html>";
186 
187         final WebClient client = getWebClientWithMockWebConnection();
188         final List<String> collectedAlerts = new ArrayList<>();
189         client.setAlertHandler(new CollectingAlertHandler(collectedAlerts));
190 
191         final MockWebConnection webConnection = getMockWebConnection();
192         webConnection.setResponse(URL_FIRST, firstHtml);
193         webConnection.setDefaultResponse(secondHtml);
194 
195         final HtmlPage firstPage = client.getPage(URL_FIRST);
196         final HtmlSubmitInput button = firstPage.getHtmlElementById("button");
197 
198         assertEquals(Collections.EMPTY_LIST, collectedAlerts);
199         final HtmlPage secondPage = button.click();
200         assertEquals("Second", secondPage.getTitleText());
201 
202         assertEquals(new String[] {"clicked"}, collectedAlerts);
203     }
204 
205     /**
206      * @throws Exception if the test fails
207      */
208     @Test
209     public void submit_onSubmitHandler_returnFalse() throws Exception {
210         final String firstHtml = DOCTYPE_HTML
211             + "<html><head><title>First</title></head><body>\n"
212             + "<form method='get' action='" + URL_SECOND + "' "
213             + "onSubmit='alert(\"clicked\");return false;'>\n"
214             + "<input name='button' type='submit' value='PushMe' id='button'/></form>\n"
215             + "</body></html>";
216         final String secondHtml = DOCTYPE_HTML + "<html><head><title>Second</title></head><body></body></html>";
217 
218         final WebClient client = getWebClientWithMockWebConnection();
219         final List<String> collectedAlerts = new ArrayList<>();
220         client.setAlertHandler(new CollectingAlertHandler(collectedAlerts));
221 
222         final MockWebConnection webConnection = getMockWebConnection();
223         webConnection.setResponse(URL_FIRST, firstHtml);
224         webConnection.setResponse(URL_SECOND, secondHtml);
225 
226         final HtmlPage firstPage = client.getPage(URL_FIRST);
227         final HtmlSubmitInput button = firstPage.getHtmlElementById("button");
228 
229         assertEquals(Collections.EMPTY_LIST, collectedAlerts);
230         final HtmlPage secondPage = button.click();
231         assertEquals(firstPage.getTitleText(), secondPage.getTitleText());
232 
233         assertEquals(new String[] {"clicked"}, collectedAlerts);
234     }
235 
236     /**
237      * Testcase for 3072010.
238      *
239      * @throws Exception if the test fails
240      */
241     @Test
242     @Alerts("clicked")
243     public void submit_onSubmitHandler_preventDefaultOnly() throws Exception {
244         final String firstHtml = DOCTYPE_HTML
245             + "<html><body>\n"
246             + "<form method='post' action='/foo' >\n"
247             + "<input type='submit' id='button'/>\n"
248             + "</form>\n"
249             + "<script>\n"
250             + "function foo(e) {\n"
251             + "  alert('clicked');\n"
252             + "  e.returnValue = false;\n"
253             + "  if (e.preventDefault) {\n"
254             + "    e.preventDefault();\n"
255             + "  }\n"
256             + "}\n"
257             + "var oForm = document.forms[0];\n"
258             + "oForm.addEventListener('submit', foo, false);\n"
259             + "</script>\n"
260             + "</body></html>";
261 
262         final WebClient client = getWebClientWithMockWebConnection();
263         final List<String> collectedAlerts = new ArrayList<>();
264         client.setAlertHandler(new CollectingAlertHandler(collectedAlerts));
265 
266         getMockWebConnection().setResponse(URL_FIRST, firstHtml);
267         getMockWebConnection().setDefaultResponse("");
268 
269         final HtmlPage firstPage = client.getPage(URL_FIRST);
270         final HtmlSubmitInput button = firstPage.getHtmlElementById("button");
271 
272         assertEquals(Collections.EMPTY_LIST, collectedAlerts);
273         final HtmlPage secondPage = button.click();
274         assertSame(firstPage, secondPage);
275 
276         assertEquals(getExpectedAlerts(), collectedAlerts);
277     }
278 
279     /**
280      * Regression test for NullPointerException when submitting forms.
281      * @throws Exception if the test fails
282      */
283     @Test
284     public void submit_onSubmitHandler_fails() throws Exception {
285         final String firstHtml = DOCTYPE_HTML
286             + "<html><head><title>First</title></head><body>\n"
287             + "<form method='get' action='" + URL_SECOND + "' onSubmit='return null'>\n"
288             + "<input name='button' type='submit' value='PushMe' id='button'/></form>\n"
289             + "</body></html>";
290         final String secondHtml = DOCTYPE_HTML + "<html><head><title>Second</title></head><body></body></html>";
291 
292         final WebClient client = getWebClientWithMockWebConnection();
293         final MockWebConnection webConnection = getMockWebConnection();
294         webConnection.setResponse(URL_FIRST, firstHtml);
295         webConnection.setDefaultResponse(secondHtml);
296 
297         final HtmlPage firstPage = client.getPage(URL_FIRST);
298         final HtmlSubmitInput button = firstPage.getHtmlElementById("button");
299         final HtmlPage secondPage = button.click();
300         assertEquals("Second", secondPage.getTitleText());
301     }
302 
303     /**
304      * @throws Exception if the test fails
305      */
306     @Test
307     public void submit_onSubmitHandler_javascriptDisabled() throws Exception {
308         final String firstHtml = DOCTYPE_HTML
309             + "<html><head><title>First</title></head><body>\n"
310             + "<form method='get' action='" + URL_SECOND + "' onSubmit='alert(\"clicked\")'>\n"
311             + "<input name='button' type='submit' value='PushMe' id='button'/></form>\n"
312             + "</body></html>";
313         final String secondHtml = DOCTYPE_HTML + "<html><head><title>Second</title></head><body></body></html>";
314 
315         final WebClient client = getWebClientWithMockWebConnection();
316         client.getOptions().setJavaScriptEnabled(false);
317 
318         final List<String> collectedAlerts = new ArrayList<>();
319         client.setAlertHandler(new CollectingAlertHandler(collectedAlerts));
320 
321         final MockWebConnection webConnection = getMockWebConnection();
322         webConnection.setResponse(URL_FIRST, firstHtml);
323         webConnection.setDefaultResponse(secondHtml);
324 
325         final HtmlPage firstPage = client.getPage(URL_FIRST);
326         final HtmlSubmitInput button = firstPage.getHtmlElementById("button");
327 
328         assertEquals(Collections.EMPTY_LIST, collectedAlerts);
329         final HtmlPage secondPage = button.click();
330         assertEquals("First", firstPage.getTitleText());
331         assertEquals("Second", secondPage.getTitleText());
332 
333         assertEquals(Collections.EMPTY_LIST, collectedAlerts);
334     }
335 
336     /**
337      * @throws Exception if the test fails
338      */
339     @Test
340     public void submit_javascriptAction() throws Exception {
341         final String firstHtml = DOCTYPE_HTML
342             + "<html><head><title>First</title></head><body>\n"
343             + "<form method='get' action='javascript:alert(\"clicked\")'>\n"
344             + "<input name='button' type='submit' value='PushMe' id='button'/></form>\n"
345             + "</body></html>";
346         final String secondHtml = DOCTYPE_HTML + "<html><head><title>Second</title></head><body></body></html>";
347 
348         final WebClient client = getWebClientWithMockWebConnection();
349         final List<String> collectedAlerts = new ArrayList<>();
350         client.setAlertHandler(new CollectingAlertHandler(collectedAlerts));
351 
352         final MockWebConnection webConnection = getMockWebConnection();
353         webConnection.setResponse(URL_FIRST, firstHtml);
354         webConnection.setResponse(URL_SECOND, secondHtml);
355 
356         final HtmlPage firstPage = client.getPage(URL_FIRST);
357         final HtmlSubmitInput button = firstPage.getHtmlElementById("button");
358 
359         assertEquals(Collections.EMPTY_LIST, collectedAlerts);
360         final HtmlPage secondPage = button.click();
361         assertEquals(firstPage.getTitleText(), secondPage.getTitleText());
362 
363         assertEquals(new String[] {"clicked"}, collectedAlerts);
364     }
365 
366     /**
367      * @throws Exception if the test fails
368      */
369     @Test
370     public void submit_javascriptActionMixedCase() throws Exception {
371         final String firstHtml = DOCTYPE_HTML
372             + "<html><head><title>First</title></head><body>\n"
373             + "<form method='get' action='jaVAscrIpt:alert(\"clicked\")'>\n"
374             + "<input name='button' type='submit' value='PushMe' id='button'/></form>\n"
375             + "</body></html>";
376         final String secondHtml = DOCTYPE_HTML + "<html><head><title>Second</title></head><body></body></html>";
377 
378         final WebClient client = getWebClientWithMockWebConnection();
379         final List<String> collectedAlerts = new ArrayList<>();
380         client.setAlertHandler(new CollectingAlertHandler(collectedAlerts));
381 
382         final MockWebConnection webConnection = getMockWebConnection();
383         webConnection.setResponse(URL_FIRST, firstHtml);
384         webConnection.setResponse(URL_SECOND, secondHtml);
385 
386         final HtmlPage firstPage = client.getPage(URL_FIRST);
387         final HtmlSubmitInput button = firstPage.getHtmlElementById("button");
388 
389         assertEquals(Collections.EMPTY_LIST, collectedAlerts);
390         final HtmlPage secondPage = button.click();
391         assertEquals(firstPage.getTitleText(), secondPage.getTitleText());
392 
393         assertEquals(new String[] {"clicked"}, collectedAlerts);
394     }
395 
396     /**
397      * @throws Exception if the test fails
398      */
399     @Test
400     public void submit_javascriptActionLeadingWhitespace() throws Exception {
401         final String firstHtml = DOCTYPE_HTML
402             + "<html><head><title>First</title></head><body>\n"
403             + "<form method='get' action=' javascript:alert(\"clicked\")'>\n"
404             + "<input name='button' type='submit' value='PushMe' id='button'/></form>\n"
405             + "</body></html>";
406         final String secondHtml = DOCTYPE_HTML + "<html><head><title>Second</title></head><body></body></html>";
407 
408         final WebClient client = getWebClientWithMockWebConnection();
409         final List<String> collectedAlerts = new ArrayList<>();
410         client.setAlertHandler(new CollectingAlertHandler(collectedAlerts));
411 
412         final MockWebConnection webConnection = getMockWebConnection();
413         webConnection.setResponse(URL_FIRST, firstHtml);
414         webConnection.setResponse(URL_SECOND, secondHtml);
415 
416         final HtmlPage firstPage = client.getPage(URL_FIRST);
417         final HtmlSubmitInput button = firstPage.getHtmlElementById("button");
418 
419         assertEquals(Collections.EMPTY_LIST, collectedAlerts);
420         final HtmlPage secondPage = button.click();
421         assertEquals(firstPage.getTitleText(), secondPage.getTitleText());
422 
423         assertEquals(new String[] {"clicked"}, collectedAlerts);
424     }
425 
426     /**
427      * @throws Exception if the test fails
428      */
429     @Test
430     public void submit_javascriptAction_javascriptDisabled() throws Exception {
431         final String html = DOCTYPE_HTML
432             + "<html><head><title>First</title></head><body>\n"
433             + "<form method='get' action='javascript:alert(\"clicked\")'>\n"
434             + "<input name='button' type='submit' value='PushMe' id='button'/></form>\n"
435             + "</body></html>";
436 
437         final WebClient client = getWebClientWithMockWebConnection();
438         client.getOptions().setJavaScriptEnabled(false);
439 
440         final List<String> collectedAlerts = new ArrayList<>();
441         client.setAlertHandler(new CollectingAlertHandler(collectedAlerts));
442 
443         final MockWebConnection webConnection = getMockWebConnection();
444         webConnection.setResponse(URL_FIRST, html);
445 
446         final HtmlPage firstPage = client.getPage(URL_FIRST);
447         final HtmlSubmitInput button = firstPage.getHtmlElementById("button");
448 
449         assertEquals(Collections.EMPTY_LIST, collectedAlerts);
450         final HtmlPage secondPage = button.click();
451         assertSame(firstPage, secondPage);
452     }
453 
454     /**
455      * Regression test for a bug that caused a NullPointer exception to be thrown during submit.
456      * @throws Exception if the test fails
457      */
458     @Test
459     public void submitRadioButton() throws Exception {
460         final String html = DOCTYPE_HTML
461             + "<html><body><form method='POST' action='" + URL_FIRST + "'>\n"
462             + "<table><tr> <td ><input type='radio' name='name1' value='foo'> "
463             + "Option 1</td> </tr>\n"
464             + "<tr> <td ><input type='radio' name='name1' value='bar' checked >\n"
465             + "Option 2</td> </tr>\n"
466             + "<tr> <td ><input type='radio' name='name1' value='baz'> Option 3</td> </tr>\n"
467             + "</table><input type='submit' value='Login' name='loginButton1'></form>\n"
468             + "</body></html>";
469 
470         final HtmlPage page = loadPage(html);
471         final HtmlSubmitInput loginButton
472             = page.getDocumentElement().getOneHtmlElementByAttribute("input", "value", "Login");
473         loginButton.click();
474     }
475 
476     /**
477      * @throws Exception if the test fails
478      */
479     @Test
480     public void reset_onResetHandler() throws Exception {
481         final String html = DOCTYPE_HTML
482             + "<html><head><title>First</title></head><body>\n"
483             + "<form method='get' action='" + URL_SECOND + "' "
484             + "onReset='alert(\"clicked\");alert(event.type)'>\n"
485             + "<input name='button' type='reset' value='PushMe' id='button'/></form>\n"
486             + "</body></html>";
487 
488         final List<String> collectedAlerts = new ArrayList<>();
489 
490         final HtmlPage firstPage = loadPage(html, collectedAlerts);
491         final HtmlResetInput button = (HtmlResetInput) firstPage.getHtmlElementById("button");
492 
493         assertEquals(Collections.EMPTY_LIST, collectedAlerts);
494         final HtmlPage secondPage = button.click();
495         assertSame(firstPage, secondPage);
496 
497         final String[] expectedAlerts = {"clicked", "reset"};
498         assertEquals(expectedAlerts, collectedAlerts);
499     }
500 
501     /**
502      * <p>Simulate a bug report where an anchor contained JavaScript that caused a form submit.
503      * According to the bug report, the form would be submitted even though the onsubmit
504      * handler would return false. This wasn't reproducible but I added a test for it anyway.</p>
505      *
506      * <p>UPDATE: If the form submit is triggered by JavaScript then the onsubmit handler is not
507      * supposed to be called so it doesn't matter what value it returns.</p>
508      * @throws Exception if the test fails
509      */
510     @Test
511     public void submit_AnchorCausesSubmit_onSubmitHandler_returnFalse() throws Exception {
512         final String firstHtml = DOCTYPE_HTML
513             + "<html><head><title>First</title></head>\n"
514             + "<script>function doalert(message){alert(message);}</script>\n"
515             + "<body><form name='form1' method='get' action='" + URL_SECOND + "' "
516             + "onSubmit='doalert(\"clicked\");return false;'>\n"
517             + "<input name='button' type='submit' value='PushMe' id='button'/></form>\n"
518             + "<a id='link1' href='javascript:document.form1.submit()'>Click me</a>\n"
519             + "</body></html>";
520         final String secondHtml = DOCTYPE_HTML + "<html><head><title>Second</title></head><body></body></html>";
521 
522         final WebClient client = getWebClientWithMockWebConnection();
523         final List<String> collectedAlerts = new ArrayList<>();
524         client.setAlertHandler(new CollectingAlertHandler(collectedAlerts));
525 
526         final MockWebConnection webConnection = getMockWebConnection();
527         webConnection.setResponse(URL_FIRST, firstHtml);
528         webConnection.setDefaultResponse(secondHtml);
529 
530         final HtmlPage firstPage = client.getPage(URL_FIRST);
531         final HtmlAnchor anchor = firstPage.getHtmlElementById("link1");
532 
533         assertEquals(Collections.EMPTY_LIST, collectedAlerts);
534         final HtmlPage secondPage = anchor.click();
535         assertEquals("Second", secondPage.getTitleText());
536 
537         assertEquals(Collections.EMPTY_LIST, collectedAlerts);
538     }
539 
540     /**
541      * @throws Exception if the test fails
542      */
543     @Test
544     public void submit_CheckboxClicked() throws Exception {
545         final String html = DOCTYPE_HTML
546             + "<html><head><title>foo</title>\n"
547             + "<script language='javascript'>\n"
548             + "function setFormat() {\n"
549             + "  if (document.form1.Format.checked) {\n"
550             + "    document.form1.Format.value = 'html';\n"
551             + "  } else {\n"
552             + "    document.form1.Format.value = 'plain';\n"
553             + "  }\n"
554             + "}\n"
555             + "</script>\n"
556             + "</head><body>\n"
557             + "<form name='form1' id='form1' method='post'>\n"
558             + "  <input type=checkbox name=Format value='' onclick='setFormat()'>\n"
559             + "  <input type='submit' name='button' value='foo'/>\n"
560             + "</form></body></html>";
561 
562         final HtmlPage page1 = loadPage(html);
563         final MockWebConnection webConnection1 = getMockConnection(page1);
564         final HtmlForm form1 = page1.getHtmlElementById("form1");
565         final HtmlSubmitInput button1 = form1.getInputByName("button");
566 
567         final HtmlPage page2 = button1.click();
568         final List<NameValuePair> collectedParameters1 = webConnection1.getLastParameters();
569         final List<NameValuePair> expectedParameters1 =
570             Arrays.asList(new NameValuePair[] {new NameValuePair("button", "foo")});
571 
572         final MockWebConnection webConnection2 = getMockConnection(page2);
573         final HtmlForm form2 = page2.getHtmlElementById("form1");
574         final HtmlCheckBoxInput checkBox2 = form2.getInputByName("Format");
575         final HtmlSubmitInput button2 = form2.getInputByName("button");
576 
577         checkBox2.click();
578         button2.click();
579         final List<NameValuePair> collectedParameters2 = webConnection2.getLastParameters();
580         final List<NameValuePair> expectedParameters2 = Arrays.asList(new NameValuePair[] {
581             new NameValuePair("Format", "html"),
582             new NameValuePair("button", "foo")
583         });
584 
585         assertEquals(expectedParameters1, collectedParameters1);
586         assertEquals(expectedParameters2, collectedParameters2);
587     }
588 
589     /**
590      * @throws Exception if the test fails
591      */
592     @Test
593     public void getInputByValue() throws Exception {
594         final String html = DOCTYPE_HTML
595             + "<html><head><title>foo</title></head><body>\n"
596             + "<form id='form1'>\n"
597             + "  <input type='submit' name='button' value='xxx'/>\n"
598             + "  <input type='text' name='textfield' value='foo'/>\n"
599             + "  <input type='submit' name='button1' value='foo'/>\n"
600             + "  <input type='reset' name='button2' value='foo'/>\n"
601             + "  <input type='submit' name='button' value='bar'/>\n"
602             + "</form></body></html>";
603         final HtmlPage page = loadPage(html);
604 
605         final HtmlForm form = page.getHtmlElementById("form1");
606 
607         final List<String> actualInputs = new ArrayList<>();
608         for (final HtmlInput input : form.getInputsByValue("foo")) {
609             actualInputs.add(input.getNameAttribute());
610         }
611 
612         final String[] expectedInputs = {"textfield", "button1", "button2"};
613         assertEquals("Get all", expectedInputs, actualInputs);
614         assertEquals(Collections.EMPTY_LIST, form.getInputsByValue("none-matching"));
615 
616         assertEquals("Get first", "button", form.getInputByValue("bar").getNameAttribute());
617         try {
618             form.getInputByValue("none-matching");
619             fail("Expected ElementNotFoundException");
620         }
621         catch (final ElementNotFoundException e) {
622             // Expected path.
623         }
624     }
625 
626 
627     /**
628      * @throws Exception if the test fails
629      */
630     @Test
631     public void getInputByValueValueChanged() throws Exception {
632         final String html = DOCTYPE_HTML
633             + "<html><head><title>foo</title></head><body>\n"
634             + "<form id='form1'>\n"
635             + "  <input type='submit' name='button' value='xxx'/>\n"
636             + "  <input type='text' name='textfield' value='foo'/>\n"
637             + "  <input type='submit' name='button1' value='foo'/>\n"
638             + "  <input type='reset' name='button2' value='foo'/>\n"
639             + "  <input type='button' name='button3' value='foo'/>\n"
640             + "  <input type='image' name='img' value='foo'/>\n"
641             + "  <input type='submit' name='button' value='bar'/>\n"
642             + "</form></body></html>";
643         final HtmlPage page = loadPage(html);
644 
645         final HtmlForm form = page.getHtmlElementById("form1");
646 
647         HtmlInput input = form.getInputByValue("xxx");
648         input.setValue("yyy");
649         HtmlElement elem = form.getInputByValue("yyy");
650         assertEquals(input, elem);
651 
652         input = form.getInputByValue("foo");
653         input.setValue("text");
654         elem = form.getInputByValue("text");
655         assertEquals(input, elem);
656 
657         input = form.getInputByValue("foo");
658         input.setValue("suBmit");
659         elem = form.getInputByValue("suBmit");
660         assertEquals(input, elem);
661 
662         input = form.getInputByValue("foo");
663         input.setValue("RESET");
664         elem = form.getInputByValue("RESET");
665         assertEquals(input, elem);
666 
667         input = form.getInputByValue("foo");
668         input.setValue("button");
669         elem = form.getInputByValue("button");
670         assertEquals(input, elem);
671 
672         input = form.getInputByValue("foo");
673         input.setValue("Image");
674         elem = form.getInputByValue("Image");
675         assertEquals(input, elem);
676 
677         input = form.getInputByValue("bar");
678         input.setValue("1234");
679         elem = form.getInputByValue("1234");
680         assertEquals(input, elem);
681     }
682 
683     /**
684      * Test that {@link HtmlForm#getTextAreaByName(String)} returns
685      * the first textarea with the given name.
686      *
687      * @throws Exception if the test page can't be loaded
688      */
689     @Test
690     public void getTextAreaByName() throws Exception {
691         final String html = DOCTYPE_HTML
692             + "<html><head><title>foo</title></head><body>\n"
693             + "<form id='form1'>\n"
694             + "  <textarea id='ta1_1' name='ta1'>hello</textarea>\n"
695             + "  <textarea id='ta1_2' name='ta1'>world</textarea>\n"
696             + "  <textarea id='ta2_1' name='ta2'>!</textarea>\n"
697             + "</form></body></html>";
698         final HtmlPage page = loadPage(html);
699 
700         final HtmlForm form = page.getHtmlElementById("form1");
701 
702         assertEquals("First textarea with name 'ta1'", page.getElementById("ta1_1"),
703             form.getTextAreaByName("ta1"));
704         assertEquals("First textarea with name 'ta2'", page.getElementById("ta2_1"),
705             form.getTextAreaByName("ta2"));
706 
707         try {
708             form.getTextAreaByName("ta3");
709             fail("Expected ElementNotFoundException as there is no textarea with name 'ta3'");
710         }
711         catch (final ElementNotFoundException e) {
712             // pass: exception is expected
713         }
714     }
715 
716     /**
717      * Test that {@link HtmlForm#getButtonByName(String)} returns
718      * the first button with the given name.
719      *
720      * @throws Exception if the test page can't be loaded
721      */
722     @Test
723     public void getButtonByName() throws Exception {
724         final String html = DOCTYPE_HTML
725             + "<html><head><title>foo</title></head><body>\n"
726             + "<form id='form1'>\n"
727             + "  <button id='b1_1' name='b1' value='hello' type='button'/>\n"
728             + "  <button id='b1_2' name='b1' value='world' type='button'/>\n"
729             + "  <button id='b2_1' name='b2' value='!' type='button'/>\n"
730             + "</form></body></html>";
731         final HtmlPage page = loadPage(html);
732 
733         final HtmlForm form = page.getHtmlElementById("form1");
734 
735         assertEquals("First button with name 'b1'", page.getElementById("b1_1"),
736             form.getButtonByName("b1"));
737         assertEquals("First button with name 'b2'", page.getElementById("b2_1"),
738             form.getButtonByName("b2"));
739 
740         try {
741             form.getTextAreaByName("b3");
742             fail("Expected ElementNotFoundException as there is no button with name 'b3'");
743         }
744         catch (final ElementNotFoundException e) {
745             // pass: exception is expected
746         }
747     }
748 
749     /**
750      * Tests that the result of the form will get loaded into the window specified by "target".
751      * @throws Exception if the test fails
752      */
753     @Test
754     public void submitToTargetWindow() throws Exception {
755         final String html = DOCTYPE_HTML
756             + "<html><head><title>first</title></head><body>\n"
757             + "<form id='form1' target='window2' action='" + URL_SECOND + "' method='post'>\n"
758             + "  <input type='submit' name='button' value='push me'/>\n"
759             + "</form></body></html>";
760         final WebClient client = getWebClientWithMockWebConnection();
761 
762         final MockWebConnection webConnection = getMockWebConnection();
763         webConnection.setResponse(URL_FIRST, html);
764         webConnection.setResponseAsGenericHtml(URL_SECOND, "second");
765 
766         final HtmlPage page = client.getPage(URL_FIRST);
767         final WebWindow firstWindow = client.getCurrentWindow();
768         assertEquals("first window name", "", firstWindow.getName());
769         assertSame(page, firstWindow.getEnclosedPage());
770 
771         final HtmlForm form = page.getHtmlElementById("form1");
772 
773         final HtmlSubmitInput button = form.getInputByName("button");
774         final HtmlPage secondPage = button.click();
775         assertEquals("window2", secondPage.getEnclosingWindow().getName());
776         assertSame(secondPage.getEnclosingWindow(), client.getCurrentWindow());
777     }
778 
779     /**
780      * @throws Exception if the test fails
781      */
782     @Test
783     public void submit_SelectHasNoOptions() throws Exception {
784         final String html = DOCTYPE_HTML
785             + "<html><body><form name='form' method='GET' action='action.html'>\n"
786             + "  <select name='select'>\n"
787             + "  </select>\n"
788             + "  <input type='submit' id='clickMe'>\n"
789             + "</form></body></html>";
790         final HtmlPage page = loadPage(html);
791         final MockWebConnection webConnection = getMockConnection(page);
792 
793         final HtmlPage secondPage = page.getHtmlElementById("clickMe").click();
794 
795         assertNotNull(secondPage);
796         assertEquals("parameters", Collections.EMPTY_LIST, webConnection.getLastParameters());
797     }
798 
799     /**
800      * @throws Exception if the test fails
801      */
802     @Test
803     public void submit_SelectOptionWithoutValueAttribute() throws Exception {
804         final String html = DOCTYPE_HTML
805             + "<html><body><form name='form' action='action.html'>\n"
806             + "<select name='select'>\n"
807             + "  <option>first value</option>\n"
808             + "  <option selected>second value</option>\n"
809             + "</select>\n"
810             + "<input type='submit' id='mySubmit'>\n"
811             + "</form></body></html>";
812         final HtmlPage page = loadPage(html);
813         final HtmlPage secondPage = page.getHtmlElementById("mySubmit").click();
814 
815         assertNotNull(secondPage);
816         assertEquals(page.getUrl() + "action.html?select=second+value", secondPage.getUrl());
817     }
818 
819     /**
820      * At one point this test was failing because deeply nested inputs weren't getting picked up.
821      * @throws Exception if the test fails
822      */
823     @Test
824     public void submit_DeepInputs() throws Exception {
825         final String html = DOCTYPE_HTML
826             + "<html><form method='post' action=''>\n"
827             + "<table><tr><td>\n"
828             + "<input value='NOT_SUBMITTED' name='data' type='text'/>\n"
829             + "</td></tr></table>\n"
830             + "<input id='submitButton' name='submit' type='submit'/>\n"
831             + "</form></html>";
832         final HtmlPage page = loadPage(html);
833         final MockWebConnection webConnection = getMockConnection(page);
834 
835         final HtmlInput submitButton = page.getHtmlElementById("submitButton");
836         submitButton.click();
837 
838         final List<NameValuePair> collectedParameters = webConnection.getLastParameters();
839         final List<NameValuePair> expectedParameters = Arrays.asList(new NameValuePair[] {
840             new NameValuePair("data", "NOT_SUBMITTED"),
841             new NameValuePair("submit", "Submit Query")
842         });
843         assertEquals(expectedParameters, collectedParameters);
844     }
845 
846     /**
847      * Test order of submitted parameters matches order of elements in form.
848      * @throws Exception if the test fails
849      */
850     @Test
851     public void submit_FormElementOrder() throws Exception {
852         final String html = DOCTYPE_HTML
853             + "<html><head></head><body><form method='post' action=''>\n"
854             + "<input type='submit' name='dispatch' value='Save' id='submitButton'>\n"
855             + "<input type='hidden' name='dispatch' value='TAB'>\n"
856             + "</form></body></html>";
857         final WebClient client = getWebClientWithMockWebConnection();
858 
859         final MockWebConnection webConnection = getMockWebConnection();
860         webConnection.setDefaultResponse(html);
861 
862         final WebRequest request = new WebRequest(URL_FIRST, HttpMethod.POST);
863 
864         final HtmlPage page = client.getPage(request);
865         final HtmlInput submitButton = page.getHtmlElementById("submitButton");
866         submitButton.click();
867 
868         final List<NameValuePair> collectedParameters = webConnection.getLastParameters();
869         final List<NameValuePair> expectedParameters = Arrays.asList(new NameValuePair[] {
870             new NameValuePair("dispatch", "Save"),
871             new NameValuePair("dispatch", "TAB"),
872         });
873         assertEquals(expectedParameters, collectedParameters);
874     }
875 
876     /**
877      * @throws Exception if the test fails
878      */
879     @Test
880     public void urlAfterSubmit()
881         throws Exception {
882         urlAfterSubmit("get", "foo", "foo?textField=foo&nonAscii=Flo%DFfahrt&button=foo");
883         // for a get submit, query parameters in action are lost in browsers
884         urlAfterSubmit("get", "foo?foo=12", "foo?textField=foo&nonAscii=Flo%DFfahrt&button=foo");
885         urlAfterSubmit("post", "foo", "foo");
886         urlAfterSubmit("post", "foo?foo=12", "foo?foo=12");
887         urlAfterSubmit("post", "", "");
888         urlAfterSubmit("post", "?a=1&b=2", "?a=1&b=2");
889         final URL url = new URL(URL_FIRST + "?a=1&b=2");
890         urlAfterSubmit(url, "post", "", url.toExternalForm());
891     }
892 
893     /**
894      * @throws Exception if the test fails
895      */
896     @Test
897     @Alerts({"foo?textField=foo&nonAscii=Flo%DFfahrt&button=foo#anchor",
898              "foo?textField=foo&nonAscii=Flo%DFfahrt&button=foo#anchor",
899              "foo#anchor",
900              "foo?foo=12#anchor"})
901     public void urlAfterSubmitWithAnchor() throws Exception {
902         urlAfterSubmit("get", "foo#anchor", getExpectedAlerts()[0]);
903         urlAfterSubmit("get", "foo?foo=12#anchor", getExpectedAlerts()[1]);
904         urlAfterSubmit("post", "foo#anchor", getExpectedAlerts()[2]);
905         urlAfterSubmit("post", "foo?foo=12#anchor", getExpectedAlerts()[3]);
906     }
907 
908     /**
909      * Utility for {@link #testUrlAfterSubmit()}
910      * @param method the form method to use
911      * @param action the form action to use
912      * @param expectedUrl the expected URL
913      * @throws Exception if the test fails
914      */
915     private void urlAfterSubmit(final URL url, final String method, final String action,
916             final String expectedUrl) throws Exception {
917         final String html = DOCTYPE_HTML
918             + "<html><head><title>foo</title></head><body>\n"
919             + "<form id='form1' method='" + method + "' action='" + action + "'>\n"
920             + "<input type='text' name='textField' value='foo'/>\n"
921             + "<input type='text' name='nonAscii' value='Flo\u00DFfahrt'/>\n"
922             + "<input id='submitButton' type='submit' name='button' value='foo'/>\n"
923             + "<input type='button' name='inputButton' value='foo'/>\n"
924             + "<button type='button' name='buttonButton' value='foo'/>\n"
925             + "</form></body></html>";
926         final HtmlPage page = loadPage(getBrowserVersion(), html, null, url);
927         final Page page2 = page.getHtmlElementById("submitButton").click();
928 
929         assertEquals(expectedUrl, page2.getUrl());
930     }
931 
932     /**
933      * Utility for {@link #testUrlAfterSubmit()}. Calls {@link #urlAfterSubmit(URL, String, String, String)} with
934      * the default url.
935      * @param method the form method to use
936      * @param action the form action to use
937      * @param expectedUrlEnd the expected URL
938      * @throws Exception if the test fails
939      */
940     private void urlAfterSubmit(final String method, final String action, final String expectedUrlEnd)
941         throws Exception {
942         urlAfterSubmit(URL_FIRST, method, action, URL_FIRST + expectedUrlEnd);
943     }
944 
945     /**
946      * @throws Exception if the test fails
947      */
948     @Test
949     public void submitRequestCharset() throws Exception {
950         pageCharset("utf-8", null, null, "UTF-8");
951         pageCharset(null, "utf-8", null, "UTF-8");
952         pageCharset("iso-8859-1", null, "utf-8", "windows-1252");
953         pageCharset("iso-8859-1", null, "utf-8, iso-8859-1", "windows-1252");
954         pageCharset("utf-8", null, "iso-8859-1 utf-8", "UTF-8");
955         pageCharset("iso-8859-1", null, "utf-8, iso-8859-1", "windows-1252");
956     }
957 
958     /**
959      * Utility for {@link #submitRequestCharset()}
960      * @param headerCharset the charset for the content type header if not null
961      * @param metaCharset the charset for the meta http-equiv content type tag if not null
962      * @param formCharset the charset for the form's accept-charset attribute if not null
963      * @throws Exception if the test fails
964      */
965     private void pageCharset(final String headerCharset,
966             final String metaCharset, final String formCharset,
967             final String expectedRequestCharset) throws Exception {
968 
969         final String formAcceptCharset;
970         if (formCharset == null) {
971             formAcceptCharset = "";
972         }
973         else {
974             formAcceptCharset = " accept-charset='" + formCharset + "'";
975         }
976 
977         final String metaContentType;
978         if (metaCharset == null) {
979             metaContentType = "";
980         }
981         else {
982             metaContentType = "<meta http-equiv='Content-Type' content='text/html; charset="
983                 + metaCharset + "'>\n";
984         }
985 
986         final String html = DOCTYPE_HTML
987             + "<html><head><title>foo</title>\n"
988             + metaContentType
989             + "</head><body>\n"
990             + "<form name='form1' method='post' action='foo'"
991             + formAcceptCharset + ">\n"
992             + "<input type='text' name='textField' value='foo'/>\n"
993             + "<input type='text' name='nonAscii' value='Flo\u00DFfahrt'/>\n"
994             + "<input type='submit' name='button' value='foo'/>\n"
995             + "</form></body></html>";
996         final WebClient client = getWebClientWithMockWebConnection();
997         final MockWebConnection webConnection = getMockWebConnection();
998 
999         String contentType = MimeType.TEXT_HTML;
1000         if (headerCharset != null) {
1001             contentType += ";charset=" + headerCharset;
1002         }
1003         webConnection.setDefaultResponse(html, 200, "ok", contentType);
1004         final HtmlPage page = client.getPage(URL_FIRST);
1005 
1006         assertEquals(expectedRequestCharset, page.getCharset().name());
1007     }
1008 
1009     /**
1010      * @throws Exception if the test fails
1011      */
1012     @Test
1013     public void sumbit_submitInputValue() throws Exception {
1014         final String html = DOCTYPE_HTML
1015             + "<html><head>\n"
1016             + "</head>\n"
1017             + "<body>\n"
1018             + "<form action='" + URL_SECOND + "'>\n"
1019             + "  <input id='myButton' type='submit' name='Save'>\n"
1020             + "</form>\n"
1021             + "</body></html>";
1022 
1023         final HtmlPage firstPage = loadPage(html);
1024         final HtmlSubmitInput submitInput = firstPage.getHtmlElementById("myButton");
1025         final HtmlPage secondPage = submitInput.click();
1026         assertEquals(URL_SECOND + "?Save=Submit+Query", secondPage.getUrl());
1027     }
1028 
1029     /**
1030      * Regression test for bug #536.
1031      * @throws Exception if the test fails
1032      */
1033     @Test
1034     public void submitWithOnClickThatReturnsFalse() throws Exception {
1035         final String firstHtml = DOCTYPE_HTML
1036             + "<html><head><title>foo</title></head><body>\n"
1037             + "<form action='" + URL_SECOND + "' method='post'>\n"
1038             + "  <input type='submit' name='mySubmit' onClick='document.forms[0].submit(); return false;'>\n"
1039             + "</form></body></html>";
1040 
1041         final String secondHtml = DOCTYPE_HTML
1042             + "<html><head><title>foo</title><script>\n"
1043             + "  Number.prototype.gn = false;\n"
1044             + "  function test() {\n"
1045             + "    var v = 0;\n"
1046             + "    alert(typeof v);\n"
1047             + "    alert(v.gn);\n"
1048             + "  }\n"
1049             + "</script></head><body onload='test()'>\n"
1050             + "</body></html>";
1051 
1052         final String[] expectedAlerts = {"number", "false"};
1053         final List<String> collectedAlerts = new ArrayList<>();
1054         final WebClient client = getWebClientWithMockWebConnection();
1055         client.setAlertHandler(new CollectingAlertHandler(collectedAlerts));
1056 
1057         final MockWebConnection conn = getMockWebConnection();
1058         conn.setResponse(URL_FIRST, firstHtml);
1059         conn.setResponse(URL_SECOND, secondHtml);
1060 
1061         final HtmlPage page = client.getPage(URL_FIRST);
1062         final HtmlForm form = page.getForms().get(0);
1063         final HtmlSubmitInput submit = form.getInputByName("mySubmit");
1064         submit.click();
1065         assertEquals(expectedAlerts, collectedAlerts);
1066     }
1067 
1068     /**
1069      * Tests that submitting a form without parameters does not trail the URL with a question mark (IE only).
1070      *
1071      * @throws Exception if the test fails
1072      */
1073     @Test
1074     public void submitURLWithoutParameters() throws Exception {
1075         final String firstHtml = DOCTYPE_HTML
1076             + "<html><head><title>foo</title></head><body>\n"
1077             + "<form action='" + URL_SECOND + "'>\n"
1078             + "  <input type='submit' name='mySubmit' onClick='document.forms[0].submit(); return false;'>\n"
1079             + "</form></body></html>";
1080 
1081         final String secondHtml = DOCTYPE_HTML + "<html><head><title>second</title></head></html>";
1082 
1083         final List<String> collectedAlerts = new ArrayList<>();
1084         final WebClient client = getWebClientWithMockWebConnection();
1085         client.setAlertHandler(new CollectingAlertHandler(collectedAlerts));
1086 
1087         final MockWebConnection conn = getMockWebConnection();
1088         conn.setResponse(URL_FIRST, firstHtml);
1089         conn.setDefaultResponse(secondHtml);
1090 
1091         final HtmlPage page = client.getPage(URL_FIRST);
1092         final HtmlForm form = page.getForms().get(0);
1093         final HtmlSubmitInput submit = form.getInputByName("mySubmit");
1094         final HtmlPage secondPage = submit.click();
1095 
1096         final String expectedURL = URL_SECOND.toString();
1097         assertEquals(expectedURL, secondPage.getUrl());
1098     }
1099 
1100     /**
1101      * @throws Exception if the test page can't be loaded
1102      */
1103     @Test
1104     public void malformedHtml_fieldGetters() throws Exception {
1105         final String html = DOCTYPE_HTML
1106             + "<html><head><title>foo</title></head><body>\n"
1107             + "<div>\n"
1108             + "<form id='form1' method='get' action='foo'>\n"
1109             + "  <input name='field1' value='val1'/>\n"
1110             + "  <input name='field2' value='val2'/>\n"
1111             + "  <input type='radio' name='radio1' value='val2'/>\n"
1112             + "  <input type='submit' id='submitButton'/>\n"
1113             + "</div>\n"
1114             + "  <input name='field3' value='val1'/>\n"
1115             + "  <input name='field4' value='val2'/>\n"
1116             + "  <input type='radio' name='radio1' value='val3'/>\n"
1117             + "  <input type='submit' id='submitButton'/>\n"
1118             + "</form></body></html>";
1119 
1120         final HtmlPage page = loadPage(html);
1121         final HtmlForm form = page.getForms().get(0);
1122 
1123         assertEquals("val1", form.getInputByName("field3").getValueAttribute());
1124         assertEquals("val1", form.getInputByName("field3").getValue());
1125         assertEquals(2, form.getInputsByName("radio1").size());
1126 
1127         assertEquals(3, form.getInputsByValue("val2").size());
1128         assertEquals("radio1", form.getInputByValue("val3").getNameAttribute());
1129 
1130         assertEquals(2, form.getRadioButtonsByName("radio1").size());
1131     }
1132 
1133     /**
1134      * Regression test for bug #784 (form lost children breakage when there is more than one
1135      * form element with the same name).
1136      * @throws Exception if an error occurs
1137      */
1138     @Test
1139     public void malformedHtml_formAndTables() throws Exception {
1140         final String html = DOCTYPE_HTML
1141             + "<html><body>\n"
1142             + "\n"
1143             + "<table id='table1'>\n"
1144             + "<tr>\n"
1145             + "<td>this is table1</td>\n"
1146             + "\n"
1147             + "<form name='cb_form' method='post' onSubmit='return formsubmit(\"submit\");'>\n"
1148             + "<input type='hidden' name='ls' value='0'>\n"
1149             + "<input type='hidden' name='seller' value='OTTO'>\n"
1150             + "<input type='hidden' name='getLA' value='true'>\n"
1151             + "<input type='hidden' name='li_count' value='10'>\n"
1152             + "<input type='hidden' name='EmailTo' value=''>\n"
1153             + "\n"
1154             + "</tr>\n"
1155             + "</table>\n"
1156             + "\n"
1157             + "<table id='table2'>\n"
1158             + "\n"
1159             + "<tr>\n"
1160             + "<td><input type='text' value='' name='OrderNr'></td>\n"
1161             + "<td><input type='text' value='' name='Size'></td>\n"
1162             + "<td><input type='text' value='' name='Quantity'></td>\n"
1163             + "</tr>\n"
1164             + "\n"
1165             + "<tr>\n"
1166             + "<td><input type='text' value='' name='OrderNr'></td>\n"
1167             + "<td><input type='text' value='' name='Size'></td>\n"
1168             + "<td><input type='text' value='' name='Quantity'></td>\n"
1169             + "</tr>\n"
1170             + "\n"
1171             + "<tr>\n"
1172             + "<td><input type='text' value='' name='OrderNr'></td>\n"
1173             + "<td><input type='text' value='' name='Size'></td>\n"
1174             + "<td><input type='text' value='' name='Quantity'></td>\n"
1175             + "</tr>\n"
1176             + "\n"
1177             + "</form>\n"
1178             + "</table>\n"
1179             + "\n"
1180             + "<script>\n"
1181             + "var i = 0;\n"
1182             + "while (document.cb_form.Quantity[i]) {\n"
1183             + "  document.cb_form.Quantity[i].value = document.cb_form.Quantity[i].value.replace(/[^0-9]/g, '');\n"
1184             + "  if ((document.cb_form.Quantity[i].value.length == 0)) {\n"
1185             + "    document.cb_form.Quantity[i].value = '1';\n"
1186             + "  }\n"
1187             + "  i++;\n"
1188             + "}\n"
1189             + "</script>\n"
1190             + "\n"
1191             + "</body></html>";
1192         final HtmlPage page = loadPage(html);
1193         final List<DomElement> quantities = page.getElementsByName("Quantity");
1194         assertEquals(3, quantities.size());
1195         for (final DomElement quantity : quantities) {
1196             assertEquals("1", ((HtmlInput) quantity).getValue());
1197         }
1198     }
1199 
1200     /**
1201      * @throws Exception if the test fails
1202      */
1203     @Test
1204     public void urlAfterSubmit2() throws Exception {
1205         final URL url = new URL(URL_FIRST, "test.html");
1206         urlAfterSubmit(url, "post", "?hi", url + "?hi");
1207         urlAfterSubmit(new URL(URL_FIRST, "test.html?there"), "post", "?hi",
1208                 URL_FIRST + "test.html?hi");
1209     }
1210 
1211     /**
1212      * @throws Exception if the test fails
1213      */
1214     @Test
1215     public void asXml_emptyTag() throws Exception {
1216         final String html = DOCTYPE_HTML
1217             + "<html><body>\n"
1218             + "<form></form>\n"
1219             + "<div>test</div>\n"
1220             + "</body></html>";
1221 
1222         final String xml =
1223             "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n"
1224             + "<html>\r\n"
1225             + "  <head/>\r\n"
1226             + "  <body>\r\n"
1227             + "    <form>\r\n"
1228             + "    </form>\r\n"
1229             + "    <div>\r\n"
1230             + "      test\r\n"
1231             + "    </div>\r\n"
1232             + "  </body>\r\n"
1233             + "</html>\r\n";
1234 
1235         final HtmlPage page = loadPage(html);
1236         assertEquals(xml, page.asXml());
1237     }
1238 
1239     /**
1240      * @throws Exception if the test fails
1241      */
1242     @Test
1243     @Alerts("second/?hiddenName=hiddenValue")
1244     public void inputHiddenAdded() throws Exception {
1245         final String html = DOCTYPE_HTML
1246             + "<html><head></head>\n"
1247             + "<body>\n"
1248             + "  <p>hello world</p>\n"
1249             + "  <form id='myForm' method='GET' action='" + URL_SECOND + "'>\n"
1250             + "    <input id='myButton' type='submit' />\n"
1251             + "  </form>\n"
1252             + "</body></html>";
1253 
1254         final String secondContent = "second content";
1255         getMockWebConnection().setResponse(URL_SECOND, secondContent);
1256 
1257         final HtmlPage page = loadPage(html);
1258         final HtmlForm form = (HtmlForm) page.getElementById("myForm");
1259 
1260         final DomElement input = page.createElement("input");
1261         input.setAttribute("type", "hidden");
1262         input.setAttribute("id", "hiddenId");
1263         input.setAttribute("name", "hiddenName");
1264         input.setAttribute("value", "hiddenValue");
1265 
1266         form.appendChild(input);
1267 
1268         page.getElementById("myButton").click();
1269 
1270         final String url = getMockWebConnection().getLastWebRequest().getUrl().toExternalForm();
1271         assertTrue(url.endsWith(getExpectedAlerts()[0]));
1272     }
1273 }