diff options
Diffstat (limited to 'toolkit/content/tests/chrome/xul_selectcontrol.js')
-rw-r--r-- | toolkit/content/tests/chrome/xul_selectcontrol.js | 689 |
1 files changed, 689 insertions, 0 deletions
diff --git a/toolkit/content/tests/chrome/xul_selectcontrol.js b/toolkit/content/tests/chrome/xul_selectcontrol.js new file mode 100644 index 0000000000..310ab5c3fa --- /dev/null +++ b/toolkit/content/tests/chrome/xul_selectcontrol.js @@ -0,0 +1,689 @@ +// This script is used to test elements that implement +// nsIDOMXULSelectControlElement. This currently is the following elements: +// listbox, menulist, radiogroup, richlistbox, tabs +// +// flag behaviours that differ for certain elements +// allow-other-value - alternate values for the value property may be used +// besides those in the list +// other-value-clears-selection - alternative values for the value property +// clears the selected item +// selection-required - an item must be selected in the list, unless there +// aren't any to select +// activate-disabled-menuitem - disabled menuitems can be highlighted +// select-keynav-wraps - key navigation over a selectable list wraps +// select-extended-keynav - home, end, page up and page down keys work to +// navigate over a selectable list +// keynav-leftright - key navigation is left/right rather than up/down +// The win:, mac: and gtk: or other prefixes may be used for platform specific behaviour +var behaviours = { + menu: "win:activate-disabled-menuitem activate-disabled-menuitem-mousemove select-keynav-wraps select-extended-keynav", + menulist: "allow-other-value other-value-clears-selection", + listbox: "select-extended-keynav", + richlistbox: "select-extended-keynav", + radiogroup: "select-keynav-wraps dont-select-disabled allow-other-value", + tabs: "select-extended-keynav mac:select-keynav-wraps allow-other-value selection-required keynav-leftright", +}; + +function behaviourContains(tag, behaviour) { + var platform = "none:"; + if (navigator.platform.includes("Mac")) { + platform = "mac:"; + } else if (navigator.platform.includes("Win")) { + platform = "win:"; + } else if (navigator.platform.includes("X")) { + platform = "gtk:"; + } + + var re = new RegExp( + "\\s" + platform + behaviour + "\\s|\\s" + behaviour + "\\s" + ); + return re.test(" " + behaviours[tag] + " "); +} + +function test_nsIDOMXULSelectControlElement(element, childtag, testprefix) { + var testid = testprefix ? testprefix + " " : ""; + testid += element.localName + " nsIDOMXULSelectControlElement "; + + // 'initial' - check if the initial state of the element is correct + test_nsIDOMXULSelectControlElement_States( + element, + testid + "initial", + 0, + null, + -1, + "" + ); + + test_nsIDOMXULSelectControlElement_init(element, testid); + + // 'appendItem' - check if appendItem works to add a new item + var firstitem = element.appendItem("First Item", "first"); + is( + firstitem.localName, + childtag, + testid + "appendItem - first item is " + childtag + ); + test_nsIDOMXULSelectControlElement_States( + element, + testid + "appendItem", + 1, + null, + -1, + "" + ); + + is(firstitem.control, element, testid + "control"); + + // 'selectedIndex' - check if an item may be selected + element.selectedIndex = 0; + test_nsIDOMXULSelectControlElement_States( + element, + testid + "selectedIndex", + 1, + firstitem, + 0, + "first" + ); + + // 'appendItem 2' - check if a second item may be added + var seconditem = element.appendItem("Second Item", "second"); + test_nsIDOMXULSelectControlElement_States( + element, + testid + "appendItem 2", + 2, + firstitem, + 0, + "first" + ); + + // 'selectedItem' - check if the second item may be selected + element.selectedItem = seconditem; + test_nsIDOMXULSelectControlElement_States( + element, + testid + "selectedItem", + 2, + seconditem, + 1, + "second" + ); + + // 'selectedIndex 2' - check if selectedIndex may be set to -1 to deselect items + var selectionRequired = behaviourContains( + element.localName, + "selection-required" + ); + element.selectedIndex = -1; + test_nsIDOMXULSelectControlElement_States( + element, + testid + "selectedIndex 2", + 2, + selectionRequired ? seconditem : null, + selectionRequired ? 1 : -1, + selectionRequired ? "second" : "" + ); + + // 'selectedItem 2' - check if the selectedItem property may be set to null + element.selectedIndex = 1; + element.selectedItem = null; + test_nsIDOMXULSelectControlElement_States( + element, + testid + "selectedItem 2", + 2, + selectionRequired ? seconditem : null, + selectionRequired ? 1 : -1, + selectionRequired ? "second" : "" + ); + + // 'getIndexOfItem' - check if getIndexOfItem returns the right index + is( + element.getIndexOfItem(firstitem), + 0, + testid + "getIndexOfItem - first item at index 0" + ); + is( + element.getIndexOfItem(seconditem), + 1, + testid + "getIndexOfItem - second item at index 1" + ); + + var otheritem = element.ownerDocument.createXULElement(childtag); + is( + element.getIndexOfItem(otheritem), + -1, + testid + "getIndexOfItem - other item not found" + ); + + // 'getItemAtIndex' - check if getItemAtIndex returns the right item + is( + element.getItemAtIndex(0), + firstitem, + testid + "getItemAtIndex - index 0 is first item" + ); + is( + element.getItemAtIndex(1), + seconditem, + testid + "getItemAtIndex - index 0 is second item" + ); + is( + element.getItemAtIndex(-1), + null, + testid + "getItemAtIndex - index -1 is null" + ); + is( + element.getItemAtIndex(2), + null, + testid + "getItemAtIndex - index 2 is null" + ); + + // check if setting the value changes the selection + element.value = "first"; + test_nsIDOMXULSelectControlElement_States( + element, + testid + "set value 1", + 2, + firstitem, + 0, + "first" + ); + element.value = "second"; + test_nsIDOMXULSelectControlElement_States( + element, + testid + "set value 2", + 2, + seconditem, + 1, + "second" + ); + // setting the value attribute to one not in the list doesn't change the selection. + // The value is only changed for elements which support having a value other than the + // selection. + element.value = "other"; + var allowOtherValue = behaviourContains( + element.localName, + "allow-other-value" + ); + var otherValueClearsSelection = behaviourContains( + element.localName, + "other-value-clears-selection" + ); + test_nsIDOMXULSelectControlElement_States( + element, + testid + "set value other", + 2, + otherValueClearsSelection ? null : seconditem, + otherValueClearsSelection ? -1 : 1, + allowOtherValue ? "other" : "second" + ); + if (allowOtherValue) { + element.value = ""; + } + + var fourthitem = element.appendItem("Fourth Item", "fourth"); + element.selectedIndex = 0; + fourthitem.disabled = true; + element.selectedIndex = 2; + test_nsIDOMXULSelectControlElement_States( + element, + testid + "selectedIndex disabled", + 3, + fourthitem, + 2, + "fourth" + ); + + element.selectedIndex = 0; + element.selectedItem = fourthitem; + test_nsIDOMXULSelectControlElement_States( + element, + testid + "selectedItem disabled", + 3, + fourthitem, + 2, + "fourth" + ); + + if (element.menupopup) { + element.menupopup.textContent = ""; + } else { + element.textContent = ""; + } +} + +function test_nsIDOMXULSelectControlElement_init(element, testprefix) { + var id = element.id; + element = document.getElementById(id + "-initwithvalue"); + if (element) { + var seconditem = element.getItemAtIndex(1); + test_nsIDOMXULSelectControlElement_States( + element, + testprefix + " value initialization", + 3, + seconditem, + 1, + seconditem.value + ); + } + + element = document.getElementById(id + "-initwithselected"); + if (element) { + var thirditem = element.getItemAtIndex(2); + test_nsIDOMXULSelectControlElement_States( + element, + testprefix + " selected initialization", + 3, + thirditem, + 2, + thirditem.value + ); + } +} + +function test_nsIDOMXULSelectControlElement_States( + element, + testid, + expectedcount, + expecteditem, + expectedindex, + expectedvalue +) { + // need an itemCount property here + var count = element.itemCount; + is(count, expectedcount, testid + " item count"); + is(element.selectedItem, expecteditem, testid + " selectedItem"); + is(element.selectedIndex, expectedindex, testid + " selectedIndex"); + is(element.value, expectedvalue, testid + " value"); + if (element.selectedItem) { + is( + element.selectedItem.selected, + true, + testid + " selectedItem marked as selected" + ); + } +} + +/** test_nsIDOMXULSelectControlElement_UI + * + * Test the UI aspects of an element which implements nsIDOMXULSelectControlElement + * + * Parameters: + * element - element to test + */ +function test_nsIDOMXULSelectControlElement_UI(element, testprefix) { + var testid = testprefix ? testprefix + " " : ""; + testid += element.localName + " nsIDOMXULSelectControlElement UI "; + + if (element.menupopup) { + element.menupopup.textContent = ""; + } else { + element.textContent = ""; + } + + var firstitem = element.appendItem("First Item", "first"); + var seconditem = element.appendItem("Second Item", "second"); + + // 'mouse select' - check if clicking an item selects it + synthesizeMouseExpectEvent( + firstitem, + 2, + 2, + {}, + element, + "select", + testid + "mouse select" + ); + test_nsIDOMXULSelectControlElement_States( + element, + testid + "mouse select", + 2, + firstitem, + 0, + "first" + ); + + synthesizeMouseExpectEvent( + seconditem, + 2, + 2, + {}, + element, + "select", + testid + "mouse select 2" + ); + test_nsIDOMXULSelectControlElement_States( + element, + testid + "mouse select 2", + 2, + seconditem, + 1, + "second" + ); + + // make sure the element is focused so keyboard navigation will apply + element.selectedIndex = 1; + element.focus(); + + var navLeftRight = behaviourContains(element.localName, "keynav-leftright"); + var backKey = navLeftRight ? "VK_LEFT" : "VK_UP"; + var forwardKey = navLeftRight ? "VK_RIGHT" : "VK_DOWN"; + + // 'key select' - check if keypresses move between items + synthesizeKeyExpectEvent(backKey, {}, element, "select", testid + "key up"); + test_nsIDOMXULSelectControlElement_States( + element, + testid + "key up", + 2, + firstitem, + 0, + "first" + ); + + var keyWrap = behaviourContains(element.localName, "select-keynav-wraps"); + + var expectedItem = keyWrap ? seconditem : firstitem; + var expectedIndex = keyWrap ? 1 : 0; + var expectedValue = keyWrap ? "second" : "first"; + synthesizeKeyExpectEvent( + backKey, + {}, + keyWrap ? element : null, + "select", + testid + "key up 2" + ); + test_nsIDOMXULSelectControlElement_States( + element, + testid + "key up 2", + 2, + expectedItem, + expectedIndex, + expectedValue + ); + + element.selectedIndex = 0; + synthesizeKeyExpectEvent( + forwardKey, + {}, + element, + "select", + testid + "key down" + ); + test_nsIDOMXULSelectControlElement_States( + element, + testid + "key down", + 2, + seconditem, + 1, + "second" + ); + + expectedItem = keyWrap ? firstitem : seconditem; + expectedIndex = keyWrap ? 0 : 1; + expectedValue = keyWrap ? "first" : "second"; + synthesizeKeyExpectEvent( + forwardKey, + {}, + keyWrap ? element : null, + "select", + testid + "key down 2" + ); + test_nsIDOMXULSelectControlElement_States( + element, + testid + "key down 2", + 2, + expectedItem, + expectedIndex, + expectedValue + ); + + var thirditem = element.appendItem("Third Item", "third"); + var fourthitem = element.appendItem("Fourth Item", "fourth"); + if (behaviourContains(element.localName, "select-extended-keynav")) { + element.appendItem("Fifth Item", "fifth"); + var sixthitem = element.appendItem("Sixth Item", "sixth"); + + synthesizeKeyExpectEvent( + "VK_END", + {}, + element, + "select", + testid + "key end" + ); + test_nsIDOMXULSelectControlElement_States( + element, + testid + "key end", + 6, + sixthitem, + 5, + "sixth" + ); + + synthesizeKeyExpectEvent( + "VK_HOME", + {}, + element, + "select", + testid + "key home" + ); + test_nsIDOMXULSelectControlElement_States( + element, + testid + "key home", + 6, + firstitem, + 0, + "first" + ); + + synthesizeKeyExpectEvent( + "VK_PAGE_DOWN", + {}, + element, + "select", + testid + "key page down" + ); + test_nsIDOMXULSelectControlElement_States( + element, + testid + "key page down", + 6, + fourthitem, + 3, + "fourth" + ); + synthesizeKeyExpectEvent( + "VK_PAGE_DOWN", + {}, + element, + "select", + testid + "key page down to end" + ); + test_nsIDOMXULSelectControlElement_States( + element, + testid + "key page down to end", + 6, + sixthitem, + 5, + "sixth" + ); + + synthesizeKeyExpectEvent( + "VK_PAGE_UP", + {}, + element, + "select", + testid + "key page up" + ); + test_nsIDOMXULSelectControlElement_States( + element, + testid + "key page up", + 6, + thirditem, + 2, + "third" + ); + synthesizeKeyExpectEvent( + "VK_PAGE_UP", + {}, + element, + "select", + testid + "key page up to start" + ); + test_nsIDOMXULSelectControlElement_States( + element, + testid + "key page up to start", + 6, + firstitem, + 0, + "first" + ); + + element.getItemAtIndex(5).remove(); + element.getItemAtIndex(4).remove(); + } + + // now test whether a disabled item works. + element.selectedIndex = 0; + seconditem.disabled = true; + + var dontSelectDisabled = behaviourContains( + element.localName, + "dont-select-disabled" + ); + + // 'mouse select' - check if clicking an item selects it + synthesizeMouseExpectEvent( + seconditem, + 2, + 2, + {}, + element, + dontSelectDisabled ? "!select" : "select", + testid + "mouse select disabled" + ); + test_nsIDOMXULSelectControlElement_States( + element, + testid + "mouse select disabled", + 4, + dontSelectDisabled ? firstitem : seconditem, + dontSelectDisabled ? 0 : 1, + dontSelectDisabled ? "first" : "second" + ); + + if (dontSelectDisabled) { + // test whether disabling an item won't allow it to be selected + synthesizeKeyExpectEvent( + forwardKey, + {}, + element, + "select", + testid + "key down disabled" + ); + test_nsIDOMXULSelectControlElement_States( + element, + testid + "key down disabled", + 4, + thirditem, + 2, + "third" + ); + + synthesizeKeyExpectEvent( + backKey, + {}, + element, + "select", + testid + "key up disabled" + ); + test_nsIDOMXULSelectControlElement_States( + element, + testid + "key up disabled", + 4, + firstitem, + 0, + "first" + ); + + element.selectedIndex = 2; + firstitem.disabled = true; + + synthesizeKeyExpectEvent( + backKey, + {}, + keyWrap ? element : null, + "select", + testid + "key up disabled 2" + ); + expectedItem = keyWrap ? fourthitem : thirditem; + expectedIndex = keyWrap ? 3 : 2; + expectedValue = keyWrap ? "fourth" : "third"; + test_nsIDOMXULSelectControlElement_States( + element, + testid + "key up disabled 2", + 4, + expectedItem, + expectedIndex, + expectedValue + ); + } else { + // in this case, disabled items should behave the same as non-disabled items. + element.selectedIndex = 0; + synthesizeKeyExpectEvent( + forwardKey, + {}, + element, + "select", + testid + "key down disabled" + ); + test_nsIDOMXULSelectControlElement_States( + element, + testid + "key down disabled", + 4, + seconditem, + 1, + "second" + ); + synthesizeKeyExpectEvent( + forwardKey, + {}, + element, + "select", + testid + "key down disabled again" + ); + test_nsIDOMXULSelectControlElement_States( + element, + testid + "key down disabled again", + 4, + thirditem, + 2, + "third" + ); + + synthesizeKeyExpectEvent( + backKey, + {}, + element, + "select", + testid + "key up disabled" + ); + test_nsIDOMXULSelectControlElement_States( + element, + testid + "key up disabled", + 4, + seconditem, + 1, + "second" + ); + synthesizeKeyExpectEvent( + backKey, + {}, + element, + "select", + testid + "key up disabled again" + ); + test_nsIDOMXULSelectControlElement_States( + element, + testid + "key up disabled again", + 4, + firstitem, + 0, + "first" + ); + } +} |