/*
* 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"
+ "";
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"
+ "";
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"
+ "";
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"
+ "";
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"
+ "";
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"
+ "";
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"
+ "";
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"
+ "";
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"
+ "";
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"
+ "";
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"
+ "";
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";
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"
+ "";
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 = "";
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 = "";
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 = "";
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"
+ "";
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 = "";
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"
+ "";
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"
+ "";
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"
+ "";
final String[] expectedAlerts = {"0"};
final List collectedAlerts = new ArrayList();
loadPage(content, collectedAlerts);
assertEquals(expectedAlerts, collectedAlerts);
}
/**
* @throws Exception if the test fails
*/
@Test
public void testAsXml_size() 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"
+ "";
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);
}
}