blob: de5a6e698df0fb0571d37cba220dc02a8baaa8a4 [file] [log] [blame] [edit]
<!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.events');
goog.require('goog.testing.jsunit');
goog.require('goog.userAgent');
</script>
<script type="text/javascript">
var singleSelect, multiSelect, radioButtons, checkboxes, changeCount;
var gotPointerCaptureCount, lostPointerCaptureCount;
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);
goog.events.removeAll(multiSelect);
for (var i = 0; i < checkboxes.length; ++i) {
goog.events.removeAll(checkboxes[i]);
}
for (var i = 0; i < radioButtons.length; ++i) {
goog.events.removeAll(radioButtons[i]);
}
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 expectPointerCaptures(target) {
gotPointerCaptureCount = 0;
lostPointerCaptureCount = 0;
goog.events.listen(target, goog.events.EventType.MSGOTPOINTERCAPTURE,
function (e) {
gotPointerCaptureCount++;
});
goog.events.listen(target, goog.events.EventType.MSLOSTPOINTERCAPTURE,
function (e) {
lostPointerCaptureCount++;
});
}
function assertPointerCaptures(expectedCount) {
assertEquals('Unexpected number of got captures', expectedCount,
gotPointerCaptureCount);
assertEquals('Unexpected number of lost captures', expectedCount,
lostPointerCaptureCount);
}
function canSelectAnOptionFromASingleSelect(action) {
if (!checkActionCompatibility(action)) {
return;
}
assertFalse(bot.dom.isSelected(singleSelect.options[1]));
expectChanges(singleSelect);
if (bot.userAgent.IE_DOC_10) {
expectPointerCaptures(singleSelect);
}
action(singleSelect.options[1]);
assertChanges(1);
if (bot.userAgent.IE_DOC_10) {
assertPointerCaptures(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 =
// Disabled on Chrome due to
// https://code.google.com/p/chromedriver/issues/detail?id=1073
// Disabled on Safari due to
// https://github.com/SeleniumHQ/selenium/issues/461
(goog.userAgent.product.CHROME || goog.userAgent.product.SAFARI) ?
goog.nullFunction :
goog.partial(canToggleOptionsInAMultiSelect, bot.action.click);
var testTapCanToggleOptionsInAMultiSelect =
// Disabled on Chrome due to
// https://code.google.com/p/chromedriver/issues/detail?id=1073
// Disabled on Safari due to
// https://github.com/SeleniumHQ/selenium/issues/461
(goog.userAgent.product.CHROME || goog.userAgent.product.SAFARI) ?
goog.nullFunction :
goog.partial(canToggleOptionsInAMultiSelect, bot.action.tap);
function canToggleCheckboxes(action) {
if (!checkActionCompatibility(action)) {
return;
}
// IE <= 8 fires a change event on the next click after the change.
checkboxes[0].checked = true;
expectChanges(checkboxes[0]);
action(checkboxes[0]);
assertChanges(1);
if (!bot.userAgent.IE_DOC_PRE9) {
expectChanges(checkboxes[1]);
}
action(checkboxes[1]);
assertChanges(1);
expectChanges(checkboxes[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 <= 8 fires a change event on the next click after the change.
expectChanges(radioButtons[0]);
action(radioButtons[0]);
assertChanges(1);
assertTrue(bot.dom.isSelected(radioButtons[0]));
if (!bot.userAgent.IE_DOC_PRE9) {
expectChanges(radioButtons[1]);
}
action(radioButtons[1]);
assertChanges(1);
assertTrue(bot.dom.isSelected(radioButtons[1]));
expectChanges(radioButtons[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 =
// Disabled on Safari due to
// https://github.com/SeleniumHQ/selenium/issues/461
goog.userAgent.product.SAFARI ?
goog.nullFunction :
goog.partial(canSelectOptionWhenDefaultPrevented, bot.action.click);
var testTapCanSelectOptionWhenDefaultPrevented =
// Disabled on Chrome due to
// https://code.google.com/p/chromedriver/issues/detail?id=1073
// Disabled on Safari due to
// https://github.com/SeleniumHQ/selenium/issues/461
(goog.userAgent.product.CHROME || goog.userAgent.product.SAFARI) ?
goog.nullFunction :
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);
// Some browsers fire change events when the checkbox isn't toggled.
assertChanges(firesChangeEventIfNotToggled() ? 1 : 0);
assertFalse(bot.dom.isSelected(elem));
}
function firesChangeEventIfNotToggled() {
if (goog.userAgent.product.CHROME && bot.userAgent.isProductVersion(45)) {
// Chrome 45 and above do not fire the change event.
return false;
} else if (goog.userAgent.WEBKIT || bot.userAgent.IE_DOC_9 ||
goog.userAgent.EDGE) {
// Other browsers with goog.userAgent.WEBKIT fire the change event.
// IE 9 standards mode fires the change event.
return true;
}
// All other browsers do not fire the change event.
return false;
}
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);
// Chrome < 39 and WebKit select a radio button even when the handler
// prevents the default; IE does not.
if ((goog.userAgent.product.CHROME &&
!bot.userAgent.isProductVersion(39)) ||
(goog.userAgent.WEBKIT && !goog.userAgent.product.CHROME)) {
assertChanges(1);
assertTrue(bot.dom.isSelected(elem));
} else {
// Some browsers fire change events when the checkbox isn't toggled.
assertChanges(firesChangeEventIfNotToggled() ? 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);
function pointerCaptureFiresOnCheckboxToggle(action) {
if (!bot.userAgent.IE_DOC_10) {
return;
}
checkboxes[0].checked = true;
expectPointerCaptures(checkboxes[0]);
action(checkboxes[0]);
// For input elements, the got/lost pointer capture events only fire for
// a tap and not for mouse clicks.
if (action == bot.action.tap) {
assertPointerCaptures(1);
} else {
assertPointerCaptures(0);
}
assertFalse(bot.dom.isSelected(checkboxes[0]));
}
var testClickPointerCaptureFiresOnCheckboxToggle =
goog.partial(pointerCaptureFiresOnCheckboxToggle, bot.action.click);
var testTapPointerCaptureFiresOnCheckboxToggle =
goog.partial(pointerCaptureFiresOnCheckboxToggle, bot.action.tap);
function togglesByTheTimeChangeEventFires(action) {
if (!checkActionCompatibility(action)) {
return;
}
singleSelect.options[0].selected = true;
checkToggleAtChange(action, singleSelect, singleSelect.options[1]);
multiSelect.options[0].selected = false;
checkToggleAtChange(action, multiSelect, multiSelect.options[0]);
radioButtons[0].checked = false;
checkToggleAtChange(action, radioButtons[0], radioButtons[0]);
checkboxes[0].checked = false;
checkToggleAtChange(action, checkboxes[0], checkboxes[0]);
function checkToggleAtChange(action, targetElem, toggleElem) {
var preState = bot.dom.isSelected(toggleElem);
var postState = null;
goog.events.listen(targetElem, 'change', function (e) {
postState = bot.dom.isSelected(toggleElem);
});
action(toggleElem);
assertNotNull('change event did not fire', postState);
assertNotEquals('element did not toggle', postState, preState);
}
}
var testClickTogglesByTheTimeChangeEventFires =
// Disabled on Safari due to
// https://github.com/SeleniumHQ/selenium/issues/461
goog.userAgent.product.SAFARI ?
goog.nullFunction :
goog.partial(togglesByTheTimeChangeEventFires, bot.action.click);
var testTapTogglesByTheTimeChangeEventFires =
// Disabled on Chrome due to
// https://code.google.com/p/chromedriver/issues/detail?id=1073
// Disabled on Safari due to
// https://github.com/SeleniumHQ/selenium/issues/461
(goog.userAgent.product.CHROME || goog.userAgent.product.SAFARI) ?
goog.nullFunction :
goog.partial(togglesByTheTimeChangeEventFires, 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>