accessible/tests/mochitest/attributes.js

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

michael@0 1 ////////////////////////////////////////////////////////////////////////////////
michael@0 2 // Object attributes.
michael@0 3
michael@0 4 /**
michael@0 5 * Test object attributes.
michael@0 6 *
michael@0 7 * @param aAccOrElmOrID [in] the accessible identifier
michael@0 8 * @param aAttrs [in] the map of expected object attributes
michael@0 9 * (name/value pairs)
michael@0 10 * @param aSkipUnexpectedAttrs [in] points this function doesn't fail if
michael@0 11 * unexpected attribute is encountered
michael@0 12 */
michael@0 13 function testAttrs(aAccOrElmOrID, aAttrs, aSkipUnexpectedAttrs)
michael@0 14 {
michael@0 15 testAttrsInternal(aAccOrElmOrID, aAttrs, aSkipUnexpectedAttrs);
michael@0 16 }
michael@0 17
michael@0 18 /**
michael@0 19 * Test object attributes that must not be present.
michael@0 20 *
michael@0 21 * @param aAccOrElmOrID [in] the accessible identifier
michael@0 22 * @param aAbsentAttrs [in] map of attributes that should not be
michael@0 23 * present (name/value pairs)
michael@0 24 */
michael@0 25 function testAbsentAttrs(aAccOrElmOrID, aAbsentAttrs)
michael@0 26 {
michael@0 27 testAttrsInternal(aAccOrElmOrID, {}, true, aAbsentAttrs);
michael@0 28 }
michael@0 29
michael@0 30 /**
michael@0 31 * Test CSS based object attributes.
michael@0 32 */
michael@0 33 function testCSSAttrs(aID)
michael@0 34 {
michael@0 35 var node = document.getElementById(aID);
michael@0 36 var computedStyle = document.defaultView.getComputedStyle(node, "");
michael@0 37
michael@0 38 var attrs = {
michael@0 39 "display": computedStyle.display,
michael@0 40 "text-align": computedStyle.textAlign,
michael@0 41 "text-indent": computedStyle.textIndent,
michael@0 42 "margin-left": computedStyle.marginLeft,
michael@0 43 "margin-right": computedStyle.marginRight,
michael@0 44 "margin-top": computedStyle.marginTop,
michael@0 45 "margin-bottom": computedStyle.marginBottom
michael@0 46 };
michael@0 47 testAttrs(aID, attrs, true);
michael@0 48 }
michael@0 49
michael@0 50 /**
michael@0 51 * Test the accessible that it doesn't have CSS-based object attributes.
michael@0 52 */
michael@0 53 function testAbsentCSSAttrs(aID)
michael@0 54 {
michael@0 55 var attrs = {
michael@0 56 "display": "",
michael@0 57 "text-align": "",
michael@0 58 "text-indent": "",
michael@0 59 "margin-left": "",
michael@0 60 "margin-right": "",
michael@0 61 "margin-top": "",
michael@0 62 "margin-bottom": ""
michael@0 63 };
michael@0 64 testAbsentAttrs(aID, attrs);
michael@0 65 }
michael@0 66
michael@0 67 /**
michael@0 68 * Test group object attributes (posinset, setsize and level) and
michael@0 69 * nsIAccessible::groupPosition() method.
michael@0 70 *
michael@0 71 * @param aAccOrElmOrID [in] the ID, DOM node or accessible
michael@0 72 * @param aPosInSet [in] the value of 'posinset' attribute
michael@0 73 * @param aSetSize [in] the value of 'setsize' attribute
michael@0 74 * @param aLevel [in, optional] the value of 'level' attribute
michael@0 75 */
michael@0 76 function testGroupAttrs(aAccOrElmOrID, aPosInSet, aSetSize, aLevel)
michael@0 77 {
michael@0 78 var acc = getAccessible(aAccOrElmOrID);
michael@0 79 var levelObj = {}, posInSetObj = {}, setSizeObj = {};
michael@0 80 acc.groupPosition(levelObj, setSizeObj, posInSetObj);
michael@0 81
michael@0 82 if (aPosInSet && aSetSize) {
michael@0 83 is(posInSetObj.value, aPosInSet,
michael@0 84 "Wrong group position (posinset) for " + prettyName(aAccOrElmOrID));
michael@0 85 is(setSizeObj.value, aSetSize,
michael@0 86 "Wrong size of the group (setsize) for " + prettyName(aAccOrElmOrID));
michael@0 87
michael@0 88 var attrs = {
michael@0 89 "posinset": String(aPosInSet),
michael@0 90 "setsize": String(aSetSize)
michael@0 91 };
michael@0 92 testAttrs(aAccOrElmOrID, attrs, true);
michael@0 93 }
michael@0 94
michael@0 95 if (aLevel) {
michael@0 96 is(levelObj.value, aLevel,
michael@0 97 "Wrong group level for " + prettyName(aAccOrElmOrID));
michael@0 98
michael@0 99 var attrs = { "level" : String(aLevel) };
michael@0 100 testAttrs(aAccOrElmOrID, attrs, true);
michael@0 101 }
michael@0 102 }
michael@0 103
michael@0 104 ////////////////////////////////////////////////////////////////////////////////
michael@0 105 // Text attributes.
michael@0 106
michael@0 107 /**
michael@0 108 * Test text attributes.
michael@0 109 *
michael@0 110 * @param aID [in] the ID of DOM element having text
michael@0 111 * accessible
michael@0 112 * @param aOffset [in] the offset inside text accessible to fetch
michael@0 113 * text attributes
michael@0 114 * @param aAttrs [in] the map of expected text attributes
michael@0 115 * (name/value pairs) exposed at the offset
michael@0 116 * @param aDefAttrs [in] the map of expected text attributes
michael@0 117 * (name/value pairs) exposed on hyper text
michael@0 118 * accessible
michael@0 119 * @param aStartOffset [in] expected start offset where text attributes
michael@0 120 * are applied
michael@0 121 * @param aEndOffset [in] expected end offset where text attribute
michael@0 122 * are applied
michael@0 123 * @param aSkipUnexpectedAttrs [in] points the function doesn't fail if
michael@0 124 * unexpected attribute is encountered
michael@0 125 */
michael@0 126 function testTextAttrs(aID, aOffset, aAttrs, aDefAttrs,
michael@0 127 aStartOffset, aEndOffset, aSkipUnexpectedAttrs)
michael@0 128 {
michael@0 129 var accessible = getAccessible(aID, [nsIAccessibleText]);
michael@0 130 if (!accessible)
michael@0 131 return;
michael@0 132
michael@0 133 var startOffset = { value: -1 };
michael@0 134 var endOffset = { value: -1 };
michael@0 135
michael@0 136 // do not include attributes exposed on hyper text accessbile
michael@0 137 var attrs = getTextAttributes(aID, accessible, false, aOffset,
michael@0 138 startOffset, endOffset);
michael@0 139
michael@0 140 if (!attrs)
michael@0 141 return;
michael@0 142
michael@0 143 var errorMsg = " for " + aID + " at offset " + aOffset;
michael@0 144
michael@0 145 is(startOffset.value, aStartOffset, "Wrong start offset" + errorMsg);
michael@0 146 is(endOffset.value, aEndOffset, "Wrong end offset" + errorMsg);
michael@0 147
michael@0 148 compareAttrs(errorMsg, attrs, aAttrs, aSkipUnexpectedAttrs);
michael@0 149
michael@0 150 // include attributes exposed on hyper text accessbile
michael@0 151 var expectedAttrs = {};
michael@0 152 for (var name in aAttrs)
michael@0 153 expectedAttrs[name] = aAttrs[name];
michael@0 154
michael@0 155 for (var name in aDefAttrs) {
michael@0 156 if (!(name in expectedAttrs))
michael@0 157 expectedAttrs[name] = aDefAttrs[name];
michael@0 158 }
michael@0 159
michael@0 160 attrs = getTextAttributes(aID, accessible, true, aOffset,
michael@0 161 startOffset, endOffset);
michael@0 162
michael@0 163 if (!attrs)
michael@0 164 return;
michael@0 165
michael@0 166 compareAttrs(errorMsg, attrs, expectedAttrs, aSkipUnexpectedAttrs);
michael@0 167 }
michael@0 168
michael@0 169 /**
michael@0 170 * Test default text attributes.
michael@0 171 *
michael@0 172 * @param aID [in] the ID of DOM element having text
michael@0 173 * accessible
michael@0 174 * @param aDefAttrs [in] the map of expected text attributes
michael@0 175 * (name/value pairs)
michael@0 176 * @param aSkipUnexpectedAttrs [in] points the function doesn't fail if
michael@0 177 * unexpected attribute is encountered
michael@0 178 */
michael@0 179 function testDefaultTextAttrs(aID, aDefAttrs, aSkipUnexpectedAttrs)
michael@0 180 {
michael@0 181 var accessible = getAccessible(aID, [nsIAccessibleText]);
michael@0 182 if (!accessible)
michael@0 183 return;
michael@0 184
michael@0 185 var defAttrs = null;
michael@0 186 try{
michael@0 187 defAttrs = accessible.defaultTextAttributes;
michael@0 188 } catch (e) {
michael@0 189 }
michael@0 190
michael@0 191 if (!defAttrs) {
michael@0 192 ok(false, "Can't get default text attributes for " + aID);
michael@0 193 return;
michael@0 194 }
michael@0 195
michael@0 196 var errorMsg = ". Getting default text attributes for " + aID;
michael@0 197 compareAttrs(errorMsg, defAttrs, aDefAttrs, aSkipUnexpectedAttrs);
michael@0 198 }
michael@0 199
michael@0 200 /**
michael@0 201 * Test text attributes for wrong offset.
michael@0 202 */
michael@0 203 function testTextAttrsWrongOffset(aID, aOffset)
michael@0 204 {
michael@0 205 var res = false;
michael@0 206 try {
michael@0 207 var s = {}, e = {};
michael@0 208 var acc = getAccessible(ID, [nsIAccessibleText]);
michael@0 209 acc.getTextAttributes(false, 157, s, e);
michael@0 210 } catch (e) {
michael@0 211 res = true;
michael@0 212 }
michael@0 213
michael@0 214 ok(res,
michael@0 215 "text attributes are calculated successfully at wrong offset " + aOffset + " for " + prettyName(aID));
michael@0 216 }
michael@0 217
michael@0 218 const kNormalFontWeight =
michael@0 219 function equalsToNormal(aWeight) { return aWeight <= 400 ; }
michael@0 220
michael@0 221 const kBoldFontWeight =
michael@0 222 function equalsToBold(aWeight) { return aWeight > 400; }
michael@0 223
michael@0 224 // The pt font size of the input element can vary by Linux distro.
michael@0 225 const kInputFontSize = WIN ?
michael@0 226 "10pt" : (MAC ? "8pt" : function() { return true; });
michael@0 227
michael@0 228 const kAbsentFontFamily =
michael@0 229 function(aFontFamily) { return aFontFamily != "sans-serif"; }
michael@0 230 const kInputFontFamily =
michael@0 231 function(aFontFamily) { return aFontFamily != "sans-serif"; }
michael@0 232
michael@0 233 const kMonospaceFontFamily =
michael@0 234 function(aFontFamily) { return aFontFamily != "monospace"; }
michael@0 235 const kSansSerifFontFamily =
michael@0 236 function(aFontFamily) { return aFontFamily != "sans-serif"; }
michael@0 237 const kSerifFontFamily =
michael@0 238 function(aFontFamily) { return aFontFamily != "serif"; }
michael@0 239
michael@0 240 const kCursiveFontFamily = LINUX ? "DejaVu Serif" : "Comic Sans MS";
michael@0 241
michael@0 242 /**
michael@0 243 * Return used font from the given computed style.
michael@0 244 */
michael@0 245 function fontFamily(aComputedStyle)
michael@0 246 {
michael@0 247 var name = aComputedStyle.fontFamily;
michael@0 248 switch (name) {
michael@0 249 case "monospace":
michael@0 250 return kMonospaceFontFamily;
michael@0 251 case "sans-serif":
michael@0 252 return kSansSerifFontFamily;
michael@0 253 case "serif":
michael@0 254 return kSerifFontFamily;
michael@0 255 default:
michael@0 256 return name;
michael@0 257 }
michael@0 258 }
michael@0 259
michael@0 260 /**
michael@0 261 * Build an object of default text attributes expected for the given accessible.
michael@0 262 *
michael@0 263 * @param aID [in] identifier of accessible
michael@0 264 * @param aFontSize [in] font size
michael@0 265 * @param aFontWeight [in, optional] kBoldFontWeight or kNormalFontWeight,
michael@0 266 * default value is kNormalFontWeight
michael@0 267 */
michael@0 268 function buildDefaultTextAttrs(aID, aFontSize, aFontWeight, aFontFamily)
michael@0 269 {
michael@0 270 var elm = getNode(aID);
michael@0 271 var computedStyle = document.defaultView.getComputedStyle(elm, "");
michael@0 272 var bgColor = computedStyle.backgroundColor == "transparent" ?
michael@0 273 "rgb(255, 255, 255)" : computedStyle.backgroundColor;
michael@0 274
michael@0 275 var defAttrs = {
michael@0 276 "font-style": computedStyle.fontStyle,
michael@0 277 "font-size": aFontSize,
michael@0 278 "background-color": bgColor,
michael@0 279 "font-weight": aFontWeight ? aFontWeight : kNormalFontWeight,
michael@0 280 "color": computedStyle.color,
michael@0 281 "font-family": aFontFamily ? aFontFamily : fontFamily(computedStyle),
michael@0 282 "text-position": computedStyle.verticalAlign
michael@0 283 };
michael@0 284
michael@0 285 return defAttrs;
michael@0 286 }
michael@0 287
michael@0 288 ////////////////////////////////////////////////////////////////////////////////
michael@0 289 // Private.
michael@0 290
michael@0 291 function getTextAttributes(aID, aAccessible, aIncludeDefAttrs, aOffset,
michael@0 292 aStartOffset, aEndOffset)
michael@0 293 {
michael@0 294 // This function expects the passed in accessible to already be queried for
michael@0 295 // nsIAccessibleText.
michael@0 296 var attrs = null;
michael@0 297 try {
michael@0 298 attrs = aAccessible.getTextAttributes(aIncludeDefAttrs, aOffset,
michael@0 299 aStartOffset, aEndOffset);
michael@0 300 } catch (e) {
michael@0 301 }
michael@0 302
michael@0 303 if (attrs)
michael@0 304 return attrs;
michael@0 305
michael@0 306 ok(false, "Can't get text attributes for " + aID);
michael@0 307 return null;
michael@0 308 }
michael@0 309
michael@0 310 function testAttrsInternal(aAccOrElmOrID, aAttrs, aSkipUnexpectedAttrs,
michael@0 311 aAbsentAttrs)
michael@0 312 {
michael@0 313 var accessible = getAccessible(aAccOrElmOrID);
michael@0 314 if (!accessible)
michael@0 315 return;
michael@0 316
michael@0 317 var attrs = null;
michael@0 318 try {
michael@0 319 attrs = accessible.attributes;
michael@0 320 } catch (e) { }
michael@0 321
michael@0 322 if (!attrs) {
michael@0 323 ok(false, "Can't get object attributes for " + prettyName(aAccOrElmOrID));
michael@0 324 return;
michael@0 325 }
michael@0 326
michael@0 327 var errorMsg = " for " + prettyName(aAccOrElmOrID);
michael@0 328 compareAttrs(errorMsg, attrs, aAttrs, aSkipUnexpectedAttrs, aAbsentAttrs);
michael@0 329 }
michael@0 330
michael@0 331 function compareAttrs(aErrorMsg, aAttrs, aExpectedAttrs, aSkipUnexpectedAttrs,
michael@0 332 aAbsentAttrs)
michael@0 333 {
michael@0 334 // Check if all obtained attributes are expected and have expected value.
michael@0 335 var enumerate = aAttrs.enumerate();
michael@0 336 while (enumerate.hasMoreElements()) {
michael@0 337 var prop = enumerate.getNext().QueryInterface(nsIPropertyElement);
michael@0 338
michael@0 339 if (!(prop.key in aExpectedAttrs)) {
michael@0 340 if (!aSkipUnexpectedAttrs)
michael@0 341 ok(false, "Unexpected attribute '" + prop.key + "' having '" +
michael@0 342 prop.value + "'" + aErrorMsg);
michael@0 343 } else {
michael@0 344 var msg = "Attribute '" + prop.key + "' has wrong value" + aErrorMsg;
michael@0 345 var expectedValue = aExpectedAttrs[prop.key];
michael@0 346
michael@0 347 if (typeof expectedValue == "function")
michael@0 348 ok(expectedValue(prop.value), msg);
michael@0 349 else
michael@0 350 is(prop.value, expectedValue, msg);
michael@0 351 }
michael@0 352 }
michael@0 353
michael@0 354 // Check if all expected attributes are presented.
michael@0 355 for (var name in aExpectedAttrs) {
michael@0 356 var value = "";
michael@0 357 try {
michael@0 358 value = aAttrs.getStringProperty(name);
michael@0 359 } catch(e) { }
michael@0 360
michael@0 361 if (!value)
michael@0 362 ok(false,
michael@0 363 "There is no expected attribute '" + name + "' " + aErrorMsg);
michael@0 364 }
michael@0 365
michael@0 366 // Check if all unexpected attributes are absent.
michael@0 367 if (aAbsentAttrs) {
michael@0 368 for (var name in aAbsentAttrs) {
michael@0 369 var wasFound = false;
michael@0 370
michael@0 371 var enumerate = aAttrs.enumerate();
michael@0 372 while (enumerate.hasMoreElements()) {
michael@0 373 var prop = enumerate.getNext().QueryInterface(nsIPropertyElement);
michael@0 374 if (prop.key == name)
michael@0 375 wasFound = true;
michael@0 376 }
michael@0 377 }
michael@0 378
michael@0 379 ok(!wasFound,
michael@0 380 "There is an unexpected attribute '" + name + "' " + aErrorMsg);
michael@0 381 }
michael@0 382 }

mercurial