зеркало из https://github.com/mozilla/pjs.git
bug 443889 - nsIAccessible tests for lists and selects, r=surkov
This commit is contained in:
Родитель
9ed32e4cd4
Коммит
8d580b0555
|
@ -53,6 +53,7 @@ _TEST_FILES =\
|
|||
nsIAccessible_name.css \
|
||||
nsIAccessible_name.js \
|
||||
nsIAccessible_name.xbl \
|
||||
nsIAccessible_selects.js \
|
||||
nsIAccessibleEditableText.js \
|
||||
test_aria_activedescendant.html \
|
||||
test_aria_role_article.html \
|
||||
|
@ -66,6 +67,7 @@ _TEST_FILES =\
|
|||
test_nsIAccessible_actions.xul \
|
||||
test_nsIAccessible_name.html \
|
||||
test_nsIAccessible_name.xul \
|
||||
test_nsIAccessible_selects.html \
|
||||
test_nsIAccessible_focus.html \
|
||||
test_nsIAccessibleDocument.html \
|
||||
test_nsIAccessibleEditableText.html \
|
||||
|
|
|
@ -30,6 +30,28 @@ const nsIObserverService = Components.interfaces.nsIObserverService;
|
|||
|
||||
const nsIDOMNode = Components.interfaces.nsIDOMNode;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Roles
|
||||
const ROLE_COMBOBOX = nsIAccessibleRole.ROLE_COMBOBOX;
|
||||
const ROLE_COMBOBOX_LIST = nsIAccessibleRole.ROLE_COMBOBOX_LIST;
|
||||
const ROLE_COMBOBOX_OPTION = nsIAccessibleRole.ROLE_COMBOBOX_OPTION;
|
||||
const ROLE_LABEL = nsIAccessibleRole.ROLE_LABEL;
|
||||
const ROLE_LIST = nsIAccessibleRole.ROLE_LIST;
|
||||
const ROLE_OPTION = nsIAccessibleRole.ROLE_OPTION;
|
||||
const ROLE_TEXT_LEAF = nsIAccessibleRole.ROLE_TEXT_LEAF;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// States
|
||||
const STATE_COLLAPSED = nsIAccessibleStates.STATE_COLLAPSED;
|
||||
const STATE_EXPANDED = nsIAccessibleStates.STATE_EXPANDED;
|
||||
const STATE_EXTSELECTABLE = nsIAccessibleStates.STATE_EXTSELECTABLE;
|
||||
const STATE_FOCUSABLE = nsIAccessibleStates.STATE_FOCUSABLE;
|
||||
const STATE_FOCUSED = nsIAccessibleStates.STATE_FOCUSED;
|
||||
const STATE_HASPOPUP = nsIAccessibleStates.STATE_HASPOPUP;
|
||||
const STATE_MULTISELECTABLE = nsIAccessibleStates.STATE_MULTISELECTABLE;
|
||||
const STATE_SELECTABLE = nsIAccessibleStates.STATE_SELECTABLE;
|
||||
const STATE_SELECTED = nsIAccessibleStates.STATE_SELECTED;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Accessible general
|
||||
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
/**
|
||||
* Tests an accessible and its children.
|
||||
* The accessible is one of the following:
|
||||
* - HTML:select (ROLE_COMBOBOX)
|
||||
* - HTML:select @size (ROLE_LIST)
|
||||
* - HTML:label containing either of the above (ROLE_LABEL)
|
||||
*
|
||||
* @param aID The ID of the base element to test.
|
||||
* @param aNames The array of expected names for the accessible and
|
||||
* its children.
|
||||
* @param aRoles The array of expected roles for the accessible and
|
||||
* its children.
|
||||
* @param aStates The array of states to test for on each accessible.
|
||||
* @param aUndesiredStates Array of states we don't want to have for each
|
||||
* accessible.
|
||||
*
|
||||
* @note Each of the three arrays must have an equal number of elements. The
|
||||
* order of elements corresponds to the order in which the tree is walked from
|
||||
* the base accessible downwards.
|
||||
*/
|
||||
function testSelect(aID, aNames, aRoles, aStates, aUndesiredStates)
|
||||
{
|
||||
// used to walk the tree starting at the aID's accessible.
|
||||
var acc = getAccessible(aID);
|
||||
if (!acc) {
|
||||
return;
|
||||
}
|
||||
|
||||
testThis(aID, acc, aNames, aRoles, aStates, aUndesiredStates, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a single accessible.
|
||||
* Recursively calls itself until it reaches the last option item.
|
||||
* Called first time from the testSelect function.
|
||||
*
|
||||
* @param aID @see testSelect
|
||||
* @param aAcc The accessible to test.
|
||||
* @param aNames @see testSelect
|
||||
* @param aRoles @see testSelect
|
||||
* @param aStates @see testSelect
|
||||
* @param aUndesiredStates @see testSelect
|
||||
* @param aIndex The index in the three arrays to use. Used for both
|
||||
* the error message and for walking the tree downwards
|
||||
* from the base accessible.
|
||||
*/
|
||||
function testThis(aID, aAcc, aNames, aRoles, aStates, aUndesiredStates, aIndex)
|
||||
{
|
||||
if (aIndex >= aNames.length)
|
||||
return; // End of test
|
||||
else if (!aAcc) {
|
||||
ok(false, "No accessible for " + aID + " at index " + aIndex + "!");
|
||||
return;
|
||||
}
|
||||
|
||||
is(aAcc.name, aNames[aIndex],
|
||||
"wrong name for " + aID + " at index " + aIndex + "!");
|
||||
var role = aAcc.role;
|
||||
is(role, aRoles[aIndex],
|
||||
"Wrong role for " + aID + " at index " + aIndex + "!");
|
||||
testStates(aID, aAcc, aStates, aUndesiredStates, aIndex);
|
||||
switch(role) {
|
||||
case ROLE_COMBOBOX:
|
||||
case ROLE_COMBOBOX_LIST:
|
||||
case ROLE_LABEL:
|
||||
case ROLE_LIST:
|
||||
// All of these expect the next item to be the first child of the current
|
||||
// accessible.
|
||||
var acc = null;
|
||||
try {
|
||||
acc = aAcc.firstChild;
|
||||
} catch(e) {}
|
||||
testThis(aID, acc, aNames, aRoles, aStates, aUndesiredStates, ++aIndex);
|
||||
break;
|
||||
case ROLE_COMBOBOX_OPTION:
|
||||
case ROLE_OPTION:
|
||||
case ROLE_TEXT_LEAF:
|
||||
// All of these expect the next item's accessible to be the next sibling.
|
||||
var acc = null;
|
||||
try {
|
||||
acc = aAcc.nextSibling;
|
||||
} catch(e) {}
|
||||
testThis(aID, acc, aNames, aRoles, aStates, aUndesiredStates, ++aIndex);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the states for the given accessible.
|
||||
* Does not test for extraStates since we don't need these.
|
||||
*
|
||||
* @param aID the ID of the base element.
|
||||
* @param aAcc the current accessible from the recursive algorithm.
|
||||
* @param aStates the states array passed down from the testThis function.
|
||||
* @param aUndesiredStates the array of states we don't want to see, if any.
|
||||
* @param aIndex the index of the item to test, determined and passed in from
|
||||
* the testThis function.
|
||||
*/
|
||||
function testStates(aID, aAcc, aStates, aUndesiredStates, aIndex)
|
||||
{
|
||||
var state = {}, extraState = {};
|
||||
aAcc.getFinalState(state, extraState);
|
||||
if (aStates[aIndex] != 0)
|
||||
is(state.value & aStates[aIndex], aStates[aIndex],
|
||||
"Wrong state bits for " + aID + " at index " + aIndex + "!");
|
||||
if (aUndesiredStates[aIndex] != 0)
|
||||
is(state.value & aUndesiredStates[aIndex], 0,
|
||||
"Wrong undesired state bits for " + aID + " at index " + aIndex + "!");
|
||||
}
|
|
@ -0,0 +1,210 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>nsIAccessible selects tests</title>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/nsIAccessible_selects.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function doTest()
|
||||
{
|
||||
// Label and combo, separate tags
|
||||
var names = [
|
||||
"Foo:", // combobox
|
||||
"Foo:", // combobox list
|
||||
"item 1", // first item
|
||||
"item 2" // second item
|
||||
];
|
||||
var roles = [
|
||||
ROLE_COMBOBOX, // root
|
||||
ROLE_COMBOBOX_LIST, // list accessible
|
||||
ROLE_COMBOBOX_OPTION, // first option
|
||||
ROLE_COMBOBOX_OPTION // second option
|
||||
];
|
||||
var states = [
|
||||
(STATE_FOCUSABLE | STATE_HASPOPUP | STATE_COLLAPSED), // combobox
|
||||
(0), // combobox_list
|
||||
(STATE_SELECTABLE | STATE_SELECTED | STATE_FOCUSABLE | STATE_FOCUSED),
|
||||
(STATE_SELECTABLE | STATE_FOCUSABLE) // second item, not focused
|
||||
];
|
||||
var undesiredStates = [
|
||||
(STATE_FOCUSED), // combobox
|
||||
(STATE_FOCUSED), // combobox_list
|
||||
(0), // first item
|
||||
(STATE_SELECTED | STATE_FOCUSED) // second, not currently focused, item
|
||||
];
|
||||
testSelect("combo1", names, roles, states, undesiredStates);
|
||||
|
||||
// Select nested within label element.
|
||||
// XXX see bug 455482: The accName for the label, combobox, and
|
||||
// combobox_list contains the label text and the names of each option.
|
||||
// When fixing bug 455482, please fix below names and remove this comment.
|
||||
names = [
|
||||
"Search in: Newsticker Entire site", // label
|
||||
"Search in:", // text leaf
|
||||
"Search in: Newsticker Entire site", // combobox
|
||||
"Search in: Newsticker Entire site", // combobox_list
|
||||
"Newsticker", // option 1
|
||||
"Entire site" // Option 2
|
||||
];
|
||||
roles = [
|
||||
ROLE_LABEL, // root
|
||||
ROLE_TEXT_LEAF, // inner text
|
||||
ROLE_COMBOBOX, // combobox accessible
|
||||
ROLE_COMBOBOX_LIST, // list accessible
|
||||
ROLE_COMBOBOX_OPTION, // first option
|
||||
ROLE_COMBOBOX_OPTION // second option
|
||||
];
|
||||
states = [
|
||||
(0), // label
|
||||
(0), // text leaf
|
||||
(STATE_FOCUSABLE | STATE_HASPOPUP | STATE_COLLAPSED), // combobox
|
||||
(0), // combobox_list
|
||||
(STATE_SELECTABLE | STATE_SELECTED | STATE_FOCUSABLE | STATE_FOCUSED),
|
||||
(STATE_SELECTABLE | STATE_FOCUSABLE) // second item, not focused
|
||||
];
|
||||
undesiredStates = [
|
||||
(0), // label
|
||||
(0), // text leaf
|
||||
(STATE_FOCUSED), // combobox
|
||||
(STATE_FOCUSED), // combobox_list
|
||||
(0), // first item
|
||||
(STATE_SELECTED | STATE_FOCUSED) // second, not currently focused, item
|
||||
];
|
||||
testSelect("combo2", names, roles, states, undesiredStates);
|
||||
|
||||
// select @size with label as separate tags.
|
||||
names = [
|
||||
"Component:", // list
|
||||
"Build", // item 1
|
||||
"Disability Access APIs", // item 2
|
||||
"General", // item 3
|
||||
"UI" // item 4
|
||||
];
|
||||
roles = [
|
||||
ROLE_LIST, // root
|
||||
ROLE_OPTION, // item 1
|
||||
ROLE_OPTION, // item 2
|
||||
ROLE_OPTION, // item 4
|
||||
ROLE_OPTION // item 4
|
||||
];
|
||||
states = [
|
||||
(STATE_FOCUSABLE), // list
|
||||
(STATE_SELECTABLE | STATE_FOCUSABLE | STATE_FOCUSED),
|
||||
(STATE_SELECTABLE | STATE_FOCUSABLE), // second item, not focused
|
||||
(STATE_SELECTABLE | STATE_FOCUSABLE), // third item, not focused
|
||||
(STATE_SELECTABLE | STATE_FOCUSABLE) // fourth item, not focused
|
||||
];
|
||||
undesiredStates = [
|
||||
(STATE_FOCUSED), // listbox
|
||||
(STATE_SELECTED), // first item
|
||||
(STATE_SELECTED | STATE_FOCUSED), // second, not currently focused, item
|
||||
(STATE_SELECTED | STATE_FOCUSED), // third, not currently focused, item
|
||||
(STATE_SELECTED | STATE_FOCUSED) // fourth, not currently focused, item
|
||||
];
|
||||
testSelect("list1", names, roles, states, undesiredStates);
|
||||
|
||||
// Select @size nested within label element.
|
||||
// XXX see bug 455482: The accName for the label and listbox
|
||||
// contains the label text and the names of each option.
|
||||
// When fixing bug 455482, please fix below names and remove this comment.
|
||||
names = [
|
||||
"Version: 2.0 3.0 3.1 trunk", // label
|
||||
"Version:", // text leaf
|
||||
"Version: 2.0 3.0 3.1 trunk", // list
|
||||
"2.0", // option 1
|
||||
"3.0", // Option 2
|
||||
"3.1", // Option 3
|
||||
"trunk" // Option 4
|
||||
];
|
||||
roles = [
|
||||
ROLE_LABEL, // root
|
||||
ROLE_TEXT_LEAF, // inner text
|
||||
ROLE_LIST, // listbox accessible
|
||||
ROLE_OPTION, // first option
|
||||
ROLE_OPTION, // second option
|
||||
ROLE_OPTION, // third option
|
||||
ROLE_OPTION // fourth option
|
||||
];
|
||||
states = [
|
||||
(0), // label
|
||||
(0), // text leaf
|
||||
(STATE_FOCUSABLE), // listbox
|
||||
(STATE_SELECTABLE | STATE_FOCUSABLE | STATE_FOCUSED), // Option 1
|
||||
(STATE_SELECTABLE | STATE_FOCUSABLE), // second item, not focused
|
||||
(STATE_SELECTABLE | STATE_FOCUSABLE), // third item, not focused
|
||||
(STATE_SELECTABLE | STATE_FOCUSABLE) // fourth item, not focused
|
||||
];
|
||||
undesiredStates = [
|
||||
(0), // label
|
||||
(0), // text leaf
|
||||
(STATE_FOCUSED | STATE_HASPOPUP | STATE_COLLAPSED), // listbox
|
||||
(STATE_SELECTED), // first item
|
||||
(STATE_SELECTED | STATE_FOCUSED), // second, not currently focused, item
|
||||
(STATE_SELECTED | STATE_FOCUSED), // third, not currently focused, item
|
||||
(STATE_SELECTED | STATE_FOCUSED) // fourth, not currently focused, item
|
||||
];
|
||||
testSelect("list2", names, roles, states, undesiredStates);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(doTest);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=443889"
|
||||
title="mochitest for selects and lists">
|
||||
Mozilla Bug 443889
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<form action="post.php" method="post">
|
||||
<!-- Label and select separate tags -->
|
||||
<label for="combo1">Foo:</label>
|
||||
<select id="combo1" name="combo1">
|
||||
<option>item 1</option>
|
||||
<option>item 2</option>
|
||||
</select><br />
|
||||
|
||||
<!-- Select embedded in label -->
|
||||
<label id="combo2">Search in:<select name="search">
|
||||
<option>Newsticker</option>
|
||||
<option>Entire site</option>
|
||||
</select></label><br />
|
||||
|
||||
<!-- Label and select @size -->
|
||||
<label for="list1">Component:</label>
|
||||
<select id="list1" name="component" size="3">
|
||||
<option>Build</option>
|
||||
<option>Disability Access APIs</option>
|
||||
<option>General</option>
|
||||
<option>UI</option>
|
||||
</select><br />
|
||||
|
||||
<!-- Select @size nested within label -->
|
||||
<label id="list2">Version:<select name="version" size="3">
|
||||
<option>2.0</option>
|
||||
<option>3.0</option>
|
||||
<option>3.1</option>
|
||||
<option>trunk</option>
|
||||
</select></label><br />
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче