// Copyright � 2002-2007 Canoo Engineering AG, Switzerland.
package com.canoo.webtest.steps.form;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.canoo.webtest.engine.StepFailedException;
import com.canoo.webtest.self.TestBlock;
import com.canoo.webtest.self.ThrowAssert;
import com.canoo.webtest.steps.BaseStepTestCase;
import com.canoo.webtest.steps.Step;
import com.gargoylesoftware.htmlunit.AlertHandler;
import com.gargoylesoftware.htmlunit.CollectingAlertHandler;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlOption;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlSelect;
/**
* Test cases for {@link com.canoo.webtest.steps.form.SetSelectField}.
* @author Marc Guillemot
*/
public class SetSelectFieldTest extends BaseStepTestCase {
private static final String HTML_CONTENT = "<html><head><title>foo</title></head>"
+ "<body>"
+ "<form name='testForm'>"
+ "<select name='mySelect' id='mySelectId'>"
+ "<option value='0'>0</option>"
+ "<option value='1'>first</option>"
+ "<option value='2' id='opt2'>second</option>"
+ "<option value='3'>third</option>"
+ "<option>4</option>"
+ "<option selected>5</option>"
+ "</select>"
+ "</form>"
+ "No access</body></html>";
private SetSelectField fStep;
protected Step createStep() {
return new SetSelectField();
}
protected void setUp() throws Exception {
super.setUp();
fStep = (SetSelectField) getStep();
}
public void testSelectOption() {
final HtmlPage page = getDummyPage(HTML_CONTENT);
final HtmlForm form = page.getFormByName("testForm");
final HtmlSelect select = form.getSelectByName("mySelect");
// test with value
fStep.setName("mySelect");
fStep.setValue("2");
HtmlOption option = fStep.findMatchingOption(select);
fStep.updateOption(select, option);
assertEquals("second", option.asText());
assertTrue(option.isSelected());
// test with value... for an option that has no value
fStep.setValue("4");
option = fStep.findMatchingOption(select);
assertEquals("4", option.asText());
// test with index
fStep.setValue(null);
fStep.setOptionIndex("1");
option = fStep.findMatchingOption(select);
fStep.updateOption(select, option);
assertEquals("first", option.asText());
assertTrue(option.isSelected());
// test with text
fStep.setOptionIndex(null);
fStep.setText("third");
option = fStep.findMatchingOption(select);
fStep.updateOption(select, option);
assertEquals("3", option.getValueAttribute());
assertTrue(option.isSelected());
// check not finding option fails step
ThrowAssert.assertThrows(StepFailedException.class, new TestBlock() {
public void call() throws Throwable {
fStep.updateOption(select, null);
}
});
}
public void testFailureConditions() throws Exception {
fStep.setName("mySelect");
fStep.setOptionIndex("1");
fStep.setValue("anything");
fStep.setText("some text");
assertErrorOnExecute(fStep, "multiple args not allowed", SetSelectField.AT_MOST_ONE_VALUE_TEXT_OPTIONINDEX);
fStep.setValue(null);
assertErrorOnExecute(fStep, "multiple args not allowed", SetSelectField.AT_MOST_ONE_VALUE_TEXT_OPTIONINDEX);
fStep.setOptionIndex(null);
fStep.verifyParameters();
assertFalse(fStep.isRegex());
assertFalse(fStep.isMultiSelect());
}
/**
* Test identification of select and option with xpath
*/
public void testXPath()
{
getContext().setDefaultResponse(HTML_CONTENT);
final HtmlPage page = getContext().getCurrentHtmlResponse(fStep);
final HtmlSelect select = page.getFormByName("testForm").getSelectByName("mySelect");
final HtmlOption option0 = select.getOption(0);
final HtmlOption option1 = select.getOption(1);
final HtmlOption option2 = select.getOption(2);
final HtmlOption option3 = select.getOption(3);
// test with xpath for the option
fStep.setXpath("//option[@value='3']");
assertFalse(option3.isSelected());
fStep.execute();
assertTrue(option3.isSelected());
// test with xpath for the select and text for the option
fStep.setXpath("//select");
fStep.setText("first");
fStep.execute();
assertTrue(option1.isSelected());
// test with xpath for the select and text for the option
fStep.setXpath("//select");
fStep.setText(null);
fStep.setValue("0");
fStep.execute();
assertTrue(option0.isSelected());
// test with xpath for the select and optionIndex for the option
fStep.setXpath("//select");
fStep.setText(null);
fStep.setValue(null);
fStep.setOptionIndex("2");
fStep.execute();
assertTrue(option2.isSelected());
}
/**
* Test identification of select and option with id
*/
public void testHtmlId()
{
getContext().setDefaultResponse(HTML_CONTENT);
final HtmlPage page = getContext().getCurrentHtmlResponse(fStep);
final HtmlSelect select = page.getFormByName("testForm").getSelectByName("mySelect");
final HtmlOption option1 = select.getOption(1);
final HtmlOption option2 = select.getOption(2);
// test with id for the option
fStep.setHtmlId("opt2");
assertFalse(option2.isSelected());
fStep.execute();
assertTrue(option2.isSelected());
// test with id for the select and text for the option
fStep.setHtmlId("mySelectId");
fStep.setText("first");
fStep.execute();
assertTrue(option1.isSelected());
// test with id for the select and nothing for the option
fStep.setHtmlId("mySelectId");
fStep.setText(null);
assertErrorOnExecute(fStep, "", SetSelectField.MESSAGE_MISSING_OPTION_IDENTIFIER);
}
/**
* Regression test for bug WT-143: onchange was wrongly triggered twice
*/
public void testOnchangeTriggeredTwice()
{
// add onchange handler to standard code
final String html = HTML_CONTENT.replaceFirst("id='mySelectId'", "id='mySelectId' onchange='alert(this.selectedIndex)')");
getContext().setDefaultResponse(html);
final HtmlPage page = getContext().getCurrentHtmlResponse(fStep);
final WebClient client = page.getWebClient();
final List collectedAlerts = new ArrayList();
final AlertHandler alertHandler = new CollectingAlertHandler(collectedAlerts);
client.setAlertHandler(alertHandler);
fStep.setName("mySelect");
fStep.setValue("3");
fStep.execute();
final List expectedAlerts = Collections.singletonList("3");
assertEquals(expectedAlerts, collectedAlerts);
}
}