summaryrefslogtreecommitdiffstats
path: root/accessible/tests/mochitest/attributes.js
diff options
context:
space:
mode:
Diffstat (limited to 'accessible/tests/mochitest/attributes.js')
-rw-r--r--accessible/tests/mochitest/attributes.js382
1 files changed, 382 insertions, 0 deletions
diff --git a/accessible/tests/mochitest/attributes.js b/accessible/tests/mochitest/attributes.js
new file mode 100644
index 000000000..b2ac78cba
--- /dev/null
+++ b/accessible/tests/mochitest/attributes.js
@@ -0,0 +1,382 @@
+////////////////////////////////////////////////////////////////////////////////
+// Object attributes.
+
+/**
+ * Test object attributes.
+ *
+ * @param aAccOrElmOrID [in] the accessible identifier
+ * @param aAttrs [in] the map of expected object attributes
+ * (name/value pairs)
+ * @param aSkipUnexpectedAttrs [in] points this function doesn't fail if
+ * unexpected attribute is encountered
+ */
+function testAttrs(aAccOrElmOrID, aAttrs, aSkipUnexpectedAttrs)
+{
+ testAttrsInternal(aAccOrElmOrID, aAttrs, aSkipUnexpectedAttrs);
+}
+
+/**
+ * Test object attributes that must not be present.
+ *
+ * @param aAccOrElmOrID [in] the accessible identifier
+ * @param aAbsentAttrs [in] map of attributes that should not be
+ * present (name/value pairs)
+ */
+function testAbsentAttrs(aAccOrElmOrID, aAbsentAttrs)
+{
+ testAttrsInternal(aAccOrElmOrID, {}, true, aAbsentAttrs);
+}
+
+/**
+ * Test CSS based object attributes.
+ */
+function testCSSAttrs(aID)
+{
+ var node = document.getElementById(aID);
+ var computedStyle = document.defaultView.getComputedStyle(node, "");
+
+ var attrs = {
+ "display": computedStyle.display,
+ "text-align": computedStyle.textAlign,
+ "text-indent": computedStyle.textIndent,
+ "margin-left": computedStyle.marginLeft,
+ "margin-right": computedStyle.marginRight,
+ "margin-top": computedStyle.marginTop,
+ "margin-bottom": computedStyle.marginBottom
+ };
+ testAttrs(aID, attrs, true);
+}
+
+/**
+ * Test the accessible that it doesn't have CSS-based object attributes.
+ */
+function testAbsentCSSAttrs(aID)
+{
+ var attrs = {
+ "display": "",
+ "text-align": "",
+ "text-indent": "",
+ "margin-left": "",
+ "margin-right": "",
+ "margin-top": "",
+ "margin-bottom": ""
+ };
+ testAbsentAttrs(aID, attrs);
+}
+
+/**
+ * Test group object attributes (posinset, setsize and level) and
+ * nsIAccessible::groupPosition() method.
+ *
+ * @param aAccOrElmOrID [in] the ID, DOM node or accessible
+ * @param aPosInSet [in] the value of 'posinset' attribute
+ * @param aSetSize [in] the value of 'setsize' attribute
+ * @param aLevel [in, optional] the value of 'level' attribute
+ */
+function testGroupAttrs(aAccOrElmOrID, aPosInSet, aSetSize, aLevel)
+{
+ var acc = getAccessible(aAccOrElmOrID);
+ var levelObj = {}, posInSetObj = {}, setSizeObj = {};
+ acc.groupPosition(levelObj, setSizeObj, posInSetObj);
+
+ if (aPosInSet && aSetSize) {
+ is(posInSetObj.value, aPosInSet,
+ "Wrong group position (posinset) for " + prettyName(aAccOrElmOrID));
+ is(setSizeObj.value, aSetSize,
+ "Wrong size of the group (setsize) for " + prettyName(aAccOrElmOrID));
+
+ var attrs = {
+ "posinset": String(aPosInSet),
+ "setsize": String(aSetSize)
+ };
+ testAttrs(aAccOrElmOrID, attrs, true);
+ }
+
+ if (aLevel) {
+ is(levelObj.value, aLevel,
+ "Wrong group level for " + prettyName(aAccOrElmOrID));
+
+ var attrs = { "level" : String(aLevel) };
+ testAttrs(aAccOrElmOrID, attrs, true);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Text attributes.
+
+/**
+ * Test text attributes.
+ *
+ * @param aID [in] the ID of DOM element having text
+ * accessible
+ * @param aOffset [in] the offset inside text accessible to fetch
+ * text attributes
+ * @param aAttrs [in] the map of expected text attributes
+ * (name/value pairs) exposed at the offset
+ * @param aDefAttrs [in] the map of expected text attributes
+ * (name/value pairs) exposed on hyper text
+ * accessible
+ * @param aStartOffset [in] expected start offset where text attributes
+ * are applied
+ * @param aEndOffset [in] expected end offset where text attribute
+ * are applied
+ * @param aSkipUnexpectedAttrs [in] points the function doesn't fail if
+ * unexpected attribute is encountered
+ */
+function testTextAttrs(aID, aOffset, aAttrs, aDefAttrs,
+ aStartOffset, aEndOffset, aSkipUnexpectedAttrs)
+{
+ var accessible = getAccessible(aID, [nsIAccessibleText]);
+ if (!accessible)
+ return;
+
+ var startOffset = { value: -1 };
+ var endOffset = { value: -1 };
+
+ // do not include attributes exposed on hyper text accessbile
+ var attrs = getTextAttributes(aID, accessible, false, aOffset,
+ startOffset, endOffset);
+
+ if (!attrs)
+ return;
+
+ var errorMsg = " for " + aID + " at offset " + aOffset;
+
+ is(startOffset.value, aStartOffset, "Wrong start offset" + errorMsg);
+ is(endOffset.value, aEndOffset, "Wrong end offset" + errorMsg);
+
+ compareAttrs(errorMsg, attrs, aAttrs, aSkipUnexpectedAttrs);
+
+ // include attributes exposed on hyper text accessbile
+ var expectedAttrs = {};
+ for (var name in aAttrs)
+ expectedAttrs[name] = aAttrs[name];
+
+ for (var name in aDefAttrs) {
+ if (!(name in expectedAttrs))
+ expectedAttrs[name] = aDefAttrs[name];
+ }
+
+ attrs = getTextAttributes(aID, accessible, true, aOffset,
+ startOffset, endOffset);
+
+ if (!attrs)
+ return;
+
+ compareAttrs(errorMsg, attrs, expectedAttrs, aSkipUnexpectedAttrs);
+}
+
+/**
+ * Test default text attributes.
+ *
+ * @param aID [in] the ID of DOM element having text
+ * accessible
+ * @param aDefAttrs [in] the map of expected text attributes
+ * (name/value pairs)
+ * @param aSkipUnexpectedAttrs [in] points the function doesn't fail if
+ * unexpected attribute is encountered
+ */
+function testDefaultTextAttrs(aID, aDefAttrs, aSkipUnexpectedAttrs)
+{
+ var accessible = getAccessible(aID, [nsIAccessibleText]);
+ if (!accessible)
+ return;
+
+ var defAttrs = null;
+ try{
+ defAttrs = accessible.defaultTextAttributes;
+ } catch (e) {
+ }
+
+ if (!defAttrs) {
+ ok(false, "Can't get default text attributes for " + aID);
+ return;
+ }
+
+ var errorMsg = ". Getting default text attributes for " + aID;
+ compareAttrs(errorMsg, defAttrs, aDefAttrs, aSkipUnexpectedAttrs);
+}
+
+/**
+ * Test text attributes for wrong offset.
+ */
+function testTextAttrsWrongOffset(aID, aOffset)
+{
+ var res = false;
+ try {
+ var s = {}, e = {};
+ var acc = getAccessible(ID, [nsIAccessibleText]);
+ acc.getTextAttributes(false, 157, s, e);
+ } catch (e) {
+ res = true;
+ }
+
+ ok(res,
+ "text attributes are calculated successfully at wrong offset " + aOffset + " for " + prettyName(aID));
+}
+
+const kNormalFontWeight =
+ function equalsToNormal(aWeight) { return aWeight <= 400 ; }
+
+const kBoldFontWeight =
+ function equalsToBold(aWeight) { return aWeight > 400; }
+
+// The pt font size of the input element can vary by Linux distro.
+const kInputFontSize = WIN ?
+ "10pt" : (MAC ? "8pt" : function() { return true; });
+
+const kAbsentFontFamily =
+ function(aFontFamily) { return aFontFamily != "sans-serif"; }
+const kInputFontFamily =
+ function(aFontFamily) { return aFontFamily != "sans-serif"; }
+
+const kMonospaceFontFamily =
+ function(aFontFamily) { return aFontFamily != "monospace"; }
+const kSansSerifFontFamily =
+ function(aFontFamily) { return aFontFamily != "sans-serif"; }
+const kSerifFontFamily =
+ function(aFontFamily) { return aFontFamily != "serif"; }
+
+const kCursiveFontFamily = LINUX ? "DejaVu Serif" : "Comic Sans MS";
+
+/**
+ * Return used font from the given computed style.
+ */
+function fontFamily(aComputedStyle)
+{
+ var name = aComputedStyle.fontFamily;
+ switch (name) {
+ case "monospace":
+ return kMonospaceFontFamily;
+ case "sans-serif":
+ return kSansSerifFontFamily;
+ case "serif":
+ return kSerifFontFamily;
+ default:
+ return name;
+ }
+}
+
+/**
+ * Build an object of default text attributes expected for the given accessible.
+ *
+ * @param aID [in] identifier of accessible
+ * @param aFontSize [in] font size
+ * @param aFontWeight [in, optional] kBoldFontWeight or kNormalFontWeight,
+ * default value is kNormalFontWeight
+ */
+function buildDefaultTextAttrs(aID, aFontSize, aFontWeight, aFontFamily)
+{
+ var elm = getNode(aID);
+ var computedStyle = document.defaultView.getComputedStyle(elm, "");
+ var bgColor = computedStyle.backgroundColor == "transparent" ?
+ "rgb(255, 255, 255)" : computedStyle.backgroundColor;
+
+ var defAttrs = {
+ "font-style": computedStyle.fontStyle,
+ "font-size": aFontSize,
+ "background-color": bgColor,
+ "font-weight": aFontWeight ? aFontWeight : kNormalFontWeight,
+ "color": computedStyle.color,
+ "font-family": aFontFamily ? aFontFamily : fontFamily(computedStyle),
+ "text-position": computedStyle.verticalAlign
+ };
+
+ return defAttrs;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Private.
+
+function getTextAttributes(aID, aAccessible, aIncludeDefAttrs, aOffset,
+ aStartOffset, aEndOffset)
+{
+ // This function expects the passed in accessible to already be queried for
+ // nsIAccessibleText.
+ var attrs = null;
+ try {
+ attrs = aAccessible.getTextAttributes(aIncludeDefAttrs, aOffset,
+ aStartOffset, aEndOffset);
+ } catch (e) {
+ }
+
+ if (attrs)
+ return attrs;
+
+ ok(false, "Can't get text attributes for " + aID);
+ return null;
+}
+
+function testAttrsInternal(aAccOrElmOrID, aAttrs, aSkipUnexpectedAttrs,
+ aAbsentAttrs)
+{
+ var accessible = getAccessible(aAccOrElmOrID);
+ if (!accessible)
+ return;
+
+ var attrs = null;
+ try {
+ attrs = accessible.attributes;
+ } catch (e) { }
+
+ if (!attrs) {
+ ok(false, "Can't get object attributes for " + prettyName(aAccOrElmOrID));
+ return;
+ }
+
+ var errorMsg = " for " + prettyName(aAccOrElmOrID);
+ compareAttrs(errorMsg, attrs, aAttrs, aSkipUnexpectedAttrs, aAbsentAttrs);
+}
+
+function compareAttrs(aErrorMsg, aAttrs, aExpectedAttrs, aSkipUnexpectedAttrs,
+ aAbsentAttrs)
+{
+ // Check if all obtained attributes are expected and have expected value.
+ var enumerate = aAttrs.enumerate();
+ while (enumerate.hasMoreElements()) {
+ var prop = enumerate.getNext().QueryInterface(nsIPropertyElement);
+
+ if (!(prop.key in aExpectedAttrs)) {
+ if (!aSkipUnexpectedAttrs)
+ ok(false, "Unexpected attribute '" + prop.key + "' having '" +
+ prop.value + "'" + aErrorMsg);
+ } else {
+ var msg = "Attribute '" + prop.key + "' has wrong value" + aErrorMsg;
+ var expectedValue = aExpectedAttrs[prop.key];
+
+ if (typeof expectedValue == "function")
+ ok(expectedValue(prop.value), msg);
+ else
+ is(prop.value, expectedValue, msg);
+ }
+ }
+
+ // Check if all expected attributes are presented.
+ for (var name in aExpectedAttrs) {
+ var value = "";
+ try {
+ value = aAttrs.getStringProperty(name);
+ } catch(e) { }
+
+ if (!value)
+ ok(false,
+ "There is no expected attribute '" + name + "' " + aErrorMsg);
+ }
+
+ // Check if all unexpected attributes are absent.
+ if (aAbsentAttrs) {
+ for (var name in aAbsentAttrs) {
+ var wasFound = false;
+
+ var enumerate = aAttrs.enumerate();
+ while (enumerate.hasMoreElements()) {
+ var prop = enumerate.getNext().QueryInterface(nsIPropertyElement);
+ if (prop.key == name)
+ wasFound = true;
+ }
+ }
+
+ ok(!wasFound,
+ "There is an unexpected attribute '" + name + "' " + aErrorMsg);
+ }
+}