blob: fe57507727a352c4d92349af10669a8481e1297e [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Expire" content="0"/>
<title>select_test.html</title>
<script type="text/javascript" src="test_bootstrap.js"></script>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript">
goog.require('bot.action');
goog.require('bot.locators');
goog.require('bot.userAgent');
goog.require('goog.array');
goog.require('goog.dom');
goog.require('goog.events');
goog.require('goog.testing.jsunit');
goog.require('goog.userAgent');
</script>
<script type="text/javascript">
var singleSelect, multiSelect, radioButtons, checkboxes, changeCount;
function setUpPage() {
singleSelect = bot.locators.findElement({id: 'singleSelect'});
multiSelect = bot.locators.findElement({id: 'multiSelect'});
checkboxes = bot.locators.findElements({name: 'checkbox'});
radioButtons = bot.locators.findElements({name: 'radio'});
}
function setUp() {
goog.events.removeAll();
singleSelect.selectedIndex = 0;
goog.array.forEach(multiSelect.options, function(e) {
e.selected = false;
});
goog.array.forEach(checkboxes, function(e) {
e.checked = false;
});
goog.array.forEach(radioButtons, function(e) {
e.checked = false;
});
}
function checkActionCompatibility(action) {
if (action == bot.action.tap) {
return bot.events.SUPPORTS_TOUCH_EVENTS;
}
return true;
}
function expectChanges(target) {
changeCount = 0;
goog.events.listen(target, 'change', function(e) {
changeCount++;
});
}
function assertChanges(expectedCount) {
assertEquals('Unexpected number of changes', expectedCount, changeCount);
}
function canSelectAnOptionFromASingleSelect(action) {
if (!checkActionCompatibility(action)) {
return;
}
assertFalse(bot.dom.isSelected(singleSelect.options[1]));
expectChanges(singleSelect);
action(singleSelect.options[1]);
assertChanges(1);
assertTrue(bot.dom.isSelected(singleSelect.options[1]));
}
var testClickCanSelectAnOptionFromASingleSelect =
goog.partial(canSelectAnOptionFromASingleSelect, bot.action.click);
var testTapCanSelectAnOptionFromASingleSelect =
goog.partial(canSelectAnOptionFromASingleSelect, bot.action.tap);
function cannotDeselectAnOptionFromASingleSelect(action) {
if (!checkActionCompatibility(action)) {
return;
}
assertTrue(bot.dom.isSelected(singleSelect.options[0]));
expectChanges(singleSelect);
action(singleSelect.options[0]);
assertChanges(0);
assertTrue(bot.dom.isSelected(singleSelect.options[0]));
}
var testClickCannotDeselectAnOptionFromASingleSelect =
goog.partial(cannotDeselectAnOptionFromASingleSelect, bot.action.click);
var testTapCannotDeselectAnOptionFromASingleSelect =
goog.partial(cannotDeselectAnOptionFromASingleSelect, bot.action.tap);
function cannotSelectAnOptionFromADisabledSelect(action) {
if (!checkActionCompatibility(action)) {
return;
}
singleSelect.disabled = true;
assertFalse(bot.dom.isSelected(singleSelect.options[1]));
expectChanges(singleSelect);
action(singleSelect.options[1]);
assertChanges(0);
assertFalse(bot.dom.isSelected(singleSelect.options[1]));
singleSelect.disabled = false;
}
var testClickCannotSelectAnOptionFromADisabled =
goog.partial(cannotSelectAnOptionFromADisabledSelect, bot.action.click);
var testTapCannotSelectAnOptionFromADisabled =
goog.partial(cannotSelectAnOptionFromADisabledSelect, bot.action.tap);
function canSelectAnEnabledOptionFromASelectWithADisabledOption(action) {
if (!checkActionCompatibility(action)) {
return;
}
singleSelect.options[1].disabled = true;
assertFalse(bot.dom.isSelected(singleSelect.options[2]));
expectChanges(singleSelect);
action(singleSelect.options[2]);
assertChanges(1);
assertTrue(bot.dom.isSelected(singleSelect.options[2]));
singleSelect.options[1].disabled = false;
}
var testClickCanSelectAnEnabledOptionFromASelectWithADisabledOption =
goog.partial(canSelectAnEnabledOptionFromASelectWithADisabledOption,
bot.action.click);
var testTapCanSelectAnEnabledOptionFromASelectWithADisabledOption =
goog.partial(canSelectAnEnabledOptionFromASelectWithADisabledOption,
bot.action.tap);
function canToggleOptionsInAMultiSelect(action) {
if (!checkActionCompatibility(action)) {
return;
}
multiSelect.options[0].selected = true;
expectChanges(multiSelect);
action(multiSelect.options[0]);
action(multiSelect.options[1]);
action(multiSelect.options[2]);
assertChanges(3);
assertFalse(bot.dom.isSelected(multiSelect.options[0]));
assertTrue(bot.dom.isSelected(multiSelect.options[1]));
assertTrue(bot.dom.isSelected(multiSelect.options[2]));
}
var testClickCanToggleOptionsInAMultiSelect =
goog.partial(canToggleOptionsInAMultiSelect, bot.action.click);
var testTapCanToggleOptionsInAMultiSelect =
goog.partial(canToggleOptionsInAMultiSelect, bot.action.tap);
function canToggleCheckboxes(action) {
if (!checkActionCompatibility(action)) {
return;
}
// IE fires a change event on the next click after the change.
checkboxes[0].checked = true;
expectChanges(checkboxes[0]);
action(checkboxes[0]);
assertChanges(bot.userAgent.IE_DOC_PRE9 ? 0 : 1);
if (!goog.userAgent.IE) {
expectChanges(checkboxes[1]);
}
action(checkboxes[1]);
assertChanges(1);
expectChanges(checkboxes[bot.userAgent.IE_DOC_PRE9 ? 1 : 2]);
action(checkboxes[2]);
assertChanges(1);
assertFalse(bot.dom.isSelected(checkboxes[0]));
assertTrue(bot.dom.isSelected(checkboxes[1]));
assertTrue(bot.dom.isSelected(checkboxes[2]));
}
var testClickCanToggleCheckboxes =
goog.partial(canToggleCheckboxes, bot.action.click);
var testTapCanToggleCheckboxes =
goog.partial(canToggleCheckboxes, bot.action.tap);
function canSelectRadioButtons(action) {
if (!checkActionCompatibility(action)) {
return;
}
// IE fires a change event on the next click after the change.
expectChanges(radioButtons[0]);
action(radioButtons[0]);
assertChanges(bot.userAgent.IE_DOC_PRE9 ? 0 : 1);
assertTrue(bot.dom.isSelected(radioButtons[0]));
if (!goog.userAgent.IE) {
expectChanges(radioButtons[1]);
}
action(radioButtons[1]);
assertChanges(1);
assertTrue(bot.dom.isSelected(radioButtons[1]));
expectChanges(radioButtons[bot.userAgent.IE_DOC_PRE9 ? 1 : 2]);
action(radioButtons[2]);
assertChanges(1);
assertTrue(bot.dom.isSelected(radioButtons[2]));
}
var testClickCanSelectRadioButtons =
goog.partial(canSelectRadioButtons, bot.action.click);
var testTapCanSelectRadioButtons =
goog.partial(canSelectRadioButtons, bot.action.tap);
function cannotDeselectRadioButtons(action) {
if (!checkActionCompatibility(action)) {
return;
}
radioButtons[0].checked = true;
expectChanges(radioButtons[0]);
action(radioButtons[0]);
assertChanges(0);
assertTrue(bot.dom.isSelected(radioButtons[0]));
}
var testClickCannotDeselectRadioButtons =
goog.partial(cannotDeselectRadioButtons, bot.action.click);
var testTapCannotDeselectRadioButtons =
goog.partial(cannotDeselectRadioButtons, bot.action.tap);
function cannotSelectDisabledElements(action) {
if (!checkActionCompatibility(action)) {
return;
}
function assertCannotSelectWhenDisabled(elem, isOption) {
elem.disabled = true;
expectChanges(isOption ? elem.parentNode : elem);
action(elem);
assertChanges(0);
assertFalse(bot.dom.isSelected(elem));
elem.disabled = false;
}
assertCannotSelectWhenDisabled(singleSelect.options[1], true);
assertCannotSelectWhenDisabled(multiSelect.options[0], true);
assertCannotSelectWhenDisabled(checkboxes[0], false);
assertCannotSelectWhenDisabled(radioButtons[0], false);
}
var testClickCannotSelectDisabledElements =
goog.partial(cannotSelectDisabledElements, bot.action.click);
var testTapCannotSelectDisabledElements =
goog.partial(cannotSelectDisabledElements, bot.action.tap);
function canSelectOptionWhenDefaultPrevented(action) {
if (!checkActionCompatibility(action)) {
return;
}
function assertCanSelectWhenDefaultPrevented(elem) {
goog.events.listen(elem, 'click', function(e) {
e.preventDefault();
});
expectChanges(elem.parentNode);
action(elem);
assertChanges(1);
assertTrue(bot.dom.isSelected(elem));
}
assertCanSelectWhenDefaultPrevented(singleSelect.options[1]);
assertCanSelectWhenDefaultPrevented(multiSelect.options[0]);
}
var testClickCanSelectOptionWhenDefaultPrevented =
goog.partial(canSelectOptionWhenDefaultPrevented, bot.action.click);
var testTapCanSelectOptionWhenDefaultPrevented =
goog.partial(canSelectOptionWhenDefaultPrevented, bot.action.tap);
function cannotSelectCheckboxWhenDefaultPrevented(action) {
if (!checkActionCompatibility(action)) {
return;
}
var elem = checkboxes[0];
goog.events.listen(elem, 'click', function(e) {
e.preventDefault();
});
expectChanges(elem);
action(elem);
// WebKit and IE9 standards mode fire change events when the
// checkbox isn't toggled.
assertChanges(
goog.userAgent.WEBKIT || bot.userAgent.IE_DOC_9 ? 1 : 0);
assertFalse(bot.dom.isSelected(elem));
}
var testClickCannotSelectCheckboxWhenDefaultPrevented =
goog.partial(cannotSelectCheckboxWhenDefaultPrevented,
bot.action.click);
var testTapCannotSelectCheckboxWhenDefaultPrevented =
goog.partial(cannotSelectCheckboxWhenDefaultPrevented, bot.action.tap);
function maybeSelectRadioButtonWhenDefaultPrevented(action) {
if (!checkActionCompatibility(action)) {
return;
}
var elem = radioButtons[0];
goog.events.listen(elem, 'click', function(e) {
e.preventDefault();
});
expectChanges(elem);
action(elem);
// WebKit and Firefox < 11 select a radio button even when the handler
// prevents the default; IE and Opera do not.
if (goog.userAgent.WEBKIT ||
(goog.userAgent.GECKO && !bot.userAgent.isEngineVersion(11))) {
// Gecko does toggle the radio button, but doesn't fire a change event.
assertChanges(goog.userAgent.GECKO ? 0 : 1);
assertTrue(bot.dom.isSelected(elem));
} else {
// IE9 standards mode still fires the change event.
assertChanges(bot.userAgent.IE_DOC_9 ? 1 : 0);
assertFalse(bot.dom.isSelected(elem));
}
}
var testClickMaybeSelectRadioButtonWhenDefaultPrevented =
goog.partial(maybeSelectRadioButtonWhenDefaultPrevented,
bot.action.click);
var testTapMaybeSelectRadioButtonWhenDefaultPrevented =
goog.partial(maybeSelectRadioButtonWhenDefaultPrevented,
bot.action.tap);
/** @see http://code.google.com/p/selenium/issues/detail?id=1941 */
function canSelectOptionFromTransparentSelect(action) {
if (!checkActionCompatibility(action)) {
return;
}
var style = singleSelect.style;
style['opacity'] = '0';
style['filter'] = 'alpha(opacity=0)';
assertEquals(0, bot.dom.getOpacity(singleSelect));
assertFalse(bot.dom.isSelected(singleSelect.options[1]));
expectChanges(singleSelect);
bot.action.click(singleSelect.options[1]);
assertChanges(1);
assertTrue(bot.dom.isSelected(singleSelect.options[1]));
style['opacity'] = '';
style['filter'] = '';
assertEquals(1, bot.dom.getOpacity(singleSelect));
}
var testClickCanSelectOptionFromTransparentSelect =
goog.partial(canSelectOptionFromTransparentSelect, bot.action.click);
var testTapCanSelectOptionFromTransparentSelect =
goog.partial(canSelectOptionFromTransparentSelect, bot.action.tap);
function noErrorAfterSelectWhenOnChangePreventsDefault(action) {
if (!checkActionCompatibility(action) ||
(goog.userAgent.IE && !bot.userAgent.isProductVersion(7))) {
return;
}
goog.events.listen(radioButtons[1], 'change', function(e) {
e.preventDefault();
});
action(radioButtons[1]);
assertTrue(bot.dom.isSelected(radioButtons[1]));
// In IE, this second click used to throw an "Unspecified error".
action(radioButtons[2]);
}
var testClickNoErrorAfterSelectWhenOnChangePreventsDefault =
goog.partial(noErrorAfterSelectWhenOnChangePreventsDefault,
bot.action.click);
var testTapNoErrorAfterSelectWhenOnChangePreventsDefault =
goog.partial(noErrorAfterSelectWhenOnChangePreventsDefault,
bot.action.tap);
function selectOptionTriggersJQueryChangeHandler(action) {
if (!checkActionCompatibility(action)) {
return;
}
var changes = 0;
$('#singleSelect').change(function() {
changes++;
});
action(singleSelect.options[1]);
assertEquals(1, changes);
$('#singleSelect').unbind();
}
var testClickSelectOptionTriggersJQueryChangeHandler =
goog.partial(selectOptionTriggersJQueryChangeHandler, bot.action.click);
var testTapSelectOptionTriggersJQueryChangeHandler =
goog.partial(selectOptionTriggersJQueryChangeHandler, bot.action.tap);
</script>
</head>
<body>
<form action="#" method="get">
<select id="singleSelect">
<option id="singleOption1" value="foo">foo</option>
<option id="singleOption2" value="bar">bar</option>
<option id="singleOption3" value="baz">baz</option>
</select>
<br>
<select id="multiSelect" multiple>
<option id="multiOption1" value="apples">apples</option>
<option id="multiOption2" value="oranges">oranges</option>
<option id="multiOption3" value="cherries">cherries</option>
</select>
<br>
<input type="checkbox" name="checkbox" value="peas">peas
<input type="checkbox" name="checkbox" value="spinach">spinach
<input type="checkbox" name="checkbox" value="broccoli">broccoli
<br>
<input type="radio" name="radio" value="cheese">cheese
<input type="radio" name="radio" value="water">water
<input type="radio" name="radio" value="bread">bread
</form>
</body>
</html>