summaryrefslogtreecommitdiff
path: root/accessible/tests/mochitest/treeupdate/test_ariaowns.html
diff options
context:
space:
mode:
Diffstat (limited to 'accessible/tests/mochitest/treeupdate/test_ariaowns.html')
-rw-r--r--accessible/tests/mochitest/treeupdate/test_ariaowns.html693
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 0000000000..44fc22a2d5
--- /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>