From: <rb...@us...> - 2013-04-24 18:18:32
|
Revision: 8240 http://sourceforge.net/p/htmlunit/code/8240 Author: rbri Date: 2013-04-24 18:18:29 +0000 (Wed, 24 Apr 2013) Log Message: ----------- more test, minor cleanup and preventDefault fix for radio buttons Modified Paths: -------------- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPage.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlRadioButtonInput.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/html/HtmlRadioButtonInput2Test.java Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPage.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPage.java 2013-04-23 19:26:30 UTC (rev 8239) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPage.java 2013-04-24 18:18:29 UTC (rev 8240) @@ -1999,43 +1999,6 @@ } /** - * Select the specified radio button in the page (outside any <form>). - * - * @param radioButtonInput the radio Button - */ - @SuppressWarnings("unchecked") - void setCheckedRadioButton(final HtmlRadioButtonInput radioButtonInput) { - // May be done in single XPath search? - final List<HtmlRadioButtonInput> pageInputs = - (List<HtmlRadioButtonInput>) getByXPath("//input[lower-case(@type)='radio' " - + "and @name='" + radioButtonInput.getNameAttribute() + "']"); - final List<HtmlRadioButtonInput> formInputs = - (List<HtmlRadioButtonInput>) getByXPath("//form//input[lower-case(@type)='radio' " - + "and @name='" + radioButtonInput.getNameAttribute() + "']"); - - pageInputs.removeAll(formInputs); - - boolean found = false; - for (final HtmlRadioButtonInput input : pageInputs) { - if (input == radioButtonInput) { - input.setAttribute("checked", "checked"); - found = true; - } - else { - input.removeAttribute("checked"); - } - } - for (final HtmlRadioButtonInput input : formInputs) { - if (input == radioButtonInput) { - found = true; - } - } - if (!found) { - radioButtonInput.setAttribute("checked", "checked"); - } - } - - /** * Creates a clone of this instance, and clears cached state * to be not shared with the original. * Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlRadioButtonInput.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlRadioButtonInput.java 2013-04-23 19:26:30 UTC (rev 8239) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlRadioButtonInput.java 2013-04-24 18:18:29 UTC (rev 8240) @@ -20,6 +20,7 @@ import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTMLINPUT_SET_CHECKED_TO_FALSE_WHEN_ADDED; import java.io.IOException; +import java.util.List; import java.util.Map; import com.gargoylesoftware.htmlunit.Page; @@ -101,7 +102,7 @@ form.setCheckedRadioButton(this); } else if (page instanceof HtmlPage) { - ((HtmlPage) page).setCheckedRadioButton(this); + setCheckedForPage((HtmlPage) page); } } else { @@ -134,13 +135,46 @@ form.setCheckedRadioButton(this); } else if (page instanceof HtmlPage) { - ((HtmlPage) page).setCheckedRadioButton(this); + setCheckedForPage((HtmlPage) page); } super.doClickStateUpdate(); return changed; } /** + * Select the specified radio button in the page (outside any <form>). + * + * @param radioButtonInput the radio Button + */ + @SuppressWarnings("unchecked") + private void setCheckedForPage(final HtmlPage htmlPage) { + // May be done in single XPath search? + final List<HtmlRadioButtonInput> pageInputs = + (List<HtmlRadioButtonInput>) htmlPage.getByXPath("//input[lower-case(@type)='radio' " + + "and @name='" + getNameAttribute() + "']"); + final List<HtmlRadioButtonInput> formInputs = + (List<HtmlRadioButtonInput>) htmlPage.getByXPath("//form//input[lower-case(@type)='radio' " + + "and @name='" + getNameAttribute() + "']"); + + pageInputs.removeAll(formInputs); + + boolean foundInPage = false; + for (final HtmlRadioButtonInput input : pageInputs) { + if (input == this) { + input.setAttribute("checked", "checked"); + foundInPage = true; + } + else { + input.removeAttribute("checked"); + } + } + + if (!foundInPage && !formInputs.contains(this)) { + setAttribute("checked", "checked"); + } + } + + /** * {@inheritDoc} */ @Override @@ -163,6 +197,14 @@ /** * {@inheritDoc} + */ + @Override + protected void preventDefault() { + setChecked(!isChecked()); + } + + /** + * {@inheritDoc} * Also sets the value to the new default value. * @see SubmittableElement#setDefaultValue(String) */ Modified: trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/html/HtmlRadioButtonInput2Test.java =================================================================== --- trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/html/HtmlRadioButtonInput2Test.java 2013-04-23 19:26:30 UTC (rev 8239) +++ trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/html/HtmlRadioButtonInput2Test.java 2013-04-24 18:18:29 UTC (rev 8240) @@ -20,6 +20,7 @@ import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; import com.gargoylesoftware.htmlunit.BrowserRunner; import com.gargoylesoftware.htmlunit.BrowserRunner.Alerts; @@ -473,4 +474,99 @@ assertEquals(getExpectedAlerts()[1], driver.getTitle()); } } + + /** + * @throws Exception if an error occurs + */ + @Test + public void preventDefault() throws Exception { + final String html = + "<html><head><script>\n" + + " function handler(e) {\n" + + " if (e)\n" + + " e.preventDefault();\n" + + " else\n" + + " return false;\n" + + " }\n" + + " function init() {\n" + + " document.getElementById('radio1').onclick = handler;\n" + + " }\n" + + "</script></head>\n" + + "<body onload='init()'>\n" + + " <input type='radio' id='radio1' name='radio1' />\n" + + "</body></html>"; + + final WebDriver driver = loadPage2(html); + final WebElement radio = driver.findElement(By.id("radio1")); + radio.click(); + assertFalse(radio.isSelected()); + } + + /** + * Verifies that a HtmlCheckBox is unchecked by default. + * The onClick tests make this assumption. + * @throws Exception if the test fails + */ + @Test + public void defaultState() throws Exception { + final String html + = "<html><head><title>foo</title></head><body>\n" + + "<form id='form1'>\n" + + " <input type='radio' name='radio' id='radio'>Check me</input>\n" + + "</form></body></html>"; + final WebDriver driver = loadPage2(html); + final WebElement radio = driver.findElement(By.id("radio")); + assertFalse(radio.isSelected()); + } + + /** + * @throws Exception if the test fails + */ + @Test + @Alerts({ "on", "on", "on", "on" }) + public void defaultValue() throws Exception { + final String html = "<html><head><title>foo</title>\n" + + "<script>\n" + + " function test() {\n" + + " alert(document.getElementById('rdo').value);\n" + + + " var input = document.createElement('input');\n" + + " input.type = 'radio';\n" + + " alert(input.value);\n" + + + " var builder = document.createElement('div');\n" + + " builder.innerHTML = '<input type=\"radio\">';\n" + + " var input = builder.firstChild;\n" + + " alert(input.value);\n" + + + " input = input.cloneNode(false);\n" + + " alert(input.value);\n" + + " }\n" + + "</script>\n" + + "</head><body onload='test()'>\n" + + "<form>\n" + + " <input type='radio' id='rdo'>\n" + + "</form>\n" + + "</body></html>"; + + loadPageWithAlerts2(html); + } + + /** + * Call to JS function click() should trigger the onchange handler but neither the onfocus handler + * nor the mousedown/up handlers. + * @throws Exception if the test fails + */ + @Test + @Alerts("changed") + public void clickShouldTriggerOnchange() throws Exception { + final String html = "<html><body>\n" + + "<input type='radio' id='it' onchange='alert(\"changed\")'" + + "onmousedown='alert(\"down\")' onmouseup='alert(\"up\")' onfocus='alert(\"focused\")'>Check me\n" + + "<script>\n" + + "var elt = document.getElementById('it');\n" + + "elt.click();\n" + + "</script></body></html>"; + loadPageWithAlerts2(html); + } } |