bug 443889 - nsIAccessible tests for lists and selects, r=surkov

This commit is contained in:
Marco Zehe 2008-09-18 09:25:09 +02:00
Родитель 9ed32e4cd4
Коммит 8d580b0555
4 изменённых файлов: 345 добавлений и 0 удалений

Просмотреть файл

@ -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>