summaryrefslogtreecommitdiffstats
path: root/accessible/tests/mochitest/name/markup.js
diff options
context:
space:
mode:
Diffstat (limited to 'accessible/tests/mochitest/name/markup.js')
-rw-r--r--accessible/tests/mochitest/name/markup.js382
1 files changed, 382 insertions, 0 deletions
diff --git a/accessible/tests/mochitest/name/markup.js b/accessible/tests/mochitest/name/markup.js
new file mode 100644
index 000000000..d3ecd8982
--- /dev/null
+++ b/accessible/tests/mochitest/name/markup.js
@@ -0,0 +1,382 @@
+////////////////////////////////////////////////////////////////////////////////
+// Name tests described by "markuprules.xml" file.
+
+var gNameRulesFileURL = "markuprules.xml";
+
+var gRuleDoc = null;
+
+// Debuggin stuff.
+var gDumpToConsole = false;
+
+/**
+ * Start name tests. Run through markup elements and test names for test
+ * element (see namerules.xml for details).
+ */
+function testNames()
+{
+ //enableLogging("tree,stack"); // debugging
+
+ var request = new XMLHttpRequest();
+ request.open("get", gNameRulesFileURL, false);
+ request.send();
+
+ gRuleDoc = request.responseXML;
+
+ var markupElms = evaluateXPath(gRuleDoc, "//rules/rulesample/markup");
+ gTestIterator.iterateMarkups(markupElms);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Private section.
+
+/**
+ * Helper class to interate through name tests.
+ */
+var gTestIterator =
+{
+ iterateMarkups: function gTestIterator_iterateMarkups(aMarkupElms)
+ {
+ this.markupElms = aMarkupElms;
+
+ this.iterateNext();
+ },
+
+ iterateRules: function gTestIterator_iterateRules(aElm, aContainer,
+ aRuleSetElm, aRuleElms,
+ aTestID)
+ {
+ this.ruleSetElm = aRuleSetElm;
+ this.ruleElms = aRuleElms;
+ this.elm = aElm;
+ this.container = aContainer;
+ this.testID = aTestID;
+
+ this.iterateNext();
+ },
+
+ iterateNext: function gTestIterator_iterateNext()
+ {
+ if (this.markupIdx == -1) {
+ this.markupIdx++;
+ testNamesForMarkup(this.markupElms[this.markupIdx]);
+ return;
+ }
+
+ this.ruleIdx++;
+ if (this.ruleIdx == this.ruleElms.length) {
+ // When test is finished then name is empty and no explict-name.
+ var defaultName = this.ruleSetElm.hasAttribute("defaultName") ?
+ this.ruleSetElm.getAttribute("defaultName") : null;
+ testName(this.elm, defaultName,
+ "Default name test (" + gTestIterator.testID + "). ");
+ testAbsentAttrs(this.elm, {"explicit-name" : "true"});
+
+ this.markupIdx++;
+ if (this.markupIdx == this.markupElms.length) {
+ //disableLogging("tree"); // debugging
+ SimpleTest.finish();
+ return;
+ }
+
+ this.ruleIdx = -1;
+
+ if (gDumpToConsole) {
+ dump("\nPend next markup processing. Wait for reorder event on " +
+ prettyName(document) + "'\n");
+ }
+ waitForEvent(EVENT_REORDER, document, testNamesForMarkup,
+ null, this.markupElms[this.markupIdx]);
+
+ document.body.removeChild(this.container);
+ return;
+ }
+
+ testNameForRule(this.elm, this.ruleElms[this.ruleIdx]);
+ },
+
+ markupElms: null,
+ markupIdx: -1,
+ rulesetElm: null,
+ ruleElms: null,
+ ruleIdx: -1,
+ elm: null,
+ container: null,
+ testID: ""
+};
+
+/**
+ * Process every 'markup' element and test names for it. Used by testNames
+ * function.
+ */
+function testNamesForMarkup(aMarkupElm)
+{
+ if (gDumpToConsole)
+ dump("\nProcessing markup '" + aMarkupElm.getAttribute("id") + "'\n");
+
+ var div = document.createElement("div");
+ div.setAttribute("id", "test");
+
+ var child = aMarkupElm.firstChild;
+ while (child) {
+ var newChild = document.importNode(child, true);
+ div.appendChild(newChild);
+ child = child.nextSibling;
+ }
+
+ if (gDumpToConsole) {
+ dump("\nProcessing markup. Wait for reorder event on " +
+ prettyName(document) + "'\n");
+ }
+ waitForEvent(EVENT_REORDER, document, testNamesForMarkupRules,
+ null, aMarkupElm, div);
+
+ document.body.appendChild(div);
+}
+
+function testNamesForMarkupRules(aMarkupElm, aContainer)
+{
+ var testID = aMarkupElm.getAttribute("id");
+ if (gDumpToConsole)
+ dump("\nProcessing markup rules '" + testID + "'\n");
+
+ var serializer = new XMLSerializer();
+
+ var expr = "//html/body/div[@id='test']/" + aMarkupElm.getAttribute("ref");
+ var elm = evaluateXPath(document, expr, htmlDocResolver)[0];
+
+ var ruleId = aMarkupElm.getAttribute("ruleset");
+ var ruleElm = gRuleDoc.querySelector("[id='" + ruleId + "']");
+ var ruleElms = getRuleElmsByRulesetId(ruleId);
+
+ var processMarkupRules =
+ gTestIterator.iterateRules.bind(gTestIterator, elm, aContainer,
+ ruleElm, ruleElms, testID);
+
+ // Images may be recreated after we append them into subtree. We need to wait
+ // in this case. If we are on profiling enabled build then stack tracing
+ // works and thus let's log instead. Note, that works if you enabled logging
+ // (refer to testNames() function).
+ if (isAccessible(elm) || isLogged("stack"))
+ processMarkupRules();
+ else
+ waitForEvent(EVENT_SHOW, elm, processMarkupRules);
+}
+
+/**
+ * Test name for current rule and current 'markup' element. Used by
+ * testNamesForMarkup function.
+ */
+function testNameForRule(aElm, aRuleElm)
+{
+ if (aRuleElm.hasAttribute("attr")) {
+ if (gDumpToConsole) {
+ dump("\nProcessing rule { attr: " + aRuleElm.getAttribute("attr") +" }\n");
+ }
+
+ testNameForAttrRule(aElm, aRuleElm);
+
+ } else if (aRuleElm.hasAttribute("elm")) {
+ if (gDumpToConsole) {
+ dump("\nProcessing rule { elm: " + aRuleElm.getAttribute("elm") +
+ ", elmattr: " + aRuleElm.getAttribute("elmattr") +" }\n");
+ }
+
+ testNameForElmRule(aElm, aRuleElm);
+
+ } else if (aRuleElm.getAttribute("fromsubtree") == "true") {
+ if (gDumpToConsole) {
+ dump("\nProcessing rule { fromsubtree: " +
+ aRuleElm.getAttribute("fromsubtree") +" }\n");
+ }
+
+ testNameForSubtreeRule(aElm, aRuleElm);
+ }
+}
+
+function testNameForAttrRule(aElm, aRule)
+{
+ var name = "";
+
+ var attr = aRule.getAttribute("attr");
+ var attrValue = aElm.getAttribute(attr);
+
+ var type = aRule.getAttribute("type");
+ if (type == "string") {
+ name = attrValue;
+
+ } else if (type == "ref" && attrValue) {
+ var ids = attrValue.split(/\s+/);
+ for (var idx = 0; idx < ids.length; idx++) {
+ var labelElm = getNode(ids[idx]);
+ if (name != "")
+ name += " ";
+
+ name += labelElm.getAttribute("textequiv");
+ }
+ }
+
+ var msg = "Attribute '" + attr + "' test (" + gTestIterator.testID + "). ";
+ testName(aElm, name, msg);
+
+ if (aRule.getAttribute("explict-name") != "false")
+ testAttrs(aElm, {"explicit-name" : "true"}, true);
+ else
+ testAbsentAttrs(aElm, {"explicit-name" : "true"});
+
+ // If @recreated attribute is used then this attribute change recreates an
+ // accessible. Wait for reorder event in this case or otherwise proceed next
+ // test immediately.
+ if (aRule.hasAttribute("recreated")) {
+ waitForEvent(EVENT_REORDER, aElm.parentNode,
+ gTestIterator.iterateNext, gTestIterator);
+ aElm.removeAttribute(attr);
+
+ } else if (aRule.hasAttribute("textchanged")) {
+ waitForEvent(EVENT_TEXT_INSERTED, aElm,
+ gTestIterator.iterateNext, gTestIterator);
+ aElm.removeAttribute(attr);
+
+ } else if (aRule.hasAttribute("contentchanged")) {
+ waitForEvent(EVENT_REORDER, aElm,
+ gTestIterator.iterateNext, gTestIterator);
+ aElm.removeAttribute(attr);
+
+ } else {
+ aElm.removeAttribute(attr);
+ gTestIterator.iterateNext();
+ }
+}
+
+function testNameForElmRule(aElm, aRule)
+{
+ var labelElm;
+
+ var tagname = aRule.getAttribute("elm");
+ var attrname = aRule.getAttribute("elmattr");
+ if (attrname) {
+ var filter = {
+ acceptNode: function filter_acceptNode(aNode)
+ {
+ if (aNode.localName == this.mLocalName &&
+ aNode.getAttribute(this.mAttrName) == this.mAttrValue)
+ return NodeFilter.FILTER_ACCEPT;
+
+ return NodeFilter.FILTER_SKIP;
+ },
+
+ mLocalName: tagname,
+ mAttrName: attrname,
+ mAttrValue: aElm.getAttribute("id")
+ };
+
+ var treeWalker = document.createTreeWalker(document.body,
+ NodeFilter.SHOW_ELEMENT,
+ filter);
+ labelElm = treeWalker.nextNode();
+
+ } else {
+ // if attrname is empty then look for the element in subtree.
+ labelElm = aElm.getElementsByTagName(tagname)[0];
+ if (!labelElm)
+ labelElm = aElm.getElementsByTagName("html:" + tagname)[0];
+ }
+
+ if (!labelElm) {
+ ok(false, msg + " Failed to find '" + tagname + "' element.");
+ gTestIterator.iterateNext();
+ return;
+ }
+
+ var msg = "Element '" + tagname + "' test (" + gTestIterator.testID + ").";
+ testName(aElm, labelElm.getAttribute("textequiv"), msg);
+ testAttrs(aElm, {"explicit-name" : "true"}, true);
+
+ var parentNode = labelElm.parentNode;
+
+ if (gDumpToConsole) {
+ dump("\nProcessed elm rule. Wait for reorder event on " +
+ prettyName(parentNode) + "\n");
+ }
+ waitForEvent(EVENT_REORDER, parentNode,
+ gTestIterator.iterateNext, gTestIterator);
+
+ parentNode.removeChild(labelElm);
+}
+
+function testNameForSubtreeRule(aElm, aRule)
+{
+ var msg = "From subtree test (" + gTestIterator.testID + ").";
+ testName(aElm, aElm.getAttribute("textequiv"), msg);
+ testAbsentAttrs(aElm, {"explicit-name" : "true"});
+
+ if (gDumpToConsole) {
+ dump("\nProcessed from subtree rule. Wait for reorder event on " +
+ prettyName(aElm) + "\n");
+ }
+ waitForEvent(EVENT_REORDER, aElm, gTestIterator.iterateNext, gTestIterator);
+
+ while (aElm.firstChild)
+ aElm.removeChild(aElm.firstChild);
+}
+
+/**
+ * Return array of 'rule' elements. Used in conjunction with
+ * getRuleElmsFromRulesetElm() function.
+ */
+function getRuleElmsByRulesetId(aRulesetId)
+{
+ var expr = "//rules/ruledfn/ruleset[@id='" + aRulesetId + "']";
+ var rulesetElm = evaluateXPath(gRuleDoc, expr);
+ return getRuleElmsFromRulesetElm(rulesetElm[0]);
+}
+
+function getRuleElmsFromRulesetElm(aRulesetElm)
+{
+ var rulesetId = aRulesetElm.getAttribute("ref");
+ if (rulesetId)
+ return getRuleElmsByRulesetId(rulesetId);
+
+ var ruleElms = [];
+
+ var child = aRulesetElm.firstChild;
+ while (child) {
+ if (child.localName == "ruleset")
+ ruleElms = ruleElms.concat(getRuleElmsFromRulesetElm(child));
+ if (child.localName == "rule")
+ ruleElms.push(child);
+
+ child = child.nextSibling;
+ }
+
+ return ruleElms;
+}
+
+/**
+ * Helper method to evaluate xpath expression.
+ */
+function evaluateXPath(aNode, aExpr, aResolver)
+{
+ var xpe = new XPathEvaluator();
+
+ var resolver = aResolver;
+ if (!resolver) {
+ var node = aNode.ownerDocument == null ?
+ aNode.documentElement : aNode.ownerDocument.documentElement;
+ resolver = xpe.createNSResolver(node);
+ }
+
+ var result = xpe.evaluate(aExpr, aNode, resolver, 0, null);
+ var found = [];
+ var res;
+ while (res = result.iterateNext())
+ found.push(res);
+
+ return found;
+}
+
+function htmlDocResolver(aPrefix) {
+ var ns = {
+ 'html' : 'http://www.w3.org/1999/xhtml'
+ };
+ return ns[aPrefix] || null;
+}