/* * Copyright (c) 2002-2008 Gargoyle Software Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.gargoylesoftware.htmlunit.html; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.fail; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import org.junit.Test; import com.gargoylesoftware.htmlunit.HttpMethod; import com.gargoylesoftware.htmlunit.MockWebConnection; import com.gargoylesoftware.htmlunit.Page; import com.gargoylesoftware.htmlunit.WebTestCase; /** * Tests for {@link HtmlSelect}. * * @version $Revision$ * @author Mike Bowler * @author Mike Williams * @author Marc Guillemot * @author Ahmed Ashour */ public class HtmlSelectTest extends WebTestCase { /** * Test the good path of submitting a select. * @exception Exception If the test fails */ @Test public void testSelect() throws Exception { final String htmlContent = "foo\n" + "
\n" + "\n" + "
"; final HtmlPage page = loadPage(htmlContent); final MockWebConnection webConnection = getMockConnection(page); final HtmlForm form = (HtmlForm) page.getHtmlElementById("form1"); final HtmlSelect select = form.getSelectsByName("select1").get(0); final HtmlSubmitInput button = (HtmlSubmitInput) form.getInputByName("button"); // Test that the select is being correctly identified as a submittable element assertEquals(Arrays.asList(new Object[] {select, button}), form.getSubmittableElements(button)); // Test that the correct value is being passed back up to the server final HtmlPage secondPage = (HtmlPage) button.click(); assertEquals("url", URL_GARGOYLE.toExternalForm() + "?select1=option2&button=foo", secondPage.getWebResponse().getUrl()); assertSame("method", HttpMethod.GET, webConnection.getLastMethod()); assertNotNull(secondPage); } /** * Tests submitting the select with no options selected. * @exception Exception If the test fails */ @Test public void testSelect_MultipleSelectNoneSelected() throws Exception { final String htmlContent = "foo\n" + "
\n" + "\n" + "
"; final HtmlPage page = loadPage(htmlContent); final MockWebConnection webConnection = getMockConnection(page); final HtmlForm form = (HtmlForm) page.getHtmlElementById("form1"); final HtmlSelect select = form.getSelectsByName("select1").get(0); assertNotNull(select); final HtmlSubmitInput button = (HtmlSubmitInput) form.getInputByName("button"); // Test that the correct value is being passed back up to the server final HtmlPage secondPage = (HtmlPage) button.click(); assertEquals("url", URL_GARGOYLE.toExternalForm() + "?button=foo", secondPage.getWebResponse().getUrl()); assertSame("method", HttpMethod.GET, webConnection.getLastMethod()); assertNotNull(secondPage); } /** * Tests changing the selected option. * @exception Exception If the test fails */ @Test public void testSelect_ChangeSelectedOption_SingleSelect() throws Exception { final String htmlContent = "foo\n" + "
\n" + "\n" + "
"; final HtmlPage page = loadPage(htmlContent); final MockWebConnection webConnection = getMockConnection(page); final HtmlForm form = (HtmlForm) page.getHtmlElementById("form1"); final HtmlSelect select = form.getSelectsByName("select1").get(0); final HtmlSubmitInput button = (HtmlSubmitInput) form.getInputByName("button"); // Change the value select.setSelectedAttribute("option3", true); // Test that the correct value is being passed back up to the server final HtmlPage secondPage = (HtmlPage) button.click(); assertEquals("url", URL_GARGOYLE.toExternalForm() + "?select1=option3&button=foo", secondPage.getWebResponse().getUrl()); assertSame("method", HttpMethod.GET, webConnection.getLastMethod()); assertNotNull(secondPage); } /** * Tests changing the selected option. * @exception Exception If the test fails */ @Test public void testSelect_ChangeSelectedOption_MultipleSelect() throws Exception { final String htmlContent = "foo\n" + "
\n" + "\n" + "
"; final HtmlPage page = loadPage(htmlContent); final MockWebConnection webConnection = getMockConnection(page); final HtmlForm form = (HtmlForm) page.getHtmlElementById("form1"); final HtmlSelect select = form.getSelectsByName("select1").get(0); final HtmlSubmitInput button = (HtmlSubmitInput) form.getInputByName("button"); // Change the value select.setSelectedAttribute("option3", true); select.setSelectedAttribute("option2", true); // Test that the correct value is being passed back up to the server final HtmlPage secondPage = (HtmlPage) button.click(); assertEquals("url", URL_GARGOYLE.toExternalForm() + "?select1=option1&select1=option2&select1=option3&button=foo", secondPage.getWebResponse().getUrl()); assertSame("method", HttpMethod.GET, webConnection.getLastMethod()); assertNotNull(secondPage); } /** * Tests multiple selected options on multiple select lists. * @exception Exception If the test fails */ @Test public void testSelect_MultipleSelectMultipleSelected() throws Exception { final String htmlContent = "foo\n" + "
\n" + "\n" + "
"; final HtmlPage page = loadPage(htmlContent); final HtmlForm form = (HtmlForm) page.getHtmlElementById("form1"); final HtmlSelect select = form.getSelectsByName("select1").get(0); final List expected = new ArrayList(); expected.add(select.getOptionByValue("option1")); expected.add(select.getOptionByValue("option3")); assertEquals(expected, select.getSelectedOptions()); } /** * Test multiple selected options on single select lists. This is erroneous HTML, but * browsers simply use the last option. * * @exception Exception If the test fails */ @Test public void testSelect_SingleSelectMultipleSelected() throws Exception { final String htmlContent = "foo\n" + "
\n" + "\n" + "
"; final HtmlPage page = loadPage(htmlContent); final HtmlForm form = (HtmlForm) page.getHtmlElementById("form1"); final HtmlSelect select = form.getSelectsByName("select1").get(0); final List expected = new ArrayList(); expected.add(select.getOptionByValue("option3")); assertEquals(expected, select.getSelectedOptions()); } /** * Test no selected options on single select lists. This is erroneous HTML, but * browsers simply assume the first one to be selected * * @exception Exception If the test fails */ @Test public void testSelect_SingleSelectNoneSelected() throws Exception { final String htmlContent = "foo\n" + "
\n" + "\n" + "
"; final HtmlPage page = loadPage(htmlContent); final HtmlForm form = (HtmlForm) page.getHtmlElementById("form1"); final HtmlSelect select = form.getSelectsByName("select1").get(0); final List expected = new ArrayList(); expected.add(select.getOptionByValue("option1")); assertEquals(expected, select.getSelectedOptions()); } /** * Tests no selected options on single select lists with a size > 1. * @exception Exception If the test fails */ @Test public void testSelect_SingleSelectNoneSelectedButSizeGreaterThanOne() throws Exception { final String htmlContent = "foo\n" + "
\n" + "\n" + "
"; final HtmlPage page = loadPage(htmlContent); final HtmlSelect select = (HtmlSelect) page.getHtmlElementById("mySelect"); assertEquals(Collections.EMPTY_LIST, select.getSelectedOptions()); } /** * Tests changing the selected option. * @exception Exception If the test fails */ @Test public void testSetSelected_IllegalValue() throws Exception { final String htmlContent = "foo\n" + "
\n" + "\n" + "\n" + "
"; final HtmlPage page = loadPage(htmlContent); final HtmlForm form = (HtmlForm) page.getHtmlElementById("form1"); final HtmlSelect select = form.getSelectByName("select1"); // Change the value try { select.setSelectedAttribute("missingOption", true); fail("Expected IllegalArgumentException"); } catch (final IllegalArgumentException e) { // Expected path } } /** * @throws Exception if the test fails */ @Test public void testGetOptions() throws Exception { final String htmlContent = "foo\n" + "
\n" + "\n" + "
"; final HtmlPage page = loadPage(htmlContent); final HtmlForm form = (HtmlForm) page.getHtmlElementById("form1"); final HtmlSelect select = form.getSelectsByName("select1").get(0); final List expectedOptions = new ArrayList(); expectedOptions.add(select.getOptionByValue("option1")); expectedOptions.add(select.getOptionByValue("option2")); expectedOptions.add(select.getOptionByValue("option3")); assertEquals(expectedOptions, select.getOptions()); } /** * @throws Exception if the test fails */ @Test public void testSelect_OptionMultiple_NoValueOnAttribute() throws Exception { final String htmlContent = "foo\n" + "
\n" + "\n" + "
"; final HtmlPage page = loadPage(htmlContent); final HtmlSelect select = (HtmlSelect) page.getHtmlElementById("select1"); assertTrue(select.isMultipleSelectEnabled()); } /** * @throws Exception if the test fails */ @Test public void testGetOptionByValue() throws Exception { final String htmlContent = "foo
\n" + "\n" + "\n" + "\n" + "
"; final HtmlPage page = loadPage(htmlContent); final HtmlForm form = (HtmlForm) page.getHtmlElementById("form1"); final HtmlSelect select = form.getSelectsByName("select2").get(0); assertEquals("s2o2", select.getOptionByValue("option2").asText()); assertEquals(select.getOption(2), select.getOptionByValue("s2o3")); } /** * @throws Exception if the test fails */ @Test public void testSelect_SetSelected_OnChangeHandler() throws Exception { final String htmlContent = "foo\n" + "
\n" + "\n" + "
"; final List collectedAlerts = new ArrayList(); final HtmlPage page = loadPage(htmlContent, collectedAlerts); final HtmlForm form = (HtmlForm) page.getHtmlElementById("form1"); final HtmlSelect select = form.getSelectsByName("select1").get(0); // Change the value select.setSelectedAttribute("option3", true); final String[] expectedAlerts = {"changing"}; assertEquals(expectedAlerts, collectedAlerts); } /** * @throws Exception if the test fails */ @Test public void testSetSelectionOnOptionWithNoName() throws Exception { final String htmlContent = "
\n" + "\n" + "
"; final List collectedAlerts = new ArrayList(); final HtmlPage page = loadPage(htmlContent, collectedAlerts); final HtmlOption option = (HtmlOption) page.getHtmlElementById("option2"); option.setSelected(true); } private void checkOptions(final HtmlSelect select) { final List options = select.getOptions(); if (options.isEmpty()) { assertNull(select.getFirstChild()); assertNull(select.getLastChild()); } else { assertEquals(options.get(0), select.getFirstChild()); assertEquals(options.get(options.size() - 1), select.getLastChild()); } } /** @throws Exception if the test fails */ @Test public void testRemoveOptionsFromSelect() throws Exception { final String htmlContent = "
\n" + "\n" + "
"; final HtmlPage page = loadPage(htmlContent); final HtmlSelect theSelect = (HtmlSelect) page.getHtmlElementById("theSelect"); assertNotNull(theSelect); assertEquals(4, theSelect.getOptions().size()); assertEquals("a", theSelect.getOption(0).getValueAttribute()); assertEquals("b", theSelect.getOption(1).getValueAttribute()); assertEquals("c", theSelect.getOption(2).getValueAttribute()); assertEquals("d", theSelect.getOption(3).getValueAttribute()); // remove from the middle theSelect.getOption(1).remove(); checkOptions(theSelect); assertEquals(3, theSelect.getOptions().size()); assertEquals("a", theSelect.getOption(0).getValueAttribute()); assertEquals("c", theSelect.getOption(1).getValueAttribute()); assertEquals("d", theSelect.getOption(2).getValueAttribute()); // remove from the end theSelect.getOption(2).remove(); checkOptions(theSelect); assertEquals(2, theSelect.getOptions().size()); assertEquals("a", theSelect.getOption(0).getValueAttribute()); assertEquals("c", theSelect.getOption(1).getValueAttribute()); // remove from the front theSelect.getOption(0).remove(); checkOptions(theSelect); assertEquals(1, theSelect.getOptions().size()); assertEquals("c", theSelect.getOption(0).getValueAttribute()); // remove from the last one theSelect.getOption(0).remove(); checkOptions(theSelect); assertEquals(0, theSelect.getOptions().size()); } /** @throws Exception if the test fails */ @Test public void testEditOptions() throws Exception { final String htmlContent = "
\n" + "\n" + "
"; final HtmlPage page = loadPage(htmlContent); final HtmlSelect theSelect = (HtmlSelect) page.getHtmlElementById("theSelect"); assertNotNull(theSelect); assertEquals(3, theSelect.getOptions().size()); appendOption(theSelect, "d"); assertEquals(4, theSelect.getOptions().size()); assertEquals("d", theSelect.getOption(3).getValueAttribute()); theSelect.setOptionSize(1); assertEquals(1, theSelect.getOptions().size()); assertEquals("a", theSelect.getOption(0).getValueAttribute()); appendOption(theSelect, "x"); assertEquals(2, theSelect.getOptions().size()); assertEquals("x", theSelect.getOption(1).getValueAttribute()); } void appendOption(final HtmlSelect select, final String value) { final HtmlOption option = (HtmlOption) HTMLParser.getFactory(HtmlOption.TAG_NAME).createElement( select.getPage(), HtmlOption.TAG_NAME, null); option.setValueAttribute(value); option.setLabelAttribute(value); select.appendOption(option); } /** * Test that asText() returns a blank string if nothing is selected. * * @exception Exception If the test fails */ @Test public void testAsTextWhenNothingSelected() throws Exception { final String htmlContent = "foo\n" + "
\n" + "\n" + "
"; final HtmlPage page = loadPage(htmlContent); final HtmlSelect select = (HtmlSelect) page.getHtmlElementById("mySelect"); assertEquals("", select.asText()); } /** * Verifies that asText() returns all options when multiple options are selectable, instead of just * the selected ones. * @throws Exception if an error occurs */ @Test public void testAsTextWithMultipleSelect() throws Exception { final String html = "
\n" + "\n" + "
"; final HtmlPage page = loadPage(html); final HtmlSelect select = (HtmlSelect) page.getDocumentElement().getHtmlElementsByTagName("select").get(0); assertEquals("foo\nbar\nbaz", select.asText()); } /** * Test that setSelectedAttribute returns the right page. * * @exception Exception If the test fails */ @Test public void testSetSelectedAttributeReturnedPage() throws Exception { final String content = "foo\n" + "\n" + "\n" + "
\n" + "\n" + "
\n" + "\n" + ""; final HtmlPage page = loadPage(content); final HtmlSelect select = (HtmlSelect) page.getHtmlElementById("mySelect"); final HtmlOption option = select.getOptionByValue("option2"); final Page page2 = select.setSelectedAttribute(option, true); assertEquals(page, page2); } /** * @throws Exception if the test fails */ @Test public void testOnChangeResultPage() throws Exception { final String htmlContent = "foo\n" + "
\n" + "\n" + "
"; final HtmlPage page = loadPage(htmlContent); final HtmlOption option1 = (HtmlOption) page.getHtmlElementById("option1"); assertEquals("about:blank", option1.click().getWebResponse().getUrl()); } /** * @throws Exception if the test fails */ @Test public void testSelectedIndex() throws Exception { final String content = "foo\n" + "
\n" + " \n" + ""; final HtmlPage page = loadPage(content); assertEquals(-1, page.asXml().indexOf("size")); } /** * @throws Exception if the test fails */ @Test public void select_focus() throws Exception { final String htmlContent = "foo\n" + "\n" + "\n" + "\n" + "
"; final List collectedAlerts = new ArrayList(); final HtmlPage page = loadPage(htmlContent, collectedAlerts); assertEquals(Collections.emptyList(), collectedAlerts); final HtmlSelect select = (HtmlSelect) page.getHtmlElementById("select1"); assertNull(page.getFocusedElement()); select.getOption(0).setSelected(true); assertSame(select, page.getFocusedElement()); final String[] expectedAlerts = {"focus"}; assertEquals(expectedAlerts, collectedAlerts); } }