diff options
Diffstat (limited to 'accessible/tests/mochitest/treeupdate/test_ariaowns.html')
-rw-r--r-- | accessible/tests/mochitest/treeupdate/test_ariaowns.html | 693 |
1 files changed, 693 insertions, 0 deletions
diff --git a/accessible/tests/mochitest/treeupdate/test_ariaowns.html b/accessible/tests/mochitest/treeupdate/test_ariaowns.html new file mode 100644 index 000000000..44fc22a2d --- /dev/null +++ b/accessible/tests/mochitest/treeupdate/test_ariaowns.html @@ -0,0 +1,693 @@ +<!DOCTYPE html> +<html> + +<head> + <title>@aria-owns attribute testing</title> + + <link rel="stylesheet" type="text/css" + href="chrome://mochikit/content/tests/SimpleTest/test.css" /> + + <script type="application/javascript" + 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="../events.js"></script> + + <script type="application/javascript"> + + //////////////////////////////////////////////////////////////////////////// + // Invokers + //////////////////////////////////////////////////////////////////////////// + + function changeARIAOwns() + { + this.eventSeq = [ + new invokerChecker(EVENT_HIDE, getNode("t1_button")), + // no hide for t1_subdiv because it is contained by hidden t1_checkbox + new invokerChecker(EVENT_HIDE, getNode("t1_checkbox")), + new invokerChecker(EVENT_SHOW, getNode("t1_checkbox")), + new invokerChecker(EVENT_SHOW, getNode("t1_button")), + new invokerChecker(EVENT_SHOW, getNode("t1_subdiv")), + new invokerChecker(EVENT_REORDER, getNode("t1_container")) + ]; + + this.invoke = function setARIAOwns_invoke() + { + // children are swapped by ARIA owns + var tree = + { SECTION: [ + { CHECKBUTTON: [ + { SECTION: [] } + ] }, + { PUSHBUTTON: [ ] } + ] }; + testAccessibleTree("t1_container", tree); + + getNode("t1_container"). + setAttribute("aria-owns", "t1_button t1_subdiv"); + } + + this.finalCheck = function setARIAOwns_finalCheck() + { + // children are swapped again, button and subdiv are appended to + // the children. + var tree = + { SECTION: [ + { CHECKBUTTON: [ ] }, // checkbox, native order + { PUSHBUTTON: [ ] }, // button, rearranged by ARIA own + { SECTION: [ ] } // subdiv from the subtree, ARIA owned + ] }; + testAccessibleTree("t1_container", tree); + } + + this.getID = function setARIAOwns_getID() + { + return "Change @aria-owns attribute"; + } + } + + function removeARIAOwns() + { + this.eventSeq = [ + new invokerChecker(EVENT_HIDE, getNode("t1_button")), + new invokerChecker(EVENT_HIDE, getNode("t1_subdiv")), + new orderChecker(), + new asyncInvokerChecker(EVENT_SHOW, getNode("t1_button")), + new asyncInvokerChecker(EVENT_SHOW, getNode("t1_subdiv")), + new orderChecker(), + new invokerChecker(EVENT_REORDER, getNode("t1_container")), + new unexpectedInvokerChecker(EVENT_REORDER, getNode("t1_checkbox")) + ]; + + this.invoke = function removeARIAOwns_invoke() + { + getNode("t1_container").removeAttribute("aria-owns"); + } + + this.finalCheck = function removeARIAOwns_finalCheck() + { + // children follow the DOM order + var tree = + { SECTION: [ + { PUSHBUTTON: [ ] }, + { CHECKBUTTON: [ + { SECTION: [] } + ] } + ] }; + testAccessibleTree("t1_container", tree); + } + + this.getID = function removeARIAOwns_getID() + { + return "Remove @aria-owns attribute"; + } + } + + function setARIAOwns() + { + this.eventSeq = [ + new invokerChecker(EVENT_HIDE, getNode("t1_button")), + new invokerChecker(EVENT_HIDE, getNode("t1_subdiv")), + new invokerChecker(EVENT_SHOW, getNode("t1_button")), + new invokerChecker(EVENT_SHOW, getNode("t1_subdiv")), + new invokerChecker(EVENT_REORDER, getNode("t1_container")) + ]; + + this.invoke = function setARIAOwns_invoke() + { + getNode("t1_container"). + setAttribute("aria-owns", "t1_button t1_subdiv"); + } + + this.finalCheck = function setARIAOwns_finalCheck() + { + // children are swapped again, button and subdiv are appended to + // the children. + var tree = + { SECTION: [ + { CHECKBUTTON: [ ] }, // checkbox + { PUSHBUTTON: [ ] }, // button, rearranged by ARIA own + { SECTION: [ ] } // subdiv from the subtree, ARIA owned + ] }; + testAccessibleTree("t1_container", tree); + } + + this.getID = function setARIAOwns_getID() + { + return "Set @aria-owns attribute"; + } + } + + function addIdToARIAOwns() + { + this.eventSeq = [ + new invokerChecker(EVENT_HIDE, getNode("t1_group")), + new invokerChecker(EVENT_SHOW, getNode("t1_group")), + new invokerChecker(EVENT_REORDER, document) + ]; + + this.invoke = function addIdToARIAOwns_invoke() + { + getNode("t1_container"). + setAttribute("aria-owns", "t1_button t1_subdiv t1_group"); + } + + this.finalCheck = function addIdToARIAOwns_finalCheck() + { + // children are swapped again, button and subdiv are appended to + // the children. + var tree = + { SECTION: [ + { CHECKBUTTON: [ ] }, // t1_checkbox + { PUSHBUTTON: [ ] }, // button, t1_button + { SECTION: [ ] }, // subdiv from the subtree, t1_subdiv + { GROUPING: [ ] } // group from outside, t1_group + ] }; + testAccessibleTree("t1_container", tree); + } + + this.getID = function addIdToARIAOwns_getID() + { + return "Add id to @aria-owns attribute value"; + } + } + + function appendEl() + { + this.eventSeq = [ + new invokerChecker(EVENT_SHOW, getNode, "t1_child3"), + new invokerChecker(EVENT_REORDER, getNode("t1_container")) + ]; + + this.invoke = function appendEl_invoke() + { + var div = document.createElement("div"); + div.setAttribute("id", "t1_child3"); + div.setAttribute("role", "radio") + getNode("t1_container").appendChild(div); + } + + this.finalCheck = function appendEl_finalCheck() + { + // children are invalidated, they includes aria-owns swapped kids and + // newly inserted child. + var tree = + { SECTION: [ + { CHECKBUTTON: [ ] }, // existing explicit, t1_checkbox + { RADIOBUTTON: [ ] }, // new explicit, t1_child3 + { PUSHBUTTON: [ ] }, // ARIA owned, t1_button + { SECTION: [ ] }, // ARIA owned, t1_subdiv + { GROUPING: [ ] } // ARIA owned, t1_group + ] }; + testAccessibleTree("t1_container", tree); + } + + this.getID = function appendEl_getID() + { + return "Append child under @aria-owns element"; + } + } + + function removeEl() + { + this.eventSeq = [ + new invokerChecker(EVENT_HIDE, getNode, "t1_checkbox"), + new invokerChecker(EVENT_SHOW, getNode, "t1_checkbox"), + new invokerChecker(EVENT_REORDER, getNode("t1_container")) + ]; + + this.invoke = function removeEl_invoke() + { + // remove a container of t1_subdiv + getNode("t1_span").parentNode.removeChild(getNode("t1_span")); + } + + this.finalCheck = function removeEl_finalCheck() + { + // subdiv should go away + var tree = + { SECTION: [ + { CHECKBUTTON: [ ] }, // explicit, t1_checkbox + { RADIOBUTTON: [ ] }, // explicit, t1_child3 + { PUSHBUTTON: [ ] }, // ARIA owned, t1_button + { GROUPING: [ ] } // ARIA owned, t1_group + ] }; + testAccessibleTree("t1_container", tree); + } + + this.getID = function removeEl_getID() + { + return "Remove a container of ARIA owned element"; + } + } + + function removeId() + { + this.eventSeq = [ + new invokerChecker(EVENT_HIDE, getNode("t1_group")), + new invokerChecker(EVENT_SHOW, getNode("t1_group")), + new invokerChecker(EVENT_REORDER, document) + ]; + + this.invoke = function removeId_invoke() + { + getNode("t1_group").removeAttribute("id"); + } + + this.finalCheck = function removeId_finalCheck() + { + var tree = + { SECTION: [ + { CHECKBUTTON: [ ] }, + { RADIOBUTTON: [ ] }, + { PUSHBUTTON: [ ] } // ARIA owned, t1_button + ] }; + testAccessibleTree("t1_container", tree); + } + + this.getID = function removeId_getID() + { + return "Remove ID from ARIA owned element"; + } + } + + function setId() + { + this.eventSeq = [ + new invokerChecker(EVENT_HIDE, getNode("t1_grouptmp")), + new invokerChecker(EVENT_SHOW, getNode("t1_grouptmp")), + new invokerChecker(EVENT_REORDER, document) + ]; + + this.invoke = function setId_invoke() + { + getNode("t1_grouptmp").setAttribute("id", "t1_group"); + } + + this.finalCheck = function setId_finalCheck() + { + var tree = + { SECTION: [ + { CHECKBUTTON: [ ] }, + { RADIOBUTTON: [ ] }, + { PUSHBUTTON: [ ] }, // ARIA owned, t1_button + { GROUPING: [ ] } // ARIA owned, t1_group, previously t1_grouptmp + ] }; + testAccessibleTree("t1_container", tree); + } + + this.getID = function setId_getID() + { + return "Set ID that is referred by ARIA owns"; + } + } + + /** + * Remove an accessible DOM element containing an element referred by + * ARIA owns. + */ + function removeA11eteiner() + { + this.eventSeq = [ + new invokerChecker(EVENT_REORDER, getNode("t2_container1")) + ]; + + this.invoke = function removeA11eteiner_invoke() + { + var tree = + { SECTION: [ + { CHECKBUTTON: [ ] } // ARIA owned, 't2_owned' + ] }; + testAccessibleTree("t2_container1", tree); + + getNode("t2_container2").removeChild(getNode("t2_container3")); + } + + this.finalCheck = function removeA11eteiner_finalCheck() + { + var tree = + { SECTION: [ + ] }; + testAccessibleTree("t2_container1", tree); + } + + this.getID = function removeA11eteiner_getID() + { + return "Remove an accessible DOM element containing an element referred by ARIA owns"; + } + } + + /** + * Steal an element from other ARIA owns element. This use case guarantees + * that result of setAttribute/removeAttribute doesn't depend on their order. + */ + function stealFromOtherARIAOwns() + { + this.eventSeq = [ + new invokerChecker(EVENT_REORDER, getNode("t3_container2")) + ]; + + this.invoke = function stealFromOtherARIAOwns_invoke() + { + getNode("t3_container2").setAttribute("aria-owns", "t3_child"); + } + + this.finalCheck = function stealFromOtherARIAOwns_finalCheck() + { + var tree = + { SECTION: [ + ] }; + testAccessibleTree("t3_container1", tree); + + tree = + { SECTION: [ + { CHECKBUTTON: [ + ] } + ] }; + testAccessibleTree("t3_container2", tree); + } + + this.getID = function stealFromOtherARIAOwns_getID() + { + return "Steal an element from other ARIA owns element"; + } + } + + function appendElToRecacheChildren() + { + this.eventSeq = [ + new invokerChecker(EVENT_REORDER, getNode("t3_container2")) + ]; + + this.invoke = function appendElToRecacheChildren_invoke() + { + var div = document.createElement("div"); + div.setAttribute("role", "radio") + getNode("t3_container2").appendChild(div); + } + + this.finalCheck = function appendElToRecacheChildren_finalCheck() + { + var tree = + { SECTION: [ + ] }; + testAccessibleTree("t3_container1", tree); + + tree = + { SECTION: [ + { RADIOBUTTON: [ ] }, + { CHECKBUTTON: [ ] } // ARIA owned + ] }; + testAccessibleTree("t3_container2", tree); + } + + this.getID = function appendElToRecacheChildren_getID() + { + return "Append a child under @aria-owns element to trigger children recache"; + } + } + + function showHiddenElement() + { + this.eventSeq = [ + new invokerChecker(EVENT_REORDER, getNode("t4_container1")) + ]; + + this.invoke = function showHiddenElement_invoke() + { + var tree = + { SECTION: [ + { RADIOBUTTON: [] } + ] }; + testAccessibleTree("t4_container1", tree); + + getNode("t4_child1").style.display = "block"; + } + + this.finalCheck = function showHiddenElement_finalCheck() + { + var tree = + { SECTION: [ + { CHECKBUTTON: [] }, + { RADIOBUTTON: [] } + ] }; + testAccessibleTree("t4_container1", tree); + } + + this.getID = function showHiddenElement_getID() + { + return "Show hidden ARIA owns referred element"; + } + } + + function rearrangeARIAOwns(aContainer, aAttr, aIdList, aRoleList) + { + this.eventSeq = []; + for (var id of aIdList) { + this.eventSeq.push(new invokerChecker(EVENT_HIDE, getNode(id))); + } + + for (var id of aIdList) { + this.eventSeq.push(new invokerChecker(EVENT_SHOW, getNode(id))); + } + this.eventSeq.push(new invokerChecker(EVENT_REORDER, getNode(aContainer))); + + this.invoke = function rearrangeARIAOwns_invoke() + { + getNode(aContainer).setAttribute("aria-owns", aAttr); + } + + this.finalCheck = function rearrangeARIAOwns_finalCheck() + { + var tree = { SECTION: [ ] }; + for (var role of aRoleList) { + var ch = {}; + ch[role] = []; + tree["SECTION"].push(ch); + } + testAccessibleTree(aContainer, tree); + } + + this.getID = function rearrangeARIAOwns_getID() + { + return `Rearrange @aria-owns attribute to '${aAttr}'`; + } + } + + function removeNotARIAOwnedEl(aContainer, aChild) + { + this.eventSeq = [ + new invokerChecker(EVENT_REORDER, aContainer) + ]; + + this.invoke = function removeNotARIAOwnedEl_invoke() + { + var tree = { + SECTION: [ + { TEXT_LEAF: [ ] }, + { GROUPING: [ ] } + ] + }; + testAccessibleTree(aContainer, tree); + + getNode(aContainer).removeChild(getNode(aChild)); + } + + this.finalCheck = function removeNotARIAOwnedEl_finalCheck() + { + var tree = { + SECTION: [ + { GROUPING: [ ] } + ] + }; + testAccessibleTree(aContainer, tree); + } + + this.getID = function removeNotARIAOwnedEl_getID() + { + return `remove not ARIA owned child`; + } + } + + function setARIAOwnsOnElToRemove(aParent, aChild) + { + this.eventSeq = [ + new invokerChecker(EVENT_HIDE, getAccessible(aParent)) + ]; + + this.invoke = function setARIAOwnsOnElToRemove_invoke() + { + getNode(aChild).setAttribute("aria-owns", "no_id"); + getNode(aParent).removeChild(getNode(aChild)); + getNode(aParent).parentNode.removeChild(getNode(aParent)); + } + + this.getID = function setARIAOwnsOnElToRemove_getID() + { + return `set ARIA owns on an element, and then remove it, and then remove its parent`; + } + } + + /** + * Set ARIA owns on inaccessible span element that contains + * accessible children. This will move children from the container for + * the span. + */ + function test8() + { + this.eventSeq = [ + new invokerChecker(EVENT_REORDER, "t8_container") + ]; + + this.invoke = function test8_invoke() + { + var tree = + { SECTION: [ + { PUSHBUTTON: [] }, + { ENTRY: [] }, + { ENTRY: [] }, + { ENTRY: [] } + ] }; + testAccessibleTree("t8_container", tree); + + getNode(t8_container).setAttribute("aria-owns", "t8_span t8_button"); + } + + this.finalCheck = function test8_finalCheck() + { + var tree = + { SECTION: [ + { TEXT: [ + { ENTRY: [] }, + { ENTRY: [] }, + { ENTRY: [] } + ] }, + { PUSHBUTTON: [] } + ] }; + testAccessibleTree("t8_container", tree); + } + + this.getID = function test8_getID() + { + return `Set ARIA owns on inaccessible span element that contains accessible children`; + } + } + + //////////////////////////////////////////////////////////////////////////// + // Test + //////////////////////////////////////////////////////////////////////////// + + //gA11yEventDumpToConsole = true; + //enableLogging("tree,eventTree,verbose"); // debug stuff + + var gQueue = null; + + function doTest() + { + gQueue = new eventQueue(); + + // test1 + gQueue.push(new changeARIAOwns()); + gQueue.push(new removeARIAOwns()); + gQueue.push(new setARIAOwns()); + gQueue.push(new addIdToARIAOwns()); + gQueue.push(new appendEl()); + gQueue.push(new removeEl()); + gQueue.push(new removeId()); + gQueue.push(new setId()); + + // test2 + gQueue.push(new removeA11eteiner()); + + // test3 + gQueue.push(new stealFromOtherARIAOwns()); + gQueue.push(new appendElToRecacheChildren()); + + // test4 + gQueue.push(new showHiddenElement()); + + // test5 + gQueue.push(new rearrangeARIAOwns( + "t5_container", "t5_checkbox t5_radio t5_button", + [ "t5_checkbox", "t5_radio", "t5_button" ], + [ "CHECKBUTTON", "RADIOBUTTON", "PUSHBUTTON" ])); + gQueue.push(new rearrangeARIAOwns( + "t5_container", "t5_radio t5_button t5_checkbox", + [ "t5_radio", "t5_button" ], + [ "RADIOBUTTON", "PUSHBUTTON", "CHECKBUTTON" ])); + + gQueue.push(new removeNotARIAOwnedEl("t6_container", "t6_span")); + + gQueue.push(new setARIAOwnsOnElToRemove("t7_parent", "t7_child")); + + gQueue.push(new test8()); + + gQueue.invoke(); // SimpleTest.finish() will be called in the end + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + + </script> +</head> + +<body> + + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"> + </pre> + + <div id="t1_container" aria-owns="t1_checkbox t1_button"> + <div role="button" id="t1_button"></div> + <div role="checkbox" id="t1_checkbox"> + <span id="t1_span"> + <div id="t1_subdiv"></div> + </span> + </div> + </div> + <div id="t1_group" role="group"></div> + <div id="t1_grouptmp" role="group"></div> + + <div id="t2_container1" aria-owns="t2_owned"></div> + <div id="t2_container2"> + <div id="t2_container3"><div id="t2_owned" role="checkbox"></div></div> + </div> + + <div id="t3_container1" aria-owns="t3_child"></div> + <div id="t3_child" role="checkbox"></div> + <div id="t3_container2"></div> + + <div id="t4_container1" aria-owns="t4_child1 t4_child2"></div> + <div id="t4_container2"> + <div id="t4_child1" style="display:none" role="checkbox"></div> + <div id="t4_child2" role="radio"></div> + </div> + + <div id="t5_container"> + <div role="button" id="t5_button"></div> + <div role="checkbox" id="t5_checkbox"></div> + <div role="radio" id="t5_radio"></div> + </div> + + <div id="t6_container" aria-owns="t6_fake"> + <span id="t6_span">hey</span> + </div> + <div id="t6_fake" role="group"></div> + + <div id="t7_container"> + <div id="t7_parent"> + <div id="t7_child"></div> + </div> + </div> + + <div id="t8_container"> + <input id="t8_button" type="button"><span id="t8_span"><input><input><input></span> + </div> +</body> + +</html> |