diff options
Diffstat (limited to '')
30 files changed, 3465 insertions, 0 deletions
diff --git a/accessible/tests/mochitest/states.js b/accessible/tests/mochitest/states.js new file mode 100644 index 0000000000..8e394b11a1 --- /dev/null +++ b/accessible/tests/mochitest/states.js @@ -0,0 +1,363 @@ +// ////////////////////////////////////////////////////////////////////////////// +// Helper functions for accessible states testing. +// +// requires: +// common.js +// role.js +// +// ////////////////////////////////////////////////////////////////////////////// +/* import-globals-from common.js */ +/* import-globals-from role.js */ + +// ////////////////////////////////////////////////////////////////////////////// +// State constants + +// const STATE_BUSY is defined in common.js +const STATE_CHECKED = nsIAccessibleStates.STATE_CHECKED; +const STATE_CHECKABLE = nsIAccessibleStates.STATE_CHECKABLE; +const STATE_COLLAPSED = nsIAccessibleStates.STATE_COLLAPSED; +const STATE_DEFAULT = nsIAccessibleStates.STATE_DEFAULT; +const STATE_EXPANDED = nsIAccessibleStates.STATE_EXPANDED; +const STATE_EXTSELECTABLE = nsIAccessibleStates.STATE_EXTSELECTABLE; +const STATE_FLOATING = nsIAccessibleStates.STATE_FLOATING; +const STATE_FOCUSABLE = nsIAccessibleStates.STATE_FOCUSABLE; +const STATE_FOCUSED = nsIAccessibleStates.STATE_FOCUSED; +const STATE_HASPOPUP = nsIAccessibleStates.STATE_HASPOPUP; +const STATE_INVALID = nsIAccessibleStates.STATE_INVALID; +const STATE_INVISIBLE = nsIAccessibleStates.STATE_INVISIBLE; +const STATE_LINKED = nsIAccessibleStates.STATE_LINKED; +const STATE_MIXED = nsIAccessibleStates.STATE_MIXED; +const STATE_MULTISELECTABLE = nsIAccessibleStates.STATE_MULTISELECTABLE; +const STATE_OFFSCREEN = nsIAccessibleStates.STATE_OFFSCREEN; +const STATE_PRESSED = nsIAccessibleStates.STATE_PRESSED; +const STATE_PROTECTED = nsIAccessibleStates.STATE_PROTECTED; +const STATE_READONLY = nsIAccessibleStates.STATE_READONLY; +const STATE_REQUIRED = nsIAccessibleStates.STATE_REQUIRED; +const STATE_SELECTABLE = nsIAccessibleStates.STATE_SELECTABLE; +const STATE_SELECTED = nsIAccessibleStates.STATE_SELECTED; +const STATE_TRAVERSED = nsIAccessibleStates.STATE_TRAVERSED; +const STATE_UNAVAILABLE = nsIAccessibleStates.STATE_UNAVAILABLE; + +const EXT_STATE_ACTIVE = nsIAccessibleStates.EXT_STATE_ACTIVE; +const EXT_STATE_CURRENT = nsIAccessibleStates.EXT_STATE_CURRENT; +const EXT_STATE_DEFUNCT = nsIAccessibleStates.EXT_STATE_DEFUNCT; +const EXT_STATE_EDITABLE = nsIAccessibleStates.EXT_STATE_EDITABLE; +const EXT_STATE_ENABLED = nsIAccessibleStates.EXT_STATE_ENABLED; +const EXT_STATE_EXPANDABLE = nsIAccessibleStates.EXT_STATE_EXPANDABLE; +const EXT_STATE_HORIZONTAL = nsIAccessibleStates.EXT_STATE_HORIZONTAL; +const EXT_STATE_MODAL = nsIAccessibleStates.EXT_STATE_MODAL; +const EXT_STATE_MULTI_LINE = nsIAccessibleStates.EXT_STATE_MULTI_LINE; +const EXT_STATE_PINNED = nsIAccessibleStates.EXT_STATE_PINNED; +const EXT_STATE_SENSITIVE = nsIAccessibleStates.EXT_STATE_SENSITIVE; +const EXT_STATE_SINGLE_LINE = nsIAccessibleStates.EXT_STATE_SINGLE_LINE; +const EXT_STATE_STALE = nsIAccessibleStates.EXT_STATE_STALE; +const EXT_STATE_SUPPORTS_AUTOCOMPLETION = + nsIAccessibleStates.EXT_STATE_SUPPORTS_AUTOCOMPLETION; +const EXT_STATE_VERTICAL = nsIAccessibleStates.EXT_STATE_VERTICAL; +const EXT_STATE_SELECTABLE_TEXT = nsIAccessibleStates.EXT_STATE_SELECTABLE_TEXT; + +const kOrdinalState = false; +const kExtraState = 1; + +// ////////////////////////////////////////////////////////////////////////////// +// Test functions + +/** + * Tests the states and extra states of the given accessible. + * Also tests for unwanted states and extra states. + * In addition, the function performs a few plausibility checks derived from the + * sstates and extra states passed in. + * + * @param aAccOrElmOrID The accessible, DOM element or ID to be tested. + * @param aState The state bits that are wanted. + * @param aExtraState The extra state bits that are wanted. + * @param aAbsentState State bits that are not wanted. + * @param aAbsentExtraState Extra state bits that are not wanted. + * @param aTestName The test name. + */ +function testStates( + aAccOrElmOrID, + aState, + aExtraState, + aAbsentState, + aAbsentExtraState, + aTestName +) { + var [state, extraState] = getStates(aAccOrElmOrID); + var role = getRole(aAccOrElmOrID); + var id = + prettyName(aAccOrElmOrID) + (aTestName ? " [" + aTestName + "]" : ""); + + // Primary test. + if (aState) { + isState(state & aState, aState, false, "wrong state bits for " + id + "!"); + } + + if (aExtraState) { + isState( + extraState & aExtraState, + aExtraState, + true, + "wrong extra state bits for " + id + "!" + ); + } + + if (aAbsentState) { + isState( + state & aAbsentState, + 0, + false, + "state bits should not be present in ID " + id + "!" + ); + } + + if (aAbsentExtraState) { + isState( + extraState & aAbsentExtraState, + 0, + true, + "extraState bits should not be present in ID " + id + "!" + ); + } + + // Additional test. + + // focused/focusable + if (state & STATE_FOCUSED) { + isState( + state & STATE_FOCUSABLE, + STATE_FOCUSABLE, + false, + "Focussed " + id + " must be focusable!" + ); + } + + if (aAbsentState && aAbsentState & STATE_FOCUSABLE) { + isState( + state & STATE_FOCUSED, + 0, + false, + "Not focusable " + id + " must be not focused!" + ); + } + + // multiline/singleline + if (extraState & EXT_STATE_MULTI_LINE) { + isState( + extraState & EXT_STATE_SINGLE_LINE, + 0, + true, + "Multiline " + id + " cannot be singleline!" + ); + } + + if (extraState & EXT_STATE_SINGLE_LINE) { + isState( + extraState & EXT_STATE_MULTI_LINE, + 0, + true, + "Singleline " + id + " cannot be multiline!" + ); + } + + // expanded/collapsed/expandable + if (state & STATE_COLLAPSED || state & STATE_EXPANDED) { + isState( + extraState & EXT_STATE_EXPANDABLE, + EXT_STATE_EXPANDABLE, + true, + "Collapsed or expanded " + id + " must be expandable!" + ); + } + + if (state & STATE_COLLAPSED) { + isState( + state & STATE_EXPANDED, + 0, + false, + "Collapsed " + id + " cannot be expanded!" + ); + } + + if (state & STATE_EXPANDED) { + isState( + state & STATE_COLLAPSED, + 0, + false, + "Expanded " + id + " cannot be collapsed!" + ); + } + + if (aAbsentState && extraState & EXT_STATE_EXPANDABLE) { + if (aAbsentState & STATE_EXPANDED) { + isState( + state & STATE_COLLAPSED, + STATE_COLLAPSED, + false, + "Not expanded " + id + " must be collapsed!" + ); + } else if (aAbsentState & STATE_COLLAPSED) { + isState( + state & STATE_EXPANDED, + STATE_EXPANDED, + false, + "Not collapsed " + id + " must be expanded!" + ); + } + } + + // checked/mixed/checkable + if ( + state & STATE_CHECKED || + (state & STATE_MIXED && + role != ROLE_TOGGLE_BUTTON && + role != ROLE_PROGRESSBAR) + ) { + isState( + state & STATE_CHECKABLE, + STATE_CHECKABLE, + false, + "Checked or mixed element must be checkable!" + ); + } + + if (state & STATE_CHECKED) { + isState( + state & STATE_MIXED, + 0, + false, + "Checked element cannot be state mixed!" + ); + } + + if (state & STATE_MIXED) { + isState( + state & STATE_CHECKED, + 0, + false, + "Mixed element cannot be state checked!" + ); + } + + // selected/selectable + if (state & STATE_SELECTED && !(aAbsentState & STATE_SELECTABLE)) { + isState( + state & STATE_SELECTABLE, + STATE_SELECTABLE, + false, + "Selected element must be selectable!" + ); + } +} + +/** + * Tests an accessible and its sub tree for the passed in state bits. + * Used to make sure that states are propagated to descendants, for example the + * STATE_UNAVAILABLE from a container to its children. + * + * @param aAccOrElmOrID The accessible, DOM element or ID to be tested. + * @param aState The state bits that are wanted. + * @param aExtraState The extra state bits that are wanted. + * @param aAbsentState State bits that are not wanted. + */ +function testStatesInSubtree(aAccOrElmOrID, aState, aExtraState, aAbsentState) { + // test accessible and its subtree for propagated states. + var acc = getAccessible(aAccOrElmOrID); + if (!acc) { + return; + } + + if (getRole(acc) != ROLE_TEXT_LEAF) { + // Right now, text leafs don't get tested because the states are not being + // propagated. + testStates(acc, aState, aExtraState, aAbsentState); + } + + // Iterate over its children to see if the state got propagated. + var children = null; + try { + children = acc.children; + } catch (e) {} + ok(children, "Could not get children for " + aAccOrElmOrID + "!"); + + if (children) { + for (var i = 0; i < children.length; i++) { + var childAcc = children.queryElementAt(i, nsIAccessible); + testStatesInSubtree(childAcc, aState, aExtraState, aAbsentState); + } + } +} + +/** + * Fails if no defunct state on the accessible. + */ +function testIsDefunct(aAccessible, aTestName) { + var id = prettyName(aAccessible) + (aTestName ? " [" + aTestName + "]" : ""); + var [, /* state*/ extraState] = getStates(aAccessible); + isState( + extraState & EXT_STATE_DEFUNCT, + EXT_STATE_DEFUNCT, + true, + "no defuct state for " + id + "!" + ); +} + +function getStringStates(aAccOrElmOrID) { + var [state, extraState] = getStates(aAccOrElmOrID); + return statesToString(state, extraState); +} + +function getStates(aAccOrElmOrID) { + var acc = getAccessible(aAccOrElmOrID); + if (!acc) { + return [0, 0]; + } + + var state = {}, + extraState = {}; + acc.getState(state, extraState); + + return [state.value, extraState.value]; +} + +/** + * Return true if the accessible has given states. + */ +function hasState(aAccOrElmOrID, aState, aExtraState) { + var [state, exstate] = getStates(aAccOrElmOrID); + return ( + (aState ? state & aState : true) && + (aExtraState ? exstate & aExtraState : true) + ); +} + +// ////////////////////////////////////////////////////////////////////////////// +// Private implementation details + +/** + * Analogy of SimpleTest.is function used to compare states. + */ +function isState(aState1, aState2, aIsExtraStates, aMsg) { + if (aState1 == aState2) { + ok(true, aMsg); + return; + } + + var got = "0"; + if (aState1) { + got = statesToString( + aIsExtraStates ? 0 : aState1, + aIsExtraStates ? aState1 : 0 + ); + } + + var expected = "0"; + if (aState2) { + expected = statesToString( + aIsExtraStates ? 0 : aState2, + aIsExtraStates ? aState2 : 0 + ); + } + + ok(false, aMsg + "got '" + got + "', expected '" + expected + "'"); +} diff --git a/accessible/tests/mochitest/states/a11y.ini b/accessible/tests/mochitest/states/a11y.ini new file mode 100644 index 0000000000..06e7a5a061 --- /dev/null +++ b/accessible/tests/mochitest/states/a11y.ini @@ -0,0 +1,36 @@ +[DEFAULT] +support-files = + z_frames.html + z_frames_article.html + z_frames_checkbox.html + z_frames_textbox.html + z_frames_update.html + !/accessible/tests/mochitest/*.js + !/accessible/tests/mochitest/dumbfile.zip + !/accessible/tests/mochitest/formimage.png + !/accessible/tests/mochitest/treeview.css + +[test_aria.html] +[test_aria.xhtml] +[test_aria_imgmap.html] +[test_aria_widgetitems.html] +[test_buttons.html] +[test_controls.html] +[test_controls.xhtml] +[test_doc.html] +[test_doc_busy.html] +[test_docarticle.html] +[test_editablebody.html] +[test_expandable.xhtml] +[test_frames.html] +[test_inputs.html] +[test_link.html] +[test_popup.xhtml] +[test_selects.html] +[test_stale.html] +[test_tabs.xhtml] +[test_textbox.xhtml] +[test_tree.xhtml] +[test_visibility.html] +[test_visibility.xhtml] +skip-if = asan # Bug 1199631 diff --git a/accessible/tests/mochitest/states/test_aria.html b/accessible/tests/mochitest/states/test_aria.html new file mode 100644 index 0000000000..da5df6fa09 --- /dev/null +++ b/accessible/tests/mochitest/states/test_aria.html @@ -0,0 +1,655 @@ +<html> + +<head> + <title>ARIA based nsIAccessible states testing</title> + + <link rel="stylesheet" type="text/css" + href="chrome://mochikit/content/tests/SimpleTest/test.css" /> + + <style type="text/css"> + .offscreen { + position: absolute; + left: -5000px; + top: -5000px; + height: 100px; + width: 100px; + } + </style> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <script type="application/javascript" + src="../common.js"></script> + <script type="application/javascript" + src="../role.js"></script> + <script type="application/javascript" + src="../states.js"></script> + + <script type="application/javascript"> + function testAriaDisabledTree(aAccOrElmOrID) { + // test accessible and its subtree for propagated state. + var acc = getAccessible(aAccOrElmOrID); + if (!acc) + return; + + var [state /* extraState */] = getStates(aAccOrElmOrID); + if (state & STATE_UNAVAILABLE) { + var role = getRole(acc); + if (role != ROLE_GROUPING) { + testStates(acc, STATE_FOCUSABLE); + } + } + + // Iterate over its children to see if the state got propagated. + var children = null; + try { + children = acc.children; + } catch (e) {} + ok(children, "Could not get children for " + aAccOrElmOrID + "!"); + + if (children) { + for (var i = 0; i < children.length; i++) { + var childAcc = children.queryElementAt(i, nsIAccessible); + testAriaDisabledTree(childAcc); + } + } + } + + function doTest() { + // aria_autocomplete + testStates("textbox_autocomplete_inline", 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION); + testStates("textbox_autocomplete_list", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION); + testStates("textbox_autocomplete_both", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION); + testStates("combobox_autocomplete_inline", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION); + testStates("combobox_autocomplete_list", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION); + testStates("combobox_autocomplete_both", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION); + + testStates("htmltext_autocomplete_list", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION); + testStates("htmltextarea_autocomplete_list", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION); + + // aria-busy + testStates("textbox_busy_false", 0, 0, STATE_BUSY); + testStates("textbox_busy_true", STATE_BUSY); + testStates("textbox_busy_error", STATE_INVALID); + + // aria-expanded + testStates("combobox", STATE_COLLAPSED); + testStates("combobox_expanded", STATE_EXPANDED); + + // tri-state checkbox + var checkboxElem = getNode("check1"); + if (checkboxElem) { + testStates(checkboxElem, STATE_CHECKED); + checkboxElem.checked = false; + testStates(checkboxElem, 0, 0, STATE_CHECKED); + checkboxElem.indeterminate = true; + testStates(checkboxElem, STATE_MIXED, 0); + } + + // aria-checked + testStates("aria_checked_checkbox", STATE_CHECKED); + testStates("aria_mixed_checkbox", STATE_MIXED); + testStates("aria_checked_switch", STATE_CHECKED); + testStates("aria_mixed_switch", 0, 0, STATE_MIXED); // unsupported + testStates("aria_mixed_switch", 0, 0, STATE_CHECKED); // not checked due to being unsupported + + // test disabled group and all its descendants to see if they are + // disabled, too. See bug 429285. + testAriaDisabledTree("group"); + + // aria-modal + testStates("aria_modal", 0, EXT_STATE_MODAL); + testStates("aria_modal_false", 0, 0, 0, EXT_STATE_MODAL); + + // aria-multiline + testStates("aria_multiline_textbox", 0, EXT_STATE_MULTI_LINE); + + // aria-multiselectable + testStates("aria_multiselectable_listbox", + STATE_MULTISELECTABLE | STATE_EXTSELECTABLE); + testStates("aria_multiselectable_tablist", + STATE_MULTISELECTABLE | STATE_EXTSELECTABLE); + + // aria-pressed + testStates("aria_pressed_button", STATE_PRESSED, 0, STATE_CHECKABLE); + testStates("aria_pressed_native_button", STATE_PRESSED, 0, STATE_CHECKABLE); + + // aria-readonly + testStates("aria_readonly_textbox", STATE_READONLY); + + // readonly on grid and gridcell + testStates("aria_grid_default", 0, 0, + STATE_READONLY, 0); + testStates("aria_grid_default_colheader_readonly", STATE_READONLY, 0, + 0, 0); + testStates("aria_grid_default_colheader_inherited", 0, 0, + STATE_READONLY, 0); + testStates("aria_grid_default_rowheader_readonly", STATE_READONLY, 0, + 0, 0); + testStates("aria_grid_default_rowheader_inherited", 0, 0, + STATE_READONLY, 0); + testStates("aria_grid_default_cell_readonly", STATE_READONLY, 0, + 0, 0); + testStates("aria_grid_default_cell_inherited", 0, 0, + STATE_READONLY, 0); + + testStates("aria_grid_readonly", STATE_READONLY, 0, + 0, 0); + testStates("aria_grid_readonly_colheader_editable", 0, 0, + STATE_READONLY, 0); + testStates("aria_grid_readonly_colheader_inherited", STATE_READONLY, 0, + 0, 0); + testStates("aria_grid_readonly_rowheader_editable", 0, 0, + STATE_READONLY, 0); + testStates("aria_grid_readonly_rowheader_inherited", STATE_READONLY, 0, + 0, 0); + testStates("aria_grid_readonly_cell_editable", 0, 0, + STATE_READONLY, 0); + testStates("aria_grid_readonly_cell_inherited", STATE_READONLY, 0, + 0, 0); + + // readonly on treegrid and gridcell + testStates("aria_treegrid_default", 0, 0, + STATE_READONLY, 0); + testStates("aria_treegrid_default_colheader_readonly", STATE_READONLY, 0, + 0, 0); + testStates("aria_treegrid_default_colheader_inherited", 0, 0, + STATE_READONLY, 0); + testStates("aria_treegrid_default_rowheader_readonly", STATE_READONLY, 0, + 0, 0); + testStates("aria_treegrid_default_rowheader_inherited", 0, 0, + STATE_READONLY, 0); + testStates("aria_treegrid_default_cell_readonly", STATE_READONLY, 0, + 0, 0); + testStates("aria_treegrid_default_cell_inherited", 0, 0, + STATE_READONLY, 0); + + testStates("aria_treegrid_readonly", STATE_READONLY, 0, + 0, 0); + testStates("aria_treegrid_readonly_colheader_editable", 0, 0, + STATE_READONLY, 0); + testStates("aria_treegrid_readonly_colheader_inherited", STATE_READONLY, 0, + 0, 0); + testStates("aria_treegrid_readonly_rowheader_editable", 0, 0, + STATE_READONLY, 0); + testStates("aria_treegrid_readonly_rowheader_inherited", STATE_READONLY, 0, + 0, 0); + testStates("aria_treegrid_readonly_cell_editable", 0, 0, + STATE_READONLY, 0); + testStates("aria_treegrid_readonly_cell_inherited", STATE_READONLY, 0, + 0, 0); + + // aria-readonly on directory + testStates("aria_directory", STATE_READONLY); + + // aria-selectable + testStates("aria_selectable_listitem", STATE_SELECTABLE | STATE_SELECTED); + + // active state caused by aria-activedescendant + testStates("as_item1", 0, EXT_STATE_ACTIVE); + testStates("as_item2", 0, 0, 0, EXT_STATE_ACTIVE); + + // universal ARIA properties inherited from file input control + var fileBrowseButton = getAccessible("fileinput").firstChild; + testStates(fileBrowseButton, + STATE_BUSY | STATE_UNAVAILABLE | STATE_REQUIRED | STATE_HASPOPUP | STATE_INVALID); + // No states on the label. + + // offscreen test + testStates("aria_offscreen_textbox", STATE_OFFSCREEN); + + // + // This section tests aria roles on links/anchors for underlying + // HTMLLinkAccessible creation. (see closed bug 494807) + // + + // strong roles + testStates("aria_menuitem_link", 0, 0, STATE_LINKED); + testStates("aria_button_link", 0, 0, STATE_LINKED); + testStates("aria_checkbox_link", 0, 0, STATE_LINKED); + + // strong landmark + testStates("aria_application_link", 0, 0, STATE_LINKED); + testStates("aria_application_anchor", 0, 0, STATE_SELECTABLE); + + // strange cases + testStates("aria_link_link", STATE_LINKED); + testStates("aria_link_anchor", STATE_SELECTABLE); + + // some landmarks that break accessibility for these native elements + // Note that these are illegal uses by web authors as per WAI-ARIA in HTML + testStates("aria_main_link", 0, 0, STATE_LINKED); + testStates("aria_navigation_link", 0, 0, STATE_LINKED); + testStates("aria_main_anchor", 0, 0, STATE_SELECTABLE); + testStates("aria_navigation_anchor", 0, 0, STATE_SELECTABLE); + + // aria-orientation + testStates("aria_combobox", 0, 0, 0, EXT_STATE_HORIZONTAL | EXT_STATE_VERTICAL); + testStates("aria_hcombobox", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL); + testStates("aria_vcombobox", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL); + testStates("aria_listbox", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL); + testStates("aria_hlistbox", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL); + testStates("aria_vlistbox", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL); + testStates("aria_menu", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL); + testStates("aria_hmenu", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL); + testStates("aria_vmenu", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL); + testStates("aria_menubar", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL); + testStates("aria_hmenubar", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL); + testStates("aria_vmenubar", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL); + testStates("aria_radiogroup", 0, 0, 0, EXT_STATE_HORIZONTAL | EXT_STATE_VERTICAL); + testStates("aria_hradiogroup", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL); + testStates("aria_vradiogroup", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL); + testStates("aria_scrollbar", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL); + testStates("aria_hscrollbar", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL); + testStates("aria_vscrollbar", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL); + testStates("aria_separator", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL); + testStates("aria_hseparator", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL); + testStates("aria_vseparator", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL); + testStates("aria_slider", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL); + testStates("aria_hslider", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL); + testStates("aria_vslider", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL); + testStates("aria_tablist", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL); + testStates("aria_htablist", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL); + testStates("aria_vtablist", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL); + testStates("aria_toolbar", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL); + testStates("aria_htoolbar", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL); + testStates("aria_vtoolbar", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL); + testStates("aria_tree", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL); + testStates("aria_htree", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL); + testStates("aria_vtree", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL); + testStates("aria_treegrid", 0, 0, 0, EXT_STATE_HORIZONTAL | EXT_STATE_VERTICAL); + testStates("aria_htreegrid", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL); + testStates("aria_vtreegrid", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL); + + // indeterminate ARIA progressbars (no aria-valuenow or aria-valuetext attribute) + // should expose mixed state + testStates("aria_progressbar", STATE_MIXED); + testStates("aria_progressbar_valuenow", 0, 0, STATE_MIXED); + testStates("aria_progressbar_valuetext", 0, 0, STATE_MIXED); + + // aria-current + testStates("current_page_1", 0, EXT_STATE_CURRENT); + testStates("page_2", 0, 0, EXT_STATE_CURRENT); + testStates("page_3", 0, 0, EXT_STATE_CURRENT); + testStates("page_4", 0, 0, EXT_STATE_CURRENT); + testStates("current_foo", 0, EXT_STATE_CURRENT); + + testStates("aria_listbox", STATE_FOCUSABLE); + testStates("aria_grid", STATE_FOCUSABLE); + testStates("aria_tree", STATE_FOCUSABLE); + testStates("aria_treegrid", STATE_FOCUSABLE); + testStates("aria_listbox_disabled", 0, 0, STATE_FOCUSABLE); + testStates("aria_grid_disabled", 0, 0, STATE_FOCUSABLE); + testStates("aria_tree_disabled", 0, 0, STATE_FOCUSABLE); + testStates("aria_treegrid_disabled", 0, 0, STATE_FOCUSABLE); + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + </script> + +</head> + +<body> + + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=457219" + title="nsIAccessible states testing"> + Mozilla Bug 457219 + </a><br /> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=429285" + title="Propagate aria-disabled to descendants"> + Mozilla Bug 429285 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=457226" + title="Mochitests for ARIA states"> + Mozilla Bug 457226 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=499653" + title="Unify ARIA state attributes mapping rules"> + Mozilla Bug 499653 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=681674" + title="aria-autocomplete not supported on standard form text input controls"> + Mozilla Bug 681674 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=681674" + title="aria-orientation should be applied to separator and slider roles"> + Mozilla Bug 681674 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=689847" + title="Expose active state on current item of selectable widgets"> + Mozilla Bug 689847 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=699017" + title="File input control should be propogate states to descendants"> + Mozilla Bug 699017 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=690199" + title="ARIA select widget should expose focusable state regardless the way they manage its children"> + Mozilla Bug 690199 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=740851" + title="ARIA undetermined progressmeters should expose mixed state"> + Mozilla Bug 740851 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=762876" + title="fix default horizontal / vertical state of role=scrollbar and ensure only one of horizontal / vertical states is exposed"> + Mozilla Bug 762876 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=892091" + title="ARIA treegrid should be editable by default"> + Bug 892091 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=835121" + title="ARIA grid should be editable by default"> + Mozilla Bug 835121 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=989958" + title="Pressed state is not exposed on a button element with aria-pressed attribute"> + Mozilla Bug 989958 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=1136563" + title="Support ARIA 1.1 switch role"> + Mozilla Bug 1136563 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=1355921" + title="Elements with a defined, non-false value for aria-current should expose ATK_STATE_ACTIVE"> + Mozilla Bug 1355921 + </a> + + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"> + </pre> + + <div id="textbox_autocomplete_inline" role="textbox" aria-autocomplete="inline"></div> + <div id="textbox_autocomplete_list" role="textbox" aria-autocomplete="list"></div> + <div id="textbox_autocomplete_both" role="textbox" aria-autocomplete="both"></div> + <div id="combobox_autocomplete_inline" role="combobox" aria-autocomplete="inline"></div> + <div id="combobox_autocomplete_list" role="combobox" aria-autocomplete="list"></div> + <div id="combobox_autocomplete_both" role="combobox" aria-autocomplete="both"></div> + + <input id="htmltext_autocomplete_list" type="text" aria-autocomplete="list" /> + <textarea id="htmltextarea_autocomplete_list" aria-autocomplete="list"></textarea> + + <div id="textbox_busy_false" role="textbox" aria-busy="false"></div> + <div id="textbox_busy_true" role="textbox" aria-busy="true"></div> + <div id="textbox_busy_error" role="textbox" aria-busy="error"></div> + + <div id="combobox" role="combobox">combobox</div> + <div id="combobox_expanded" role="combobox" + aria-expanded="true">combobox</div> + + <input type="checkbox" id="check1" value="I agree" checked="true"/> + + <div id="aria_checked_checkbox" role="checkbox" aria-checked="true"> + I agree + </div> + + <div id="aria_mixed_checkbox" role="checkbox" aria-checked="mixed"> + I might agree + </div> + + <div id="aria_checked_switch" role="switch" aria-checked="true"> + I am switched on + </div> + + <div id="aria_mixed_switch" role="switch" aria-checked="mixed"> + I am unsupported + </div> + + <div id="aria_modal" aria-modal="true">modal stuff</div> + <div id="aria_modal_false" aria-modal="false">non modal stuff</div>div> + <div id="aria_multiline_textbox" role="textbox" aria-multiline="true"></div> + <div id="aria_multiselectable_listbox" role="listbox" aria-multiselectable="true"></div> + <div id="aria_multiselectable_tablist" role="tablist" aria-multiselectable="true"></div> + <div id="aria_pressed_button" role="button" aria-pressed="true">Button</div> + <button id="aria_pressed_native_button" aria-pressed="true">Button</button> + + <div id="aria_readonly_textbox" + role="textbox" aria-readonly="true">This text should be readonly</div> + + <div id="aria_grid_default" role="grid"> + <div role="row"> + <div id="aria_grid_default_colheader_readonly" + role="columnheader" aria-readonly="true">colheader1</div> + <div id="aria_grid_default_colheader_inherited" + role="columnheader">colheader2</div> + </div> + <div role="row"> + <div id="aria_grid_default_rowheader_readonly" + role="rowheader" aria-readonly="true">rowheader1</div> + <div id="aria_grid_default_rowheader_inherited" + role="rowheader">rowheader2</div> + </div> + <div role="row"> + <div id="aria_grid_default_cell_readonly" + role="gridcell" aria-readonly="true">gridcell1</div> + <div id="aria_grid_default_cell_inherited" + role="gridcell">gridcell2</div> + </div> + </div> + + <div id="aria_grid_readonly" role="grid" aria-readonly="true"> + <div role="row"> + <div id="aria_grid_readonly_colheader_editable" + role="columnheader" aria-readonly="false">colheader1</div> + <div id="aria_grid_readonly_colheader_inherited" + role="columnheader">colheader2</div> + </div> + <div role="row"> + <div id="aria_grid_readonly_rowheader_editable" + role="rowheader" aria-readonly="false">rowheader1</div> + <div id="aria_grid_readonly_rowheader_inherited" + role="rowheader">rowheader2</div> + </div> + <div role="row"> + <div id="aria_grid_readonly_cell_editable" + role="gridcell" aria-readonly="false">gridcell1</div> + <div id="aria_grid_readonly_cell_inherited" + role="gridcell">gridcell2</div> + </div> + </div> + + <div id="aria_treegrid_default" role="grid"> + <div role="row"> + <div id="aria_treegrid_default_colheader_readonly" + role="columnheader" aria-readonly="true">colheader1</div> + <div id="aria_treegrid_default_colheader_inherited" + role="columnheader">colheader2</div> + </div> + <div role="row"> + <div id="aria_treegrid_default_rowheader_readonly" + role="rowheader" aria-readonly="true">rowheader1</div> + <div id="aria_treegrid_default_rowheader_inherited" + role="rowheader">rowheader2</div> + </div> + <div role="row"> + <div id="aria_treegrid_default_cell_readonly" + role="gridcell" aria-readonly="true">gridcell1</div> + <div id="aria_treegrid_default_cell_inherited" + role="gridcell">gridcell2</div> + </div> + </div> + + <div id="aria_treegrid_readonly" role="grid" aria-readonly="true"> + <div role="row"> + <div id="aria_treegrid_readonly_colheader_editable" + role="columnheader" aria-readonly="false">colheader1</div> + <div id="aria_treegrid_readonly_colheader_inherited" + role="columnheader">colheader2</div> + </div> + <div role="row"> + <div id="aria_treegrid_readonly_rowheader_editable" + role="rowheader" aria-readonly="false">rowheader1</div> + <div id="aria_treegrid_readonly_rowheader_inherited" + role="rowheader">rowheader2</div> + </div> + <div role="row"> + <div id="aria_treegrid_readonly_cell_editable" + role="gridcell" aria-readonly="false">gridcell1</div> + <div id="aria_treegrid_readonly_cell_inherited" + role="gridcell">gridcell2</div> + </div> + </div> + + <div role="listbox"> + <div id="aria_selectable_listitem" role="option" aria-selected="true">Item1</div> + </div> + + <!-- Test that aria-disabled state gets propagated to all descendants --> + <div id="group" role="group" aria-disabled="true"> + <button>hi</button> + <div tabindex="0" role="listbox" aria-activedescendant="item1" + aria-owns="item5"> + <div role="option" id="item1">Item 1</div> + <div role="option" id="item2">Item 2</div> + <div role="option" id="item3">Item 3</div> + <div role="option" id="item4">Item 4</div> + </div> + <div role="slider" tabindex="0">A slider</div> + </div> + <div role="option" id="item5">Item 5</div> + + <!-- Test active state --> + <div id="as_listbox" tabindex="0" role="listbox" + aria-activedescendant="as_item1"> + <div role="option" id="as_item1">Item 1</div> + <div role="option" id="as_item2">Item 2</div> + </div> + + <!-- universal ARIA properties should be inherited by text field of file input --> + <input type="file" id="fileinput" + aria-busy="true" + aria-disabled="true" + aria-required="true" + aria-haspopup="true" + aria-invalid="true"> + + <div id="offscreen_log" role="log" class="offscreen"> + <div id="aria_offscreen_textbox" role="textbox" aria-readonly="true">This text should be offscreen</div> + </div> + + <a id="aria_menuitem_link" role="menuitem" href="foo">menuitem</a> + <a id="aria_button_link" role="button" href="foo">button</a> + <a id="aria_checkbox_link" role="checkbox" href="foo">checkbox</a> + + <!-- strange edge case: please don't do this in the wild --> + <a id="aria_link_link" role="link" href="foo">link</a> + <a id="aria_link_anchor" role="link" name="link_anchor">link</a> + + <!-- landmarks: links --> + <a id="aria_application_link" role="application" href="foo">app</a> + <a id="aria_main_link" role="main" href="foo">main</a> + <a id="aria_navigation_link" role="navigation" href="foo">nav</a> + + <!-- landmarks: anchors --> + <a id="aria_application_anchor" role="application" name="app_anchor">app</a> + <a id="aria_main_anchor" role="main" name="main_anchor">main</a> + <a id="aria_navigation_anchor" role="navigation" name="nav_anchor">nav</a> + + <!-- aria-orientation --> + <div id="aria_combobox" role="combobox">combobox</div> + <div id="aria_hcombobox" role="combobox" aria-orientation="horizontal">horizontal combobox</div> + <div id="aria_vcombobox" role="combobox" aria-orientation="vertical">vertical combobox</div> + <div id="aria_listbox" role="listbox">listbox</div> + <div id="aria_hlistbox" role="listbox" aria-orientation="horizontal">horizontal listbox</div> + <div id="aria_vlistbox" role="listbox" aria-orientation="vertical">vertical listbox</div> + <div id="aria_menu" role="menu">menu</div> + <div id="aria_hmenu" role="menu" aria-orientation="horizontal">horizontal menu</div> + <div id="aria_vmenu" role="menu" aria-orientation="vertical">vertical menu</div> + <div id="aria_menubar" role="menubar">menubar</div> + <div id="aria_hmenubar" role="menubar" aria-orientation="horizontal">horizontal menubar</div> + <div id="aria_vmenubar" role="menubar" aria-orientation="vertical">vertical menubar</div> + <div id="aria_radiogroup" role="radiogroup">radiogroup</div> + <div id="aria_hradiogroup" role="radiogroup" aria-orientation="horizontal">horizontal radiogroup</div> + <div id="aria_vradiogroup" role="radiogroup" aria-orientation="vertical">vertical radiogroup</div> + <div id="aria_scrollbar" role="scrollbar">scrollbar</div> + <div id="aria_hscrollbar" role="scrollbar" aria-orientation="horizontal">horizontal scrollbar</div> + <div id="aria_vscrollbar" role="scrollbar" aria-orientation="vertical">vertical scrollbar</div> + <div id="aria_separator" role="separator">separator</div> + <div id="aria_hseparator" role="separator" aria-orientation="horizontal">horizontal separator</div> + <div id="aria_vseparator" role="separator" aria-orientation="vertical">vertical separator</div> + <div id="aria_slider" role="slider">slider</div> + <div id="aria_hslider" role="slider" aria-orientation="horizontal">horizontal slider</div> + <div id="aria_vslider" role="slider" aria-orientation="vertical">vertical slider</div> + + <div id="aria_tablist" role="tablist">tablist</div> + <div id="aria_htablist" role="tablist" aria-orientation="horizontal">horizontal tablist</div> + <div id="aria_vtablist" role="tablist" aria-orientation="vertical">vertical tablist</div> + <div id="aria_toolbar" role="toolbar">toolbar</div> + <div id="aria_htoolbar" role="toolbar" aria-orientation="horizontal">horizontal toolbar</div> + <div id="aria_vtoolbar" role="toolbar" aria-orientation="vertical">vertical toolbar</div> + <div id="aria_tree" role="tree">tree</div> + <div id="aria_htree" role="tree" aria-orientation="horizontal">horizontal tree</div> + <div id="aria_vtree" role="tree" aria-orientation="vertical">vertical tree</div> + <div id="aria_treegrid" role="treegrid">treegrid</div> + <div id="aria_htreegrid" role="treegrid" aria-orientation="horizontal">horizontal treegrid</div> + <div id="aria_vtreegrid" role="treegrid" aria-orientation="vertical">vertical treegrid</div> + + <!-- indeterminate ARIA progressbars should expose mixed state --> + <div id="aria_progressbar" role="progressbar"></div> + <div id="aria_progressbar_valuenow" role="progressbar" aria-valuenow="1"></div> + <div id="aria_progressbar_valuetext" role="progressbar" aria-valuetext="value"></div> + + <!-- ARIA select widget should expose focusable state regardless the way they manage its children --> + <div id="aria_listbox" role="listbox"> + <div role="option" tabindex="0">A</div> + <div role="option" tabindex="0">a</div> + </div> + <div id="aria_grid" role="grid"> + <div role="row"><div role="gridcell" tabindex="0">B</div></div></div> + <div role="row"><div role="gridcell" tabindex="0">b</div></div></div> + <div id="aria_tree" role="tree"> + <div role="treeitem" tabindex="0">C</div> + <div role="treeitem" tabindex="0">c</div> + </div> + <div id="aria_treegrid" role="treegrid"> + <div role="row"><div role="gridcell" tabindex="0">D</div></div> + <div role="row"><div role="gridcell" tabindex="0">d</div></div> + </div> + <div id="aria_listbox_disabled" role="listbox" aria-disabled="true"> + <div role="option">E</div> + <div role="option">e</div> + </div> + <div id="aria_grid_disabled" role="grid" aria-disabled="true"> + <div role="row"><div role="gridcell">F</div></div> + <div role="row"><div role="gridcell">f</div></div> + </div> + <div id="aria_tree_disabled" role="tree" aria-disabled="true"> + <div role="treeitem">G</div> + <div role="treeitem">g</div> + </div> + <div id="aria_treegrid_disabled" role="treegrid" aria-disabled="true"> + <div role="row"><div role="gridcell">H</div></div> + <div role="row"><div role="gridcell">h</div></div> + </div> + + <!-- Test that directory is readonly --> + <div id="aria_directory" role="directory"></div> + + <!-- aria-current --> + <div id="current_page_1" role="link" aria-current="page">1</div> + <div id="page_2" role="link" aria-current="false">2</div> + <div id="page_3" role="link">3</div> + <div id="page_4" role="link" aria-current="">4</div> + <div id="current_foo" aria-current="foo">foo</div> +</body> +</html> diff --git a/accessible/tests/mochitest/states/test_aria.xhtml b/accessible/tests/mochitest/states/test_aria.xhtml new file mode 100644 index 0000000000..e42a0ea96d --- /dev/null +++ b/accessible/tests/mochitest/states/test_aria.xhtml @@ -0,0 +1,70 @@ +<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
+ type="text/css"?>
+
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ title="Accessible XUL ARIA state tests">
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
+
+ <script type="application/javascript"
+ src="../common.js" />
+ <script type="application/javascript"
+ src="../role.js" />
+ <script type="application/javascript"
+ src="../states.js" />
+
+ <script type="application/javascript">
+ <![CDATA[
+ function doTest()
+ {
+ // aria-pressed
+ testStates("pressed_button", STATE_PRESSED, 0, STATE_CHECKABLE);
+
+ testStates("tabs", STATE_MULTISELECTABLE);
+ // Make sure XUL selection works, since aria-selected defaults to false.
+ testStates("tab1", STATE_SELECTED);
+ // aria-selected="true".
+ testStates("tab2", STATE_SELECTED);
+ // Neither.
+ testStates("tab3", 0, 0, STATE_SELECTED);
+
+ SimpleTest.finish()
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ ]]>
+ </script>
+
+ <hbox flex="1" style="overflow: auto;">
+ <body xmlns="http://www.w3.org/1999/xhtml">
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=1033283"
+ title="Expose pressed state on XUL menu toggle buttons">
+ Mozilla Bug 1033283
+ </a>
+ <p id="display"></p>
+ <div id="content" style="display: none">
+ </div>
+ <pre id="test">
+ </pre>
+ </body>
+
+ <vbox flex="1">
+ <button id="pressed_button" aria-pressed="true" label="I am pressed" />
+
+ <tabbox>
+ <tabs id="tabs" aria-multiselectable="true">
+ <tab id="tab1" label="tab1" selected="true"/>
+ <tab id="tab2" label="tab2" aria-selected="true"/>
+ <tab id="tab3" label="tab3"/>
+ </tabs>
+ </tabbox>
+ </vbox>
+ </hbox>
+
+</window>
+
diff --git a/accessible/tests/mochitest/states/test_aria_imgmap.html b/accessible/tests/mochitest/states/test_aria_imgmap.html new file mode 100644 index 0000000000..387e33259e --- /dev/null +++ b/accessible/tests/mochitest/states/test_aria_imgmap.html @@ -0,0 +1,75 @@ +<!DOCTYPE html> +<html> +<head> + <title>Test usemap elements and ARIA</title> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" /> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> + + <script type="application/javascript" + src="../common.js"></script> + <script type="application/javascript" + src="../role.js"></script> + <script type="application/javascript" + src="../events.js"></script> + <script type="application/javascript" + src="../states.js"></script> + + <script type="application/javascript"> + // gA11yEventDumpToConsole = true; + function doPreTest() { + waitForImageMap("imagemap", doTest); + } + + function doTest() { + var imageMap = getAccessible("imagemap"); + + var t1 = imageMap.getChildAt(0); + testStates(t1, 0, EXT_STATE_EDITABLE, STATE_LINKED); + var t2 = imageMap.getChildAt(1); + testStates(t2, 0, EXT_STATE_EDITABLE, STATE_LINKED); + var rb1 = imageMap.getChildAt(2); + testStates(rb1, (STATE_CHECKABLE | STATE_CHECKED), 0, STATE_LINKED); + var rb2 = imageMap.getChildAt(3); + testStates(rb2, STATE_CHECKABLE, 0, STATE_CHECKED, STATE_LINKED); + var cb1 = imageMap.getChildAt(4); + testStates(cb1, (STATE_CHECKABLE | STATE_CHECKED), 0, STATE_LINKED); + var cbox = imageMap.getChildAt(5); + testStates(cbox, (STATE_HASPOPUP | STATE_COLLAPSED), + EXT_STATE_EXPANDABLE, STATE_LINKED); + + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doPreTest); + </script> + +</head> +<body> + +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=548291" + title="ARIA states on image maps"> +Mozilla Bug 548291 +</a> +<p id="display"></p> +<div id="content" style="display: none"></div> +<pre id="test"> +</pre> + +<img id="imagemap" src="../formimage.png" width="219" height="229" border="0" usemap="#ariaMap"> +<map id="ariaMap" name="ariaMap"> + <area id="t1" role="textbox" shape="rect" tabindex="0" alt="" title="first name" coords="4,20,108,48" href="#" /> + <area id="t2" role="textbox" shape="rect" alt="" title="last name" coords="111,21,215,50" href="#" /> + <area id="rb1" role="radio" aria-checked="true" shape="circle" alt="" title="male" coords="60,75,11" href="#" /> + <area id="rb2" role="radio" shape="circle" alt="" title="female" coords="73,94,11" href="#" /> + <area id="cb1" role="checkbox" aria-checked="true" shape="rect" alt="" title="have bike" coords="95,123,118,145" href="#" /> + <area id="cbox" role="combobox" shape="rect" alt="" title="bike model" coords="120,124,184,146" href="#" /> + <area id="cb2" role="checkbox" shape="rect" alt="" title="have car" coords="90,145,114,164" href="#" /> + <area id="cb3" role="checkbox" shape="rect" alt="" title="have airplane" coords="130,163,152,184" href="#" /> + <area id="b1" role="button" shape="rect" alt="" title="submit" coords="4,198,67,224" href="#" /> +</map> +</body> +</html> diff --git a/accessible/tests/mochitest/states/test_aria_widgetitems.html b/accessible/tests/mochitest/states/test_aria_widgetitems.html new file mode 100644 index 0000000000..c2d546ba01 --- /dev/null +++ b/accessible/tests/mochitest/states/test_aria_widgetitems.html @@ -0,0 +1,152 @@ +<!DOCTYPE html> +<html> + +<head> + <title>Test ARIA tab accessible selected state</title> + + <link rel="stylesheet" type="text/css" + href="chrome://mochikit/content/tests/SimpleTest/test.css" /> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <script type="application/javascript" + src="../common.js"></script> + <script type="application/javascript" + src="../role.js"></script> + <script type="application/javascript" + src="../states.js"></script> + <script type="application/javascript" + src="../events.js"></script> + + <script type="application/javascript"> + function focusARIAItem(aID, aIsSelected) { + this.DOMNode = getNode(aID); + + this.invoke = function focusARIAItem_invoke() { + this.DOMNode.focus(); + }; + + this.check = function focusARIAItem_check(aEvent) { + testStates(this.DOMNode, aIsSelected ? STATE_SELECTED : 0, 0, + aIsSelected ? 0 : STATE_SELECTED); + }; + + this.getID = function focusARIAItem_getID() { + return "Focused ARIA widget item with aria-selected='" + + (aIsSelected ? "true', should" : "false', shouldn't") + + " have selected state on " + prettyName(aID); + }; + } + + function focusActiveDescendantItem(aItemID, aWidgetID, aIsSelected) { + this.DOMNode = getNode(aItemID); + this.widgetDOMNode = getNode(aWidgetID); + + this.invoke = function focusActiveDescendantItem_invoke() { + this.widgetDOMNode.setAttribute("aria-activedescendant", aItemID); + this.widgetDOMNode.focus(); + }; + + this.check = function focusActiveDescendantItem_check(aEvent) { + testStates(this.DOMNode, aIsSelected ? STATE_SELECTED : 0, 0, + aIsSelected ? 0 : STATE_SELECTED); + }; + + this.getID = function tabActiveDescendant_getID() { + return "ARIA widget item managed by activedescendant " + + (aIsSelected ? "should" : "shouldn't") + + " have the selected state on " + prettyName(aItemID); + }; + } + + // ////////////////////////////////////////////////////////////////////////// + // Test + + // gA11yEventDumpID = "eventdump"; // debug stuff + // gA11yEventDumpToConsole = true; + + var gQueue = null; + + function doTest() { + // aria-selected + testStates("aria_tab1", 0, 0, STATE_SELECTED); + testStates("aria_tab2", STATE_SELECTED); + testStates("aria_tab3", 0, 0, STATE_SELECTED); + testStates("aria_option1", 0, 0, STATE_SELECTED); + testStates("aria_option2", STATE_SELECTED); + testStates("aria_option3", 0, 0, STATE_SELECTED); + testStates("aria_treeitem1", 0, 0, STATE_SELECTED); + testStates("aria_treeitem2", STATE_SELECTED); + testStates("aria_treeitem3", 0, 0, STATE_SELECTED); + + // selected state when widget item is focused + gQueue = new eventQueue(EVENT_FOCUS); + + gQueue.push(new focusARIAItem("aria_tab1", true)); + gQueue.push(new focusARIAItem("aria_tab2", true)); + gQueue.push(new focusARIAItem("aria_tab3", false)); + gQueue.push(new focusARIAItem("aria_option1", true)); + gQueue.push(new focusARIAItem("aria_option2", true)); + gQueue.push(new focusARIAItem("aria_option3", false)); + gQueue.push(new focusARIAItem("aria_treeitem1", true)); + gQueue.push(new focusARIAItem("aria_treeitem2", true)); + gQueue.push(new focusARIAItem("aria_treeitem3", false)); + + // selected state when widget item is focused (by aria-activedescendant) + gQueue.push(new focusActiveDescendantItem("aria_tab5", "aria_tablist2", true)); + gQueue.push(new focusActiveDescendantItem("aria_tab6", "aria_tablist2", true)); + gQueue.push(new focusActiveDescendantItem("aria_tab4", "aria_tablist2", false)); + + gQueue.invoke(); // SimpleTest.finish() will be called in the end + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + </script> +</head> +<body> + + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=653601" + title="aria-selected ignored for ARIA tabs"> + Mozilla Bug 653601 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=526703" + title="Focused widget item should expose selected state by default"> + Mozilla Bug 526703 + </a> + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"> + </pre> + + <!-- tab --> + <div id="aria_tablist" role="tablist"> + <div id="aria_tab1" role="tab" tabindex="0">unselected tab</div> + <div id="aria_tab2" role="tab" tabindex="0" aria-selected="true">selected tab</div> + <div id="aria_tab3" role="tab" tabindex="0" aria-selected="false">focused explicitly unselected tab</div> + </div> + + <!-- listbox --> + <div id="aria_listbox" role="listbox"> + <div id="aria_option1" role="option" tabindex="0">unselected option</div> + <div id="aria_option2" role="option" tabindex="0" aria-selected="true">selected option</div> + <div id="aria_option3" role="option" tabindex="0" aria-selected="false">focused explicitly unselected option</div> + </div> + + <!-- tree --> + <div id="aria_tree" role="tree"> + <div id="aria_treeitem1" role="treeitem" tabindex="0">unselected treeitem</div> + <div id="aria_treeitem2" role="treeitem" tabindex="0" aria-selected="true">selected treeitem</div> + <div id="aria_treeitem3" role="treeitem" tabindex="0" aria-selected="false">focused explicitly unselected treeitem</div> + </div> + + <!-- tab managed by active-descendant --> + <div id="aria_tablist2" role="tablist" tabindex="0"> + <div id="aria_tab4" role="tab" aria-selected="false">focused explicitly unselected tab</div> + <div id="aria_tab5" role="tab">initially selected tab</div> + <div id="aria_tab6" role="tab">later selected tab</div> + </div> +</body> +</html> diff --git a/accessible/tests/mochitest/states/test_buttons.html b/accessible/tests/mochitest/states/test_buttons.html new file mode 100644 index 0000000000..ec6e65cf32 --- /dev/null +++ b/accessible/tests/mochitest/states/test_buttons.html @@ -0,0 +1,83 @@ +<!DOCTYPE html> +<html> +<head> + <title>HTML button accessible states</title> + <link rel="stylesheet" type="text/css" + href="chrome://mochikit/content/tests/SimpleTest/test.css" /> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <script type="application/javascript" + src="../common.js"></script> + <script type="application/javascript" + src="../role.js"></script> + <script type="application/javascript" + src="../states.js"></script> + + <script type="application/javascript"> + function doTest() { + // Default state. + testStates("f1_image", STATE_DEFAULT | STATE_FOCUSABLE); + testStates("f2_submit", STATE_DEFAULT | STATE_FOCUSABLE); + testStates("f3_submitbutton", STATE_DEFAULT | STATE_FOCUSABLE); + testStates("f3_disabled_reset", STATE_UNAVAILABLE, 0, STATE_FOCUSABLE, 0); + testStates("f4_button", STATE_FOCUSABLE, 0, STATE_DEFAULT); + testStates("f4_disabled_button", STATE_UNAVAILABLE, 0, STATE_FOCUSABLE, 0); + testStates("f4_image1", STATE_DEFAULT | STATE_FOCUSABLE); + testStates("f4_image2", STATE_FOCUSABLE, 0, STATE_DEFAULT); + testStates("f4_submit", STATE_FOCUSABLE, 0, STATE_DEFAULT); + testStates("f4_submitbutton", STATE_FOCUSABLE, 0, STATE_DEFAULT); + + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + </script> +</head> + +<body> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=664142" + title="DEFAULT state exposed incorrectly for HTML"> + Mozilla Bug 664142 + </a> + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"> + </pre> + + <p>A form with an image button</p> + <form name="form1" method="get"> + <input type="text" name="hi"> + + <input id="f1_image" type="image" value="image-button"> + </form> + + <p>A form with a submit button:</p> + <form name="form2" method="get"> + <input type="text" name="hi"> + <input id="f2_submit" type="submit"> + </form> + + <p>A form with a HTML4 submit button:</p> + <form name="form3" method="get"> + <input type="text" name="hi"> + <button id="f3_submitbutton" type="submit">submit</button> + <button id="f3_disabled_reset" type="reset" disabled>reset</button> + </form> + + <p>A form with normal button, two image buttons, submit button, + HTML4 submit button:</p> + <form name="form4" method="get"> + <input type="text" name="hi"> + <input id="f4_button" type="button" value="normal" name="normal-button"> + <input id="f4_disabled_button" type="button" value="disabled" name="disabled-button" disabled> + <input id="f4_image1" type="image" value="image-button1" name="image-button1"> + <input id="f4_image2" type="image" value="image-button2" name="image-button2"> + <input id="f4_submit" type="submit" value="real-submit" name="real-submit"> + <button id="f4_submitbutton" type="submit">submit</button> + </form> + + </body> +</html> diff --git a/accessible/tests/mochitest/states/test_controls.html b/accessible/tests/mochitest/states/test_controls.html new file mode 100644 index 0000000000..27aecf4c52 --- /dev/null +++ b/accessible/tests/mochitest/states/test_controls.html @@ -0,0 +1,51 @@ +<!DOCTYPE html> +<html> +<head> + <title>HTML control states</title> + <link rel="stylesheet" type="text/css" + href="chrome://mochikit/content/tests/SimpleTest/test.css" /> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <script type="application/javascript" + src="../common.js"></script> + <script type="application/javascript" + src="../role.js"></script> + <script type="application/javascript" + src="../states.js"></script> + + <script type="application/javascript"> + function doTest() { + // Undetermined progressbar (no value or aria-value attribute): mixed state + testStates("progress", STATE_MIXED); + // Determined progressbar (has value): shouldn't have mixed state + testStates("progress2", 0, 0, STATE_MIXED); + // Determined progressbar (has aria-value): shouldn't have mixed state + // testStates("progress3", 0, 0, STATE_MIXED); + todo(false, "we should respect ARIA"); + + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + </script> +</head> + +<body> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=670853" + title="Bug 670853 - undetermined progressmeters should expose mixed state"> + Mozilla Bug 670853 + </a> + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"> + </pre> + + <progress id="progress"></progress> + <progress id="progress2" value="1"></progress> + <progress id="progress3" aria-valuenow="1"></progress> + +</body> +</html> diff --git a/accessible/tests/mochitest/states/test_controls.xhtml b/accessible/tests/mochitest/states/test_controls.xhtml new file mode 100644 index 0000000000..de83f2aecc --- /dev/null +++ b/accessible/tests/mochitest/states/test_controls.xhtml @@ -0,0 +1,153 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> + +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="Accessible XUL input control state tests"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + + <script type="application/javascript" + src="../common.js" /> + <script type="application/javascript" + src="../role.js" /> + <script type="application/javascript" + src="../states.js" /> + <script type="application/javascript" + src="../events.js" /> + + <script type="application/javascript"> + <![CDATA[ + var gQueue = null; + function doTest() + { + testStates("checkbox", STATE_FOCUSABLE, 0, STATE_UNAVAILABLE); + testStates("checkbox2", STATE_UNAVAILABLE, 0 , STATE_FOCUSABLE); + testStates("radiogroup", 0, 0, STATE_FOCUSABLE | STATE_UNAVAILABLE); + testStates("radio", STATE_FOCUSABLE, 0, STATE_UNAVAILABLE); + testStates("radio-disabled", STATE_UNAVAILABLE, 0 , STATE_FOCUSABLE); + testStates("radiogroup-disabled", STATE_UNAVAILABLE, 0 , STATE_FOCUSABLE); + testStates("radio-disabledradiogroup", STATE_UNAVAILABLE, 0 , STATE_FOCUSABLE); + testStates("button", STATE_FOCUSABLE, 0, STATE_UNAVAILABLE); + testStates("button-disabled", STATE_UNAVAILABLE, 0 , STATE_FOCUSABLE); + testStates("checkbutton", + STATE_FOCUSABLE | STATE_CHECKABLE | STATE_PRESSED); + testStates("fakecheckbutton", STATE_FOCUSABLE | STATE_PRESSED, 0, + STATE_CHECKABLE); + testStates("combobox", STATE_FOCUSABLE | STATE_HASPOPUP, 0, STATE_UNAVAILABLE); + testStates("combobox-disabled", STATE_UNAVAILABLE | STATE_HASPOPUP, 0, STATE_FOCUSABLE); + testStates("listbox", STATE_FOCUSABLE, 0, STATE_UNAVAILABLE); + testStates("listitem", STATE_FOCUSABLE | STATE_SELECTABLE | STATE_SELECTED, 0, STATE_UNAVAILABLE); + testStates("listbox-disabled", STATE_UNAVAILABLE, 0, STATE_FOCUSABLE | STATE_SELECTABLE); + testStates("listitem-disabledlistbox", STATE_UNAVAILABLE | STATE_SELECTED, 0, STATE_FOCUSABLE | STATE_SELECTABLE); + testStates("menubar", 0, 0, STATE_FOCUSABLE); + testStates("menu", STATE_FOCUSABLE, 0, STATE_UNAVAILABLE); + testStates("menu-disabled", STATE_UNAVAILABLE, 0, STATE_FOCUSABLE | STATE_SELECTABLE); + testStates("tab", STATE_FOCUSABLE | STATE_SELECTABLE | STATE_SELECTED, 0, STATE_UNAVAILABLE); + testStates("tab-disabled", STATE_UNAVAILABLE, 0, STATE_FOCUSABLE | STATE_SELECTABLE | STATE_SELECTED); + + gQueue = new eventQueue(); + gQueue.invoke(); // Will call SimpleTest.finish() + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + ]]> + </script> + + <hbox flex="1" style="overflow: auto;"> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=599163" + title="check disabled state instead of attribute"> + Mozilla Bug 599163 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=756983" + title="Isolate focusable and unavailable states from State()"> + Mozilla Bug 756983 + </a> + <p id="display"></p> + <div id="content" style="display: none"> + </div> + <pre id="test"> + </pre> + </body> + + <vbox flex="1"> + + <checkbox id="checkbox" checked="true" label="Steak"/> + <checkbox id="checkbox2" checked="true" label="Salad" disabled="true"/> + + <radiogroup id="radiogroup"> + <radio id="radio" label="Orange"/> + <radio id="radio-disabled" selected="true" label="Violet" disabled="true"/> + </radiogroup> + + <radiogroup id="radiogroup-disabled" disabled="true"> + <radio id="radio-disabledradiogroup" label="Orange"/> + <radio id="violet2" selected="true" label="Violet"/> + </radiogroup> + + <button id="button" value="button"/> + <button id="button-disabled" disabled="true" value="button"/> + <button id="checkbutton" type="checkbox" checked="true" + value="checkbutton" /> + <button id="fakecheckbutton" checked="true" value="fakecheckbutton" /> + + <menulist id="combobox"> + <menupopup> + <menuitem label="item1"/> + </menupopup> + </menulist> + + <menulist id="combobox-disabled" disabled="true"> + <menupopup> + <menuitem label="item1"/> + </menupopup> + </menulist> + + <richlistbox id="listbox"> + <richlistitem id="listitem"> + <label value="list item"/> + </richlistitem> + </richlistbox> + + <richlistbox id="listbox-disabled" disabled="true"> + <richlistitem id="listitem-disabledlistbox"> + <label value="list item"/> + </richlistitem> + </richlistbox> + + <toolbox> + <menubar id="menubar"> + <menu id="menu" label="menu1"> + <menupopup> + <menuitem id="menu1-item1" label="menuitem1.1"/> + </menupopup> + </menu> + <menu id="menu-disabled" label="menu2" disabled="true"> + <menupopup> + <menuitem id="menu-disabled-item1" label="menuitem2.1"/> + </menupopup> + </menu> + </menubar> + </toolbox> + + <tabbox> + <tabs> + <tab id="tab" label="tab1" tooltip="tooltip"/> + <tab id="tab-disabled" label="tab1" disabled="true"/> + </tabs> + <tabpanels> + <tabpanel/> + <tabpanel/> + </tabpanels> + </tabbox> + + <tooltip id="tooltip"><description>tooltip</description></tooltip> + </vbox> + </hbox> + +</window> diff --git a/accessible/tests/mochitest/states/test_doc.html b/accessible/tests/mochitest/states/test_doc.html new file mode 100644 index 0000000000..a00ca957b9 --- /dev/null +++ b/accessible/tests/mochitest/states/test_doc.html @@ -0,0 +1,95 @@ +<!DOCTYPE html> +<html> +<head> + <title>states of document</title> + <link rel="stylesheet" type="text/css" + href="chrome://mochikit/content/tests/SimpleTest/test.css" /> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <script type="application/javascript" + src="../common.js"></script> + <script type="application/javascript" + src="../role.js"></script> + <script type="application/javascript" + src="../states.js"></script> + + <script type="application/javascript"> + function doTest() { + // Bug 566542: root accesible should expose active state when focused. + testStates(getRootAccessible(), 0, EXT_STATE_ACTIVE); + + // Bug 509696, 607219. + testStates(document, STATE_READONLY, 0); // role="" + + document.body.setAttribute("role", "application"); + testStates(document, 0, 0, STATE_READONLY); + document.body.setAttribute("role", "foo"); // bogus role + testStates(document, STATE_READONLY); + document.body.removeAttribute("role"); + testStates(document, STATE_READONLY); + + // Bugs 454997 and 467387 + testStates(document, STATE_READONLY); + testStates("document", STATE_READONLY); + testStates("editable_document", 0, EXT_STATE_EDITABLE, STATE_READONLY); + + testStates("p", 0, EXT_STATE_SELECTABLE_TEXT, 0, EXT_STATE_EDITABLE); + testStates("unselectable_p", 0, 0, 0, EXT_STATE_SELECTABLE_TEXT | EXT_STATE_EDITABLE); + testStates("unselectable_link", 0, 0, 0, EXT_STATE_SELECTABLE_TEXT | EXT_STATE_EDITABLE); + + document.designMode = "on"; + + testStates(document, 0, EXT_STATE_EDITABLE, STATE_READONLY); + testStates("p", 0, EXT_STATE_EDITABLE | EXT_STATE_SELECTABLE_TEXT, STATE_READONLY); + testStates("document", 0, EXT_STATE_EDITABLE, STATE_READONLY); + testStates("editable_document", 0, EXT_STATE_EDITABLE, STATE_READONLY); + testStates("unselectable_p", 0, EXT_STATE_SELECTABLE_TEXT | EXT_STATE_EDITABLE); + testStates("unselectable_link", 0, EXT_STATE_SELECTABLE_TEXT | EXT_STATE_EDITABLE); + + document.designMode = "off"; + + testStates(document, STATE_READONLY); + testStates("document", STATE_READONLY); + testStates("editable_document", 0, EXT_STATE_EDITABLE, STATE_READONLY); + + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + </script> +</head> + +<body role=""> + + <a target="_blank" + title="<body contenteditable='true'> exposed incorrectly" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=454997">Mozilla Bug 454997</a> + <a target="_blank" + title="nsIAccessible states tests of editable document" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=467387">Mozilla Bug 467387</a> + <a target="_blank" + title="Role attribute on body with empty string causes DocAccessible not to have read-only state." + href="https://bugzilla.mozilla.org/show_bug.cgi?id=509696">Mozilla Bug 509696</a> + <a target="_blank" + title="Frame for firefox does not implement the state "active" when firefox is the active frame" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=566542">Mozilla Bug 566542</a> + <a target="_blank" + title="Dynamic role attribute change on body doesn't affect on document role" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=607219">Mozilla Bug 607219</a> + + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"> + </pre> + + <p id="p">hello</p> + + <p id="unselectable_p" style="user-select: none;">unselectable <a id="unselectable_link" href="#">link</a></p> + + <div id="document" role="document">document</div> + <div id="editable_document" role="document" contentEditable="true">editable document</doc> + +</body> +</html> diff --git a/accessible/tests/mochitest/states/test_doc_busy.html b/accessible/tests/mochitest/states/test_doc_busy.html new file mode 100644 index 0000000000..d110faeb04 --- /dev/null +++ b/accessible/tests/mochitest/states/test_doc_busy.html @@ -0,0 +1,113 @@ +<!DOCTYPE html> +<html> +<head> + <title>states of document</title> + <link rel="stylesheet" type="text/css" + href="chrome://mochikit/content/tests/SimpleTest/test.css" /> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> + + <script type="application/javascript" + src="../common.js"></script> + <script type="application/javascript" + src="../role.js"></script> + <script type="application/javascript" + src="../states.js"></script> + <script type="application/javascript" + src="../promisified-events.js"></script> + + <script type="application/javascript"> + const { BrowserTestUtils } = ChromeUtils.import( + "resource://testing-common/BrowserTestUtils.jsm"); + + function matchDocBusyChange(isBusy) { + return function(event) { + const scEvent = event.QueryInterface(nsIAccessibleStateChangeEvent); + return ( + event.DOMNode == document && + scEvent.state === STATE_BUSY && + scEvent.isEnabled === isBusy + ); + }; + } + + async function doTest() { + // Because of variable timing, there are two acceptable possibilities: + // 1. We get an event for busy and an event for not busy. + // 2. The two events get coalesced, so no events are fired. + // However, we fail this test if we get the first event but not the + // second. + let gotBusy = false; + let gotNotBusy = false; + // We never actually wait on this; we just check the booleans it sets. + // We still need to hold a reference so it doesn't get garbage collected + // before it does anything. + // eslint-disable-next-line no-unused-vars + const busyEvents = async function() { + await waitForEvent(EVENT_STATE_CHANGE, matchDocBusyChange(true)); + info("Got busy event"); + gotBusy = true; + await waitForEvent(EVENT_STATE_CHANGE, matchDocBusyChange(false)); + info("Got not-busy event"); + gotNotBusy = true; + }(); + + const downloadPromptOpened = BrowserTestUtils.domWindowOpened(null, + async win => { + info("Window opened, waiting for load event"); + await BrowserTestUtils.waitForEvent(win, "load"); + info("Window loaded, checking if download prompt"); + return win.location && + win.location.href == "chrome://mozapps/content/downloads/unknownContentType.xhtml"; + } + ); + + info("Clicking link to trigger download"); + synthesizeMouse(getNode("link"), 1, 1, {}); + info("Waiting for download prompt to open"); + const downloadWin = await downloadPromptOpened; + + // Any busy events should have been fired by the time the download + // prompt has opened. + if (gotBusy && gotNotBusy) { + ok(true, "Got both busy change and not-busy change"); + } else if (!gotBusy && !gotNotBusy) { + ok(true, "No busy events, coalesced"); + } else { + ok(false, "Got busy change but didn't get not-busy change!"); + } + testStates(document, 0, 0, STATE_BUSY, 0, "Document not busy"); + + // Clean up. + info("Closing download prompt"); + downloadWin.close(); + // We might still be waiting on busy events. Remove any pending observers. + for (let observer of Services.obs.enumerateObservers( + "accessible-event") + ) { + Services.obs.removeObserver(observer, "accessible-event"); + } + + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + </script> +</head> + +<body> + + <a target="_blank" + title="Missing busy state change event when downloading files" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=446469">Bug 446469</a> + + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"> + </pre> + + <a id="link" href="http://example.com/a11y/accessible/tests/mochitest/dumbfile.zip">a file</a> +</body> +</html> diff --git a/accessible/tests/mochitest/states/test_docarticle.html b/accessible/tests/mochitest/states/test_docarticle.html new file mode 100644 index 0000000000..8e45d5ebd6 --- /dev/null +++ b/accessible/tests/mochitest/states/test_docarticle.html @@ -0,0 +1,78 @@ +<html> +<head> + <title>states of document article</title> + + <link rel="stylesheet" type="text/css" + href="chrome://mochikit/content/tests/SimpleTest/test.css" /> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <script type="application/javascript" + src="../common.js"></script> + <script type="application/javascript" + src="../role.js"></script> + <script type="application/javascript" + src="../states.js"></script> + + <script type="application/javascript"> + function doTest() { + var docAcc = getAccessible(document, [nsIAccessibleDocument]); + if (docAcc) { + testStates(docAcc, STATE_READONLY); + testStates("aria_article", STATE_READONLY); + testStates("editable_aria_article", 0, EXT_STATE_EDITABLE, + STATE_READONLY); + testStates("article", STATE_READONLY); + testStates("editable_article", 0, EXT_STATE_EDITABLE, STATE_READONLY); + + document.designMode = "on"; + + testStates(docAcc, 0, EXT_STATE_EDITABLE, STATE_READONLY); + testStates("aria_article", 0, EXT_STATE_EDITABLE, STATE_READONLY); + testStates("editable_aria_article", 0, EXT_STATE_EDITABLE, STATE_READONLY); + testStates("article", 0, EXT_STATE_EDITABLE, STATE_READONLY); + testStates("editable_article", 0, EXT_STATE_EDITABLE, STATE_READONLY); + + document.designMode = "off"; + + testStates(docAcc, STATE_READONLY); + testStates("aria_article", STATE_READONLY); + testStates("editable_aria_article", 0, EXT_STATE_EDITABLE, STATE_READONLY); + testStates("article", STATE_READONLY); + testStates("editable_article", 0, EXT_STATE_EDITABLE, STATE_READONLY); + } + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + </script> +</head> + +<body role="article"> + + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=467387" + title="Expose non-editable documents as readonly, regardless of role"> + Mozilla Bug 467387 + </a><br/> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=613502" + title="Map <article> like we do aria role article"> + Mozilla Bug 613502 + </a> + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"> + </pre> + + <div id="aria_article" role="article">aria article</div> + <div id="editable_aria_article" role="article" contentEditable="true"> + editable aria article</div> + + <article id="article">article</article> + <article id="editable_article" contentEditable="true"> + editable article</article> + +</body> +</html> diff --git a/accessible/tests/mochitest/states/test_editablebody.html b/accessible/tests/mochitest/states/test_editablebody.html new file mode 100644 index 0000000000..27b7201a2b --- /dev/null +++ b/accessible/tests/mochitest/states/test_editablebody.html @@ -0,0 +1,44 @@ +<!DOCTYPE html> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=454997 +--> +<head> + <title>nsIAccessible states tests of contenteditable body</title> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" /> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <script type="application/javascript" + src="../common.js"></script> + <script type="application/javascript" + src="../role.js"></script> + <script type="application/javascript" + src="../states.js"></script> + + <script type="application/javascript"> + function doTest() { + testStates(document, 0, EXT_STATE_EDITABLE); + testStates("p", 0, EXT_STATE_EDITABLE); + + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + </script> +</head> + +<body contentEditable="true"> + + <a target="_blank" + title="nsIAccessible states tests of contenteditable body" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=454997">Mozilla Bug 454997</a> + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"> + </pre> + + <p id="p">hello</p> +</body> +</html> diff --git a/accessible/tests/mochitest/states/test_expandable.xhtml b/accessible/tests/mochitest/states/test_expandable.xhtml new file mode 100644 index 0000000000..0d969bef5b --- /dev/null +++ b/accessible/tests/mochitest/states/test_expandable.xhtml @@ -0,0 +1,112 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> + +<!-- Firefox searchbar --> +<?xml-stylesheet href="chrome://browser/content/browser.css" + type="text/css"?> +<!-- SeaMonkey searchbar --> +<?xml-stylesheet href="chrome://navigator/content/navigator.css" + type="text/css"?> + +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + xmlns:html="http://www.w3.org/1999/xhtml" + title="Expanded state change events tests for comboboxes and autocompletes."> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js" /> + + <script type="application/javascript" + src="../autocomplete.js" /> + + <script type="application/javascript" + src="../common.js" /> + <script type="application/javascript" + src="../role.js" /> + <script type="application/javascript" + src="../states.js" /> + <script type="application/javascript" + src="../events.js" /> + + <script type="application/javascript"> + <![CDATA[ + //gA11yEventDumpToConsole = true; // debuggin + + var gQueue = null; + function doTest() + { + gQueue = new eventQueue(); + + gQueue.push(new openCombobox("menulist")); + gQueue.push(new closeCombobox("menulist")); + + todo(false, "Autocompletes don't fire expanded state change events when popup open. See bug 688480!"); + //gQueue.push(new openCombobox("autocomplete")); + //gQueue.push(new closeCombobox("autocomplete")); + + // XXX: searchbar doesn't fire state change events because accessible + // parent of combobox_list accessible is pushbutton accessible. + //var searchbar = document.getElementById("searchbar"); + //gQueue.push(new openHideCombobox(searchbar, true)); + //gQueue.push(new openHideCombobox(searchbar, false)); + todo(false, "Enable states test for XUL searchbar widget!"); + + gQueue.onFinish = function() + { + // unregister 'test-a11y-search' autocomplete search + shutdownAutoComplete(); + } + + gQueue.invoke(); // Will call SimpleTest.finish(); + } + + // This is the hacks needed to use a searchbar without browser.js. + var BrowserSearch = { + updateOpenSearchBadge() {} + }; + + SimpleTest.waitForExplicitFinish(); + + // Register 'test-a11y-search' autocomplete search. + // XPFE AutoComplete needs to register early. + initAutoComplete([ "hello", "hi" ], + [ "Beep beep'm beep beep yeah", "Baby you can drive my car" ]); + + addA11yLoadEvent(doTest); + ]]> + </script> + + <hbox style="overflow: auto;" flex="1"> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=467057" + title="xul menulist doesn't fire expand/collapse state change events"> + Mozilla Bug 467057 + </a> + <p id="display"></p> + <div id="content" style="display: none"> + </div> + <pre id="test"> + </pre> + </body> + + <vbox flex="1"> + <menulist id="menulist"> + <menupopup> + <menuitem label="item1"/> + <menuitem label="item2"/> + <menuitem label="item3"/> + </menupopup> + </menulist> + + <html:input is="autocomplete-input" + id="autocomplete" + autocompletesearch="test-a11y-search"/> + + <searchbar id="searchbar"/> + </vbox> + </hbox> + +</window> + diff --git a/accessible/tests/mochitest/states/test_frames.html b/accessible/tests/mochitest/states/test_frames.html new file mode 100644 index 0000000000..baac222d83 --- /dev/null +++ b/accessible/tests/mochitest/states/test_frames.html @@ -0,0 +1,93 @@ +<html> + +<head> + <title>frame based document testing</title> + + <link rel="stylesheet" type="text/css" + href="chrome://mochikit/content/tests/SimpleTest/test.css" /> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <script type="application/javascript" + src="../common.js"></script> + <script type="application/javascript" + src="../role.js"></script> + <script type="application/javascript" + src="../states.js"></script> + + <script type="application/javascript"> + if (navigator.platform.startsWith("Win")) { + SimpleTest.expectAssertions(0, 2); + } + + function doTest() { + const frameDoc = document.getElementById("frame_doc").contentDocument; + const frameDocArticle = document.getElementById("frame_doc_article").contentDocument; + const frameDocCheckbox = document.getElementById("frame_doc_checkbox").contentDocument; + const frameDocTextbox = document.getElementById("frame_doc_textbox").contentDocument; + + testStates(frameDoc, STATE_READONLY, 0, 0, 0, + "test1: frameDoc"); + testStates(frameDocArticle, STATE_READONLY, 0, 0, 0, + "test1: frameDocArticle"); + testStates(frameDocCheckbox, STATE_READONLY, 0, 0, 0, + "test1: frameDocCheckbox"); + testStates(frameDocTextbox, STATE_READONLY, 0, 0, 0, + "test1: frameDocTextbox"); + frameDoc.designMode = "on"; + testStates(frameDoc, 0, EXT_STATE_EDITABLE, STATE_READONLY, 0, + "test2: frameDoc"); + testStates(frameDocArticle, STATE_READONLY, 0, 0, 0, + "test2: frameDocArticle"); + testStates(frameDocCheckbox, STATE_READONLY, 0, 0, 0, + "test2: frameDocCheckbox"); + testStates(frameDocTextbox, STATE_READONLY, 0, 0, 0, + "test2: frameDocTextbox"); + + frameDocArticle.designMode = "on"; + testStates(frameDocArticle, 0, EXT_STATE_EDITABLE, STATE_READONLY, 0, + "test3: frameDocArticle"); + + frameDocCheckbox.designMode = "on"; + testStates(frameDocCheckbox, 0, EXT_STATE_EDITABLE, STATE_READONLY, 0, + "test4: frameDocCheckbox"); + + // Replace iframe document body before the document accessible tree is + // created. Check the states are updated for new body. + var frameUpdateDoc = + document.getElementById("frame_updatedoc").contentDocument; + testStates(frameUpdateDoc, 0, EXT_STATE_EDITABLE, + STATE_READONLY, EXT_STATE_STALE, "test5: frameUpdateDoc"); + + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + </script> +</head> + +<body> + + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=467387" + title="Expose non-editable documents as readonly, regardless of role"> + Mozilla Bug 467387 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=638106" + title="CKEditor document should be editable"> + Mozilla Bug 638106 + </a> + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"> + </pre> + + <iframe id="frame_doc" src="z_frames.html"></iframe> + <iframe id="frame_doc_article" src="z_frames_article.html"></iframe> + <iframe id="frame_doc_checkbox" src="z_frames_checkbox.html"></iframe> + <iframe id="frame_doc_textbox" src="z_frames_textbox.html"></iframe> + <iframe id="frame_updatedoc" src="z_frames_update.html"></iframe> +</body> +</html> diff --git a/accessible/tests/mochitest/states/test_inputs.html b/accessible/tests/mochitest/states/test_inputs.html new file mode 100644 index 0000000000..d9b9014a34 --- /dev/null +++ b/accessible/tests/mochitest/states/test_inputs.html @@ -0,0 +1,268 @@ +<!DOCTYPE html> +<html> +<head> + <title>HTML input states</title> + <link rel="stylesheet" type="text/css" + href="chrome://mochikit/content/tests/SimpleTest/test.css" /> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> + + <script type="application/javascript" + src="../common.js"></script> + <script type="application/javascript" + src="../role.js"></script> + <script type="application/javascript" + src="../states.js"></script> + + <script type="application/javascript"> + function doTest() { + // ////////////////////////////////////////////////////////////////////////// + // 'editable' and 'multiline' states. + testStates("input", 0, EXT_STATE_EDITABLE, 0, EXT_STATE_MULTI_LINE); + testStates("textarea", 0, EXT_STATE_EDITABLE | EXT_STATE_MULTI_LINE); + + testStates("input_readonly", 0, EXT_STATE_EDITABLE); + testStates("input_disabled", 0, EXT_STATE_EDITABLE); + testStates("textarea_readonly", 0, EXT_STATE_EDITABLE); + testStates("textarea_disabled", 0, EXT_STATE_EDITABLE); + + // ////////////////////////////////////////////////////////////////////////// + // 'required', 'readonly' and 'unavailable' states. + var maybe_required = ["input", "search", "radio", "checkbox", "textarea"]; + var never_required = ["submit", "button", "reset", "image"]; + + var i; + for (i in maybe_required) { + testStates(maybe_required[i], + STATE_FOCUSABLE, 0, + STATE_REQUIRED | STATE_READONLY | STATE_UNAVAILABLE); + + testStates(maybe_required[i] + "_required", + STATE_FOCUSABLE | STATE_REQUIRED, 0, + STATE_UNAVAILABLE | STATE_READONLY); + + var readonlyID = maybe_required[i] + "_readonly"; + if (document.getElementById(readonlyID)) { + testStates(readonlyID, + STATE_FOCUSABLE | STATE_READONLY, 0, + STATE_UNAVAILABLE | STATE_REQUIRED); + } + + testStates(maybe_required[i] + "_disabled", + STATE_UNAVAILABLE, 0, + STATE_FOCUSABLE | STATE_READONLY | STATE_REQUIRED); + } + + for (i in never_required) { + testStates(never_required[i], 0, 0, STATE_REQUIRED | EXT_STATE_EDITABLE); + } + + // ////////////////////////////////////////////////////////////////////////// + // inherited 'unavailable' state + testStates("f", STATE_UNAVAILABLE); + testStates("f_input", STATE_UNAVAILABLE); + testStates("f_input_disabled", STATE_UNAVAILABLE); + + // ////////////////////////////////////////////////////////////////////////// + // inherited from file control + var fileBrowseButton = getAccessible("file").firstChild; + testStates(fileBrowseButton, STATE_UNAVAILABLE | STATE_REQUIRED); + // No states on the label. + + // ////////////////////////////////////////////////////////////////////////// + // 'invalid' state + var invalid = ["pattern", "email", "url"]; + for (i in invalid) { + testStates(invalid[i], STATE_INVALID); + testStates(invalid[i] + "2", 0, 0, STATE_INVALID); + } + + // ////////////////////////////////////////////////////////////////////////// + // not 'invalid' state + // (per spec, min/maxlength are always valid until interactively edited) + var validInput = document.createElement("input"); + validInput.maxLength = "0"; + validInput.value = "a"; + ok(validInput.validity.valid, + "input should be valid despite maxlength (no interactive edits)"); + + var validInput2 = document.createElement("input"); + validInput2.minLength = "1"; + validInput2.value = ""; + ok(validInput2.validity.valid, + "input should be valid despite minlength (no interactive edits)"); + + var valid = ["minlength", "maxlength"]; + for (i in valid) { + testStates(valid[i], 0, 0, STATE_INVALID); + testStates(valid[i] + "2", 0, 0, STATE_INVALID); + } + + // ////////////////////////////////////////////////////////////////////////// + // 'invalid' state + // (per spec, min/maxlength validity is affected by interactive edits) + var mininp = document.getElementById("minlength"); + mininp.focus(); + mininp.setSelectionRange(mininp.value.length, mininp.value.length); + synthesizeKey("KEY_Backspace"); + ok(!mininp.validity.valid, + "input should be invalid after interactive edits"); + testStates(mininp, STATE_INVALID); + // inputs currently cannot be made longer than maxlength interactively, + // so we're not testing that case. + + // ////////////////////////////////////////////////////////////////////////// + // autocomplete states + testStates("autocomplete-default", 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION); + testStates("autocomplete-off", 0, 0, 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION); + testStates("autocomplete-formoff", 0, 0, 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION); + testStates("autocomplete-list", 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION); + testStates("autocomplete-list2", 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION); + testStates("autocomplete-tel", 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION); + testStates("autocomplete-email", 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION); + testStates("autocomplete-search", 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION); + + // ////////////////////////////////////////////////////////////////////////// + // haspopup + testStates("autocomplete-list", STATE_HASPOPUP); + + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + </script> +</head> + +<body> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=559275" + title="map attribute required to STATE_REQUIRED"> + Bug 559275 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=389238" + title="Support disabled state on fieldset"> + Bug 389238 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=599163" + title="check disabled state instead of attribute"> + Bug 599163 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=601205" + title="Expose intrinsic invalid state to accessibility API"> + Bug 601205 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=601205" + title="Expose intrinsic invalid state to accessibility API"> + Bug 601205 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=559766" + title="Add accessibility support for @list on HTML input and for HTML datalist"> + Bug 559766 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=699017" + title="File input control should be propogate states to descendants"> + Bug 699017 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=733382" + title="Editable state bit should be present on readonly inputs"> + Bug 733382 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=878590" + title="HTML5 datalist is not conveyed by haspopup property"> + Bug 878590 + </a> + + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"> + </pre> + + + <form> + <input id="input" type="input"> + <input id="input_required" type="input" required> + <input id="input_readonly" type="input" readonly> + <input id="input_disabled" type="input" disabled> + <input id="search" type="search"> + <input id="search_required" type="search" required> + <input id="search_readonly" type="search" readonly> + <input id="search_disabled" type="search" disabled> + <input id="radio" type="radio"> + <input id="radio_required" type="radio" required> + <input id="radio_disabled" type="radio" disabled> + <input id="checkbox" type="checkbox"> + <input id="checkbox_required" type="checkbox" required> + <input id="checkbox_disabled" type="checkbox" disabled> + <textarea id="textarea"></textarea> + <textarea id="textarea_required" required></textarea> + <textarea id="textarea_readonly" readonly></textarea> + <textarea id="textarea_disabled" disabled></textarea> + </form> + + <!-- bogus required usage --> + <input id="submit" type="submit" required> + <input id="button" type="button" required> + <input id="reset" type="reset" required> + <input id="image" type="image" required> + + <!-- inherited disabled --> + <fieldset id="f" disabled> + <input id="f_input"> + <input id="f_input_disabled" disabled> + </fieldset> + + <!-- inherited from input@type="file" --> + <input id="file" type="file" required disabled> + + <!-- invalid/valid --> + <input id="maxlength" maxlength="1" value="f"> + <input id="maxlength2" maxlength="100" value="foo"> + <input id="minlength" minlength="2" value="fo"> + <input id="minlength2" minlength="1" value="foo"> + <input id="pattern" pattern="bar" value="foo"> + <input id="pattern2" pattern="bar" value="bar"> + <input id="email" type="email" value="foo"> + <input id="email2" type="email" value="foo@bar.com"> + <input id="url" type="url" value="foo"> + <input id="url2" type="url" value="http://mozilla.org/"> + + <!-- autocomplete --> + <input id="autocomplete-default"> + <input id="autocomplete-off" autocomplete="off"> + <form autocomplete="off"> + <input id="autocomplete-formoff"> + </form> + <datalist id="cities"> + <option>Paris</option> + <option>San Francisco</option> + </datalist> + <input id="autocomplete-list" list="cities"> + <input id="autocomplete-list2" list="cities" autocomplete="off"> + <input id="autocomplete-tel" type="tel"> + + Email Address: + <input id="autocomplete-email" type="email" list="contacts" value="xyzzy"> + <datalist id="contacts"> + <option>xyzzy@plughs.com</option> + <option>nobody@mozilla.org</option> + </datalist> + + </br>Search for: + <input id="autocomplete-search" type="search" list="searchhisty" value="Gamma"> + <datalist id="searchhisty"> + <option>Gamma Rays</option> + <option>Gamma Ray Bursts</option> + </datalist> + + </body> +</html> diff --git a/accessible/tests/mochitest/states/test_link.html b/accessible/tests/mochitest/states/test_link.html new file mode 100644 index 0000000000..65632bd12f --- /dev/null +++ b/accessible/tests/mochitest/states/test_link.html @@ -0,0 +1,85 @@ +<html> + +<head> + <title>HTML link states testing</title> + + <link rel="stylesheet" type="text/css" + href="chrome://mochikit/content/tests/SimpleTest/test.css" /> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> + + <script type="application/javascript" + src="../common.js"></script> + <script type="application/javascript" + src="../role.js"></script> + <script type="application/javascript" + src="../states.js"></script> + <script type="application/javascript" + src="../events.js"></script> + + <script type="application/javascript"> + function doTest() { + // a@href and its text node + testStates("link_href", STATE_LINKED); + testStates(getAccessible("link_href").firstChild, STATE_LINKED); + + // a@onclick + testStates("link_click", STATE_LINKED); + + // a@onmousedown + testStates("link_mousedown", STATE_LINKED); + + // a@onmouseup + testStates("link_mouseup", STATE_LINKED); + + // a@role="link" + testStates("link_arialink", STATE_LINKED); + + // a@role="button" + testStates("link_ariabutton", 0, 0, STATE_LINKED); + + // a (no @href, no click event listener) + testStates("link_notlink", 0, 0, STATE_LINKED); + + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + </script> + +</head> + +<body> + + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=423409" + title="Expose click action if mouseup and mousedown are registered"> + Mozilla Bug 423409 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=754830" + title="Calculate link states separately"> + Mozilla Bug 754830 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=757774" + title="Fire state change event when link is traversed"> + Mozilla Bug 757774 + </a> + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"> + </pre> + + <a id="link_href" href="http://mozilla.org">link</a> + <a id="link_click" onclick="">link</a> + <a id="link_mousedown" onmousedown="">link</a> + <a id="link_mouseup" onmouseup="">link</a> + <a id="link_arialink" role="link">aria link</a> + <a id="link_ariabutton" role="button">aria button</a> + <a id="link_notlink">not link</a> + +</body> +</html> diff --git a/accessible/tests/mochitest/states/test_popup.xhtml b/accessible/tests/mochitest/states/test_popup.xhtml new file mode 100644 index 0000000000..c51e3ac17c --- /dev/null +++ b/accessible/tests/mochitest/states/test_popup.xhtml @@ -0,0 +1,54 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> + +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="XUL popup attribute test"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + + <script type="application/javascript" + src="../common.js" /> + <script type="application/javascript" + src="../role.js" /> + <script type="application/javascript" + src="../states.js" /> + + <script type="application/javascript"> + <![CDATA[ + function doTest() + { + // label with popup + testStates("labelWithPopup", STATE_HASPOPUP); + + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + ]]> + </script> + + <hbox flex="1" style="overflow: auto;"> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=504252" + title="Expose STATE_HASPOPUP on XUL elements that have an @popup attribute"> + Mozilla Bug 504252 + </a><br/> + <p id="display"></p> + <div id="content" style="display: none"> + </div> + <pre id="test"> + </pre> + </body> + + <!-- label with popup attribute --> + <label id="labelWithPopup" value="file name" + popup="fileContext" + tabindex="0"/> + </hbox> + +</window> + diff --git a/accessible/tests/mochitest/states/test_selects.html b/accessible/tests/mochitest/states/test_selects.html new file mode 100644 index 0000000000..37ff568458 --- /dev/null +++ b/accessible/tests/mochitest/states/test_selects.html @@ -0,0 +1,196 @@ +<html> + +<head> + <title>HTML selects accessible states tests</title> + <link rel="stylesheet" type="text/css" + href="chrome://mochikit/content/tests/SimpleTest/test.css" /> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> + + <script type="application/javascript" + src="../common.js"></script> + <script type="application/javascript" + src="../role.js"></script> + <script type="application/javascript" + src="../states.js"></script> + <script type="application/javascript" + src="../events.js"></script> + + <script type="application/javascript"> + function openComboboxNCheckStates(aID) { + this.combobox = getAccessible(aID); + this.comboboxList = this.combobox.firstChild; + this.comboboxOption = this.comboboxList.firstChild; + + this.eventSeq = [ + new invokerChecker(EVENT_FOCUS, this.comboboxOption), + ]; + + this.invoke = function openComboboxNCheckStates_invoke() { + getNode(aID).focus(); + synthesizeKey("VK_DOWN", { altKey: true }); + }; + + this.finalCheck = function openComboboxNCheckStates_invoke() { + // Expanded state on combobox. + testStates(this.combobox, STATE_EXPANDED); + + // Floating state on combobox list. + testStates(this.comboboxList, STATE_FLOATING); + }; + + this.getID = function openComboboxNCheckStates_getID() { + return "open combobox and test states"; + }; + } + + // gA11yEventDumpToConsole = true; + + var gQueue = null; + function doTest() { + // combobox + var combobox = getAccessible("combobox"); + testStates(combobox, + STATE_HASPOPUP | STATE_COLLAPSED | STATE_FOCUSABLE, 0, + STATE_FOCUSED, 0); + + var comboboxList = combobox.firstChild; + testStates(comboboxList, STATE_INVISIBLE, 0, STATE_FOCUSABLE, 0); + + var opt1 = comboboxList.firstChild; + testStates(opt1, STATE_SELECTABLE | STATE_SELECTED | STATE_FOCUSABLE, + EXT_STATE_ACTIVE, STATE_FOCUSED, 0); + + var opt2 = comboboxList.lastChild; + testStates(opt2, STATE_SELECTABLE | STATE_FOCUSABLE, 0, STATE_SELECTED, 0, + STATE_FOCUSED, EXT_STATE_ACTIVE); + + // collapsed combobox + testStates("collapsedcombobox", + STATE_COLLAPSED | STATE_FOCUSABLE, 0, + STATE_FOCUSED, 0); + + testStates("collapsed-1", + STATE_FOCUSABLE | STATE_SELECTABLE, 0, + STATE_OFFSCREEN | STATE_INVISIBLE, 0); + + testStates("collapsed-2", + STATE_OFFSCREEN, 0, + STATE_INVISIBLE, 0); + + // listbox + testStates("listbox", + STATE_FOCUSABLE, 0, + STATE_HASPOPUP | STATE_COLLAPSED | STATE_FOCUSED); + + testStates("listitem-active", + STATE_FOCUSABLE | STATE_SELECTABLE, EXT_STATE_ACTIVE, + STATE_SELECTED | STATE_FOCUSED); + + testStates("listitem", + STATE_FOCUSABLE | STATE_SELECTABLE, 0, + STATE_SELECTED | STATE_FOCUSED, EXT_STATE_ACTIVE); + + testStates("listitem-disabled", + STATE_UNAVAILABLE, 0, + STATE_SELECTABLE | STATE_SELECTED | STATE_FOCUSABLE, + EXT_STATE_ACTIVE); + + testStates("listgroup", + 0, 0, + STATE_UNAVAILABLE | STATE_SELECTABLE | STATE_SELECTED | STATE_FOCUSABLE, + EXT_STATE_ACTIVE); + + testStates("listgroup-disabled", + STATE_UNAVAILABLE, 0, + STATE_SELECTABLE | STATE_SELECTED | STATE_FOCUSABLE, + EXT_STATE_ACTIVE); + + todo(false, "no unavailable state on option in disabled group (bug 759666)"); +// testStates("listitem-disabledgroup", +// STATE_UNAVAILABLE, 0, +// STATE_SELECTABLE | STATE_SELECTED | STATE_FOCUSABLE, +// EXT_STATE_ACTIVE); + + testStates("listbox-disabled", + STATE_UNAVAILABLE, 0, + STATE_FOCUSABLE); + + todo(false, "no unavailable state on option in disabled select (bug 759666)"); +// testStates("listitem-disabledlistbox", +// STATE_UNAVAILABLE, 0, +// STATE_SELECTABLE | STATE_SELECTED | STATE_FOCUSABLE, +// EXT_STATE_ACTIVE); + + // open combobox + gQueue = new eventQueue(); + gQueue.push(new openComboboxNCheckStates("combobox")); + gQueue.invoke(); // Will call */SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(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> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=640716" + title="mochitest for selects and lists"> + Mozilla Bug 640716 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=689847" + title="Expose active state on current item of selectable widgets"> + Mozilla Bug 689847 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=756983" + title="Isolate focusable and unavailable states from State()"> + Mozilla Bug 756983 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=907682" + title=" HTML:option group position is not correct when select is collapsed"> + Mozilla Bug 907682 + </a> + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"> + </pre> + + <select id="combobox"> + <option>item 1</option> + <option>item 2</option> + </select> + + <select id="collapsedcombobox"> + <option id="collapsed-1">item 1</option> + <option id="collapsed-2">item 2</option> + </select> + + <select id="listbox" name="component" size="3"> + <option id="listitem-active">Build</option> + <option id="listitem">Disability Access APIs</option> + <option id="listitem-disabled" disabled>General</option> + <optgroup id="listgroup" label="group"> + <option>option</option> + </optgroup> + <optgroup id="listgroup-disabled" disabled label="group2"> + <option id="listitem-disabledgroup">UI</option> + </optgroup> + </select> + + <select id="listbox-disabled" size="3" disabled> + <option id="listitem-disabledlistbox">option</option> + </select> + +</body> +</html> diff --git a/accessible/tests/mochitest/states/test_stale.html b/accessible/tests/mochitest/states/test_stale.html new file mode 100644 index 0000000000..3218a2125a --- /dev/null +++ b/accessible/tests/mochitest/states/test_stale.html @@ -0,0 +1,108 @@ +<!DOCTYPE html> +<html> +<head> + <title>Stale state testing</title> + <link rel="stylesheet" type="text/css" + href="chrome://mochikit/content/tests/SimpleTest/test.css" /> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <script type="application/javascript" + src="../common.js"></script> + <script type="application/javascript" + src="../role.js"></script> + <script type="application/javascript" + src="../states.js"></script> + <script type="application/javascript" + src="../events.js"></script> + + <script type="application/javascript"> + function addChild(aContainerID) { + this.containerNode = getNode(aContainerID); + this.childNode = null; + + this.eventSeq = [ + new invokerChecker(EVENT_REORDER, this.containerNode), + ]; + + this.invoke = function addChild_invoke() { + this.childNode = document.createElement("div"); + // Note after bug 646216, a sole div without text won't be accessible + // and would not result in an embedded character. + // Therefore, add some text. + this.childNode.textContent = "hello"; + this.containerNode.appendChild(this.childNode); + }; + + this.finalCheck = function addChild_finalCheck() { + // no stale state should be set + testStates(this.childNode, 0, 0, 0, EXT_STATE_STALE); + }; + + this.getID = function addChild_getID() { + return "add child for " + prettyName(aContainerID); + }; + } + + function removeChildChecker(aInvoker) { + this.type = EVENT_HIDE; + this.__defineGetter__("target", function() { return aInvoker.child; }); + + this.check = function removeChildChecker_check() { + // stale state should be set + testStates(aInvoker.child, 0, EXT_STATE_STALE); + }; + } + + function removeChild(aContainerID) { + this.containerNode = getNode(aContainerID); + this.child = null; + + this.eventSeq = [ + new removeChildChecker(this), + ]; + + this.invoke = function removeChild_invoke() { + var childNode = this.containerNode.firstChild; + this.child = getAccessible(childNode); + + this.containerNode.removeChild(childNode); + }; + + this.getID = function removeChild_getID() { + return "remove child from " + prettyName(aContainerID); + }; + } + + // gA11yEventDumpToConsole = true; //debugging + + var gQueue = null; + function doTest() { + gQueue = new eventQueue(); + + gQueue.push(new addChild("container")); + gQueue.push(new removeChild("container")); + + gQueue.invoke(); // will call SimpleTest.finish() + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + </script> +</head> + +<body role=""> + + <a target="_blank" + title="Expose stale state on accessibles unattached from tree" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=676267">Mozilla Bug 676267</a> + + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"> + </pre> + + <div id="container"></div> + +</body> +</html> diff --git a/accessible/tests/mochitest/states/test_tabs.xhtml b/accessible/tests/mochitest/states/test_tabs.xhtml new file mode 100644 index 0000000000..4d8a83c97d --- /dev/null +++ b/accessible/tests/mochitest/states/test_tabs.xhtml @@ -0,0 +1,66 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> + +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="Accessible XUL tabbox hierarchy tests"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + + <script type="application/javascript" + src="../common.js" /> + <script type="application/javascript" + src="../role.js" /> + <script type="application/javascript" + src="../states.js" /> + + <script type="application/javascript"> + <![CDATA[ + //////////////////////////////////////////////////////////////////////////// + // Test + + function doTest() + { + testStates("tab1", 0, EXT_STATE_PINNED); + testStates("tab2", 0, 0, 0, EXT_STATE_PINNED); + testStates("tab3", 0, 0, 0, EXT_STATE_PINNED); + + SimpleTest.finish() + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + ]]> + </script> + + <hbox flex="1" style="overflow: auto;"> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=577727" + title="Make pinned tabs distinguishable from other tabs for accessibility"> + Mozilla Bug 577727 + </a><br/> + <p id="display"></p> + <div id="content" style="display: none"> + </div> + <pre id="test"> + </pre> + </body> + + <vbox flex="1"> + <tabbox> + <tabs id="tabs"> + <tab id="tab1" label="tab1" pinned="true"/> + <tab id="tab2" label="tab2" pinned="false"/> + <tab id="tab3" label="tab3"/> + </tabs> + <tabpanels id="tabpanels"> + <tabpanel/> + <tabpanel/> + </tabpanels> + </tabbox> + </vbox> + </hbox> + +</window> diff --git a/accessible/tests/mochitest/states/test_textbox.xhtml b/accessible/tests/mochitest/states/test_textbox.xhtml new file mode 100644 index 0000000000..764c1ad01c --- /dev/null +++ b/accessible/tests/mochitest/states/test_textbox.xhtml @@ -0,0 +1,78 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> + +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="nsIAccessible XUL textboxes states tests"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + + <script type="application/javascript" + src="../common.js" /> + <script type="application/javascript" + src="../role.js" /> + <script type="application/javascript" + src="../states.js" /> + + <script type="application/javascript"> + <![CDATA[ + function getInput(aID) + { + return getNode(aID).inputField; + } + + function doTest() + { + ////////////////////////////////////////////////////////////////////////// + // Search textbox without search button, searches as you type and filters + // a separate control. + testStates(getInput("searchbox"), + STATE_FOCUSABLE, + EXT_STATE_EDITABLE | EXT_STATE_SUPPORTS_AUTOCOMPLETION, + STATE_PROTECTED | STATE_UNAVAILABLE, + 0, + "searchbox"); + + ////////////////////////////////////////////////////////////////////////// + // Search textbox with search button, does not support autoCompletion. + testStates(getInput("searchfield"), + STATE_FOCUSABLE, + EXT_STATE_EDITABLE, + STATE_PROTECTED | STATE_UNAVAILABLE, + 0, + "searchfield"); + + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + ]]> + </script> + + <hbox flex="1" style="overflow: auto;"> + + <body xmlns="http://www.w3.org/1999/xhtml"> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=442648"> + Mozilla Bug 442648 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=648235" + title="XUL textbox can inherit more states from underlying HTML input"> + Mozilla Bug 648235 + </a> + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"> + </pre> + </body> + + <vbox flex="1"> + <search-textbox id="searchbox" flex="1" results="historyTree"/> + <search-textbox id="searchfield" placeholder="Search all add-ons" + searchbutton="true"/> + </vbox> + </hbox> +</window> diff --git a/accessible/tests/mochitest/states/test_tree.xhtml b/accessible/tests/mochitest/states/test_tree.xhtml new file mode 100644 index 0000000000..d81be4a54b --- /dev/null +++ b/accessible/tests/mochitest/states/test_tree.xhtml @@ -0,0 +1,146 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<?xml-stylesheet href="../treeview.css" + type="text/css"?> + +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="Accessible XUL tree states tests"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + + <script type="application/javascript" + src="../treeview.js" /> + + <script type="application/javascript" + src="../common.js" /> + <script type="application/javascript" + src="../role.js" /> + <script type="application/javascript" + src="../states.js" /> + <script type="application/javascript" + src="../events.js" /> + + <script type="application/javascript"> + <![CDATA[ + //////////////////////////////////////////////////////////////////////////// + // Test + + /** + * Event queue invoker object to test accessible states for XUL tree + * accessible. + */ + function statesChecker(aTreeID, aView) + { + this.DOMNode = getNode(aTreeID); + + this.invoke = function statesChecker_invoke() + { + this.DOMNode.view = aView; + } + + this.check = function statesChecker_check() + { + var tree = getAccessible(this.DOMNode); + + // tree states + testStates(tree, STATE_READONLY); + + if (this.DOMNode.getAttribute("seltype") != "single") + testStates(tree, STATE_MULTISELECTABLE); + else + testStates(tree, 0, 0, STATE_MULTISELECTABLE); + + // tree item states + var expandedItem = tree.getChildAt(2); + testStates(expandedItem, + STATE_SELECTABLE | STATE_FOCUSABLE | STATE_EXPANDED); + + var collapsedItem = tree.getChildAt(5); + testStates(collapsedItem, + STATE_SELECTABLE | STATE_FOCUSABLE | STATE_COLLAPSED); + + // cells states if any + var cells = collapsedItem.children; + if (cells && cells.length) { + for (var idx = 0; idx < cells.length; idx++) { + var cell = cells.queryElementAt(idx, nsIAccessible); + testStates(cell, STATE_SELECTABLE); + } + + var checkboxCell = cells.queryElementAt(3, nsIAccessible); + testStates(checkboxCell, STATE_CHECKABLE | STATE_CHECKED); + } + } + + this.getID = function statesChecker_getID() + { + return "tree processor for " + prettyName(aTreeID); + } + } + + gA11yEventDumpToConsole = true; // debug stuff + + var gQueue = null; + + function doTest() + { + gQueue = new eventQueue(EVENT_REORDER); + gQueue.push(new statesChecker("tree", new nsTreeTreeView())); + gQueue.push(new statesChecker("treesingle", new nsTreeTreeView())); + gQueue.push(new statesChecker("tabletree", new nsTreeTreeView())); + + gQueue.invoke(); // Will call SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + ]]> + </script> + + <hbox flex="1" style="overflow: auto;"> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=503727" + title="Reorganize implementation of XUL tree accessibility"> + Mozilla Bug 503727 + </a><br/> + <p id="display"></p> + <div id="content" style="display: none"> + </div> + <pre id="test"> + </pre> + </body> + + <vbox flex="1"> + <tree id="tree" flex="1"> + <treecols> + <treecol id="col" flex="1" primary="true" label="column"/> + </treecols> + <treechildren/> + </tree> + + <tree id="treesingle" flex="1" seltype="single"> + <treecols> + <treecol id="col_single" flex="1" primary="true" label="column"/> + </treecols> + <treechildren/> + </tree> + + <tree id="tabletree" flex="1" editable="true"> + <treecols> + <treecol id="tabletree_col1" cycler="true" label="cycler"/> + <treecol id="tabletree_col2" flex="1" primary="true" label="column1"/> + <treecol id="tabletree_col3" flex="1" label="column2"/> + <treecol id="tabletree_col4" flex="1" label="checker" + type="checkbox" editable="true"/> + </treecols> + <treechildren/> + </tree> + + <vbox id="debug"/> + </vbox> + </hbox> + +</window> diff --git a/accessible/tests/mochitest/states/test_visibility.html b/accessible/tests/mochitest/states/test_visibility.html new file mode 100644 index 0000000000..aa3643673a --- /dev/null +++ b/accessible/tests/mochitest/states/test_visibility.html @@ -0,0 +1,75 @@ +<html> +<head> + <title>visibility state testing</title> + + <link rel="stylesheet" type="text/css" + href="chrome://mochikit/content/tests/SimpleTest/test.css" /> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <script type="application/javascript" + src="../common.js"></script> + <script type="application/javascript" + src="../role.js"></script> + <script type="application/javascript" + src="../states.js"></script> + + <script type="application/javascript"> + // Tests + + function doTests() { + testStates("div", 0, 0, STATE_INVISIBLE | STATE_OFFSCREEN); + testStates("div_off", STATE_OFFSCREEN, 0, STATE_INVISIBLE); + testStates("div_transformed", STATE_OFFSCREEN, 0, STATE_INVISIBLE); + testStates("div_abschild", 0, 0, STATE_INVISIBLE | STATE_OFFSCREEN); + testStates("ul", STATE_OFFSCREEN, 0, STATE_INVISIBLE); + + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTests); + </script> + +</head> + +<body> + + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=591363" + title="(in)visible state is not always correct?"> + Mozilla Bug 591363 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=768786" + title="Offscreen state is not exposed under certain circumstances"> + Mozilla Bug 768786 + </a> + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"> + </pre> + + <div id="outer_div"> + + <!-- trivial cases --> + <div id="div">div</div> + <div id="div_off" style="position: absolute; left:-999px; top:-999px"> + offscreen! + </div> + <div id="div_transformed" style="transform: translate(-999px, -999px);"> + transformed! + </div> + + <!-- edge case: no rect but has out of flow child --> + <div id="div_abschild"> + <p style="position: absolute; left: 120px; top:120px;">absolute</p> + </div> + + <ul id="ul" style="display: contents;"> + <li>Supermarket 1</li> + <li>Supermarket 2</li> + </ul> + </div> +</body> +</html> diff --git a/accessible/tests/mochitest/states/test_visibility.xhtml b/accessible/tests/mochitest/states/test_visibility.xhtml new file mode 100644 index 0000000000..28d8c995db --- /dev/null +++ b/accessible/tests/mochitest/states/test_visibility.xhtml @@ -0,0 +1,151 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> + +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="XUL elements visibility states testing"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + + <script type="application/javascript" + src="../common.js" /> + <script type="application/javascript" + src="../role.js" /> + <script type="application/javascript" + src="../states.js" /> + <script type="application/javascript" + src="../events.js" /> + + <script type="application/javascript"> + <![CDATA[ + function openMenu(aID, aSubID, aOffscreenSubID) + { + this.menuNode = getNode(aID); + + this.eventSeq = [ + new invokerChecker(EVENT_FOCUS, this.menuNode) + ]; + + this.invoke = function openMenu_invoke() + { + this.menuNode.open = true; + } + + this.finalCheck = function openMenu_finalCheck() + { + testStates(aID, 0, 0, STATE_INVISIBLE | STATE_OFFSCREEN); + testStates(aSubID, 0, 0, STATE_INVISIBLE | STATE_OFFSCREEN); + if (aOffscreenSubID) + testStates(aOffscreenSubID, STATE_OFFSCREEN, 0, STATE_INVISIBLE); + } + + this.getID = function openMenu_invoke() + { + return "open menu '" + aID + "' and test states"; + } + } + + function closeMenu(aID, aSubID, aSub2ID) + { + this.menuNode = getNode(aID); + + this.eventSeq = [ + new invokerChecker(EVENT_FOCUS, document) + ]; + + this.invoke = function openMenu_invoke() + { + this.menuNode.open = false; + } + + this.finalCheck = function openMenu_finalCheck() + { + testStates(aID, 0, 0, STATE_INVISIBLE | STATE_OFFSCREEN); + testStates(aSubID, STATE_INVISIBLE, 0, STATE_OFFSCREEN); + testStates(aSub2ID, STATE_INVISIBLE, 0, STATE_OFFSCREEN); + } + + this.getID = function openMenu_invoke() + { + return "open menu and test states"; + } + } + + var gQueue = null; + function doTest() + { + testStates("deck_pane2", 0, 0, STATE_INVISIBLE | STATE_OFFSCREEN); + testStates("tabs_pane1", 0, 0, STATE_INVISIBLE | STATE_OFFSCREEN); + testStates("tabs_pane2", STATE_OFFSCREEN, 0, STATE_INVISIBLE); + + gQueue = new eventQueue(); + gQueue.push(new openMenu("mi_file1", "mi_file1.1")); + gQueue.push(new openMenu("mi_file1.2", "mi_file1.2.1", "mi_file1.2.4")); + gQueue.push(new closeMenu("mi_file1", "mi_file1.1", "mi_file1.2.1")); + gQueue.invoke(); // Will call SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + ]]> + </script> + + <hbox flex="1" style="overflow: auto;"> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=810260" + title="xul:deck hidden pages shouldn't be offscreen"> + Mozilla Bug 810260 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=865591" + title="Visible menu item have offscreen state"> + Mozilla Bug 865591 + </a> + + <p id="display"></p> + <div id="content" style="display: none"> + </div> + <pre id="test"> + </pre> + </body> + + <vbox flex="1"> + + <deck selectedIndex="1"> + <description value="This is the first page" id="deck_pane1"/> + <button label="This is the second page" id="deck_pane2"/> + </deck> + + <tabbox> + <tabs> + <tab>tab1</tab> + <tab>tab2</tab> + </tabs> + <tabpanels> + <description value="This is the first page" id="tabs_pane1"/> + <button label="This is the second page" id="tabs_pane2"/> + </tabpanels> + </tabbox> + + <menubar> + <menu label="File" id="mi_file1"> + <menupopup> + <menuitem label="SubFile" id="mi_file1.1"/> + <menu label="SubFile2" id="mi_file1.2"> + <menupopup style="max-height: 5em;"> + <menuitem label="SubSubFile" id="mi_file1.2.1"/> + <menuitem label="SubSubFile2" id="mi_file1.2.2"/> + <menuitem label="SubSubFile3" id="mi_file1.2.3"/> + <menuitem label="SubSubFile4" id="mi_file1.2.4"/> + </menupopup> + </menu> + </menupopup> + </menu> + </menubar> + </vbox> + </hbox> + +</window> + diff --git a/accessible/tests/mochitest/states/z_frames.html b/accessible/tests/mochitest/states/z_frames.html new file mode 100644 index 0000000000..819adee63e --- /dev/null +++ b/accessible/tests/mochitest/states/z_frames.html @@ -0,0 +1,11 @@ +<html> +<!-- +Auxilliary file used as frame source. +--> +<head> +</head> +<body> +<p>Frame source body has no role</p> +</body> +</html> + diff --git a/accessible/tests/mochitest/states/z_frames_article.html b/accessible/tests/mochitest/states/z_frames_article.html new file mode 100644 index 0000000000..a7a69b4dae --- /dev/null +++ b/accessible/tests/mochitest/states/z_frames_article.html @@ -0,0 +1,11 @@ +<html> +<!-- +Auxilliary file used as frame source. +--> +<head> +</head> +<body role="article"> +<p>Article</p> +</body> +</html> + diff --git a/accessible/tests/mochitest/states/z_frames_checkbox.html b/accessible/tests/mochitest/states/z_frames_checkbox.html new file mode 100644 index 0000000000..7997644243 --- /dev/null +++ b/accessible/tests/mochitest/states/z_frames_checkbox.html @@ -0,0 +1,11 @@ +<html> +<!-- +Auxilliary file used as frame source. +--> +<head> +</head> +<body role="checkbox"> +<p>Checkbox</p> +</body> +</html> + diff --git a/accessible/tests/mochitest/states/z_frames_textbox.html b/accessible/tests/mochitest/states/z_frames_textbox.html new file mode 100644 index 0000000000..0f4e1b9d66 --- /dev/null +++ b/accessible/tests/mochitest/states/z_frames_textbox.html @@ -0,0 +1,11 @@ +<html> +<!-- +Auxilliary file used as frame source. +--> +<head> +</head> +<body role="textbox"> +<p>Texbox</p> +</body> +</html> + diff --git a/accessible/tests/mochitest/states/z_frames_update.html b/accessible/tests/mochitest/states/z_frames_update.html new file mode 100644 index 0000000000..7e2cc83539 --- /dev/null +++ b/accessible/tests/mochitest/states/z_frames_update.html @@ -0,0 +1,21 @@ +<html> +<head> +<script> +function replaceBody() { + var accService = Cc["@mozilla.org/accessibilityService;1"]. + getService(Ci.nsIAccessibilityService); + accService.getAccessibleFor(document); + + var newBody = document.createElement("body"); + newBody.setAttribute("contentEditable", "true"); + newBody.textContent = "New Hello"; + document.documentElement.replaceChild(newBody, document.body); + getComputedStyle(newBody, "").color; +} +</script> +</head> +<body onload="replaceBody();"> +OLD hello +</body> +</html> + |