Bug 1275586 - adding description caching tests. r=eeejay
authorYura Zenevich <yzenevich@mozilla.com>
Wed, 25 May 2016 10:47:45 -0400
changeset 371111 fbcbc3e1aa5bbae2d25f6037b543ff9028e0121a
parent 371110 f59273abb81006a6bd85c8287849eacd32d63ca7
child 371112 f3c508b6292133376aacba82969a43cf29f0cc87
push id19232
push userbmo:gps@mozilla.com
push dateWed, 25 May 2016 22:36:54 +0000
reviewerseeejay
bugs1275586
milestone49.0a1
Bug 1275586 - adding description caching tests. r=eeejay MozReview-Commit-ID: HFxjW74WnfK
accessible/tests/browser/.eslintrc
accessible/tests/browser/browser.ini
accessible/tests/browser/browser_caching_description.js
accessible/tests/browser/events.js
accessible/tests/browser/head.js
--- a/accessible/tests/browser/.eslintrc
+++ b/accessible/tests/browser/.eslintrc
@@ -7,16 +7,17 @@
     // Content scripts have global 'content' object
     "content": true,
 
     // Defined in accessible/tests/mochitest/ common.js, name.js, states.js
     "prettyName": true,
     "statesToString": true,
     "eventTypeToString": true,
     "testName": true,
+    "testDescr": true,
     "testStates": true,
     "testAccessibleTree": true,
     "isAccessible": true,
     "getAccessibleDOMNodeID": true,
 
     // Defined for all accessibility browser tests.
     "addAccessibleTask": true,
     "BrowserTestUtils": true,
--- a/accessible/tests/browser/browser.ini
+++ b/accessible/tests/browser/browser.ini
@@ -9,16 +9,17 @@ support-files =
   doc_treeupdate_removal.xhtml
   doc_treeupdate_visibility.html
   doc_treeupdate_whitespace.html
   !/accessible/tests/mochitest/*.js
   !/accessible/tests/mochitest/letters.gif
   !/accessible/tests/mochitest/moz.png
 
 # Caching tests
+[browser_caching_description.js]
 [browser_caching_name.js]
 skip-if = e10s
 
 # Events tests
 [browser_events_caretmove.js]
 [browser_events_hide.js]
 [browser_events_show.js]
 [browser_events_statechange.js]
new file mode 100644
--- /dev/null
+++ b/accessible/tests/browser/browser_caching_description.js
@@ -0,0 +1,164 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+'use strict';
+
+/* global EVENT_DESCRIPTION_CHANGE, EVENT_NAME_CHANGE, EVENT_REORDER */
+
+loadScripts({ name: 'name.js', dir: MOCHITESTS_DIR });
+
+/**
+ * Test data has the format of:
+ * {
+ *   desc      {String}   description for better logging
+ *   expected  {String}   expected description value for a given accessible
+ *   attrs     {?Array}   an optional list of attributes to update
+ *   waitFor   {?Array}   an optional list of accessible events to wait for when
+ *                        attributes are updated
+ * }
+ */
+const tests = [{
+  desc: 'No description when there are no @alt, @title and @aria-describedby',
+  expected: ''
+}, {
+  desc: 'Description from @aria-describedby attribute',
+  attrs: [{
+    attr: 'aria-describedby',
+    value: 'description'
+  }],
+  waitFor: [{ eventType: EVENT_DESCRIPTION_CHANGE, id: 'image' }],
+  expected: 'aria description'
+}, {
+  desc: 'No description from @aria-describedby since it is the same as the ' +
+        '@alt attribute which is used as the name',
+  attrs: [{
+    attr: 'alt',
+    value: 'aria description'
+  }],
+  waitFor: [{ eventType: EVENT_REORDER, id: 'body' }],
+  expected: ''
+}, {
+  desc: 'Description from @aria-describedby attribute when @alt and ' +
+        '@aria-describedby are not the same',
+  attrs: [{
+    attr: 'aria-describedby',
+    value: 'description2'
+  }],
+  waitFor: [{ eventType: EVENT_DESCRIPTION_CHANGE, id: 'image' }],
+  expected: 'another description'
+}, {
+  desc: 'Description from @aria-describedby attribute when @title (used for ' +
+        'name) and @aria-describedby are not the same',
+  attrs: [{
+    attr: 'alt'
+  }, {
+    attr: 'title',
+    value: 'title'
+  }],
+  waitFor: [{ eventType: EVENT_REORDER, id: 'body' }],
+  expected: 'another description'
+}, {
+  desc: 'No description from @aria-describedby since it is the same as the ' +
+        '@title attribute which is used as the name',
+  attrs: [{
+    attr: 'title',
+    value: 'another description'
+  }],
+  waitFor: [{ eventType: EVENT_NAME_CHANGE, id: 'image' }],
+  expected: ''
+}, {
+  desc: 'No description with only @title attribute which is used as the name',
+  attrs: [{
+    attr: 'aria-describedby'
+  }],
+  waitFor: [{ eventType: EVENT_DESCRIPTION_CHANGE, id: 'image' }],
+  expected: ''
+}, {
+  desc: 'Description from @title attribute when @alt and @atitle are not the ' +
+        'same',
+  attrs: [{
+    attr: 'alt',
+    value: 'aria description'
+  }],
+  waitFor: [{ eventType: EVENT_REORDER, id: 'body' }],
+  expected: 'another description'
+}, {
+  desc: 'No description from @title since it is the same as the @alt ' +
+        'attribute which is used as the name',
+  attrs: [{
+    attr: 'alt',
+    value: 'another description'
+  }],
+  waitFor: [{ eventType: EVENT_NAME_CHANGE, id: 'image' }],
+  expected: ''
+}, {
+  desc: 'No description from @aria-describedby since it is the same as the ' +
+        '@alt (used for name) and @title attributes',
+  attrs: [{
+    attr: 'aria-describedby',
+    value: 'description2'
+  }],
+  waitFor: [{ eventType: EVENT_DESCRIPTION_CHANGE, id: 'image' }],
+  expected: ''
+}, {
+  desc: 'Description from @aria-describedby attribute when it is different ' +
+        'from @alt (used for name) and @title attributes',
+  attrs: [{
+    attr: 'aria-describedby',
+    value: 'description'
+  }],
+  waitFor: [{ eventType: EVENT_DESCRIPTION_CHANGE, id: 'image' }],
+  expected: 'aria description'
+}, {
+  desc: 'No description from @aria-describedby since it is the same as the ' +
+        '@alt attribute (used for name) but different from title',
+  attrs: [{
+    attr: 'alt',
+    value: 'aria description'
+  }],
+  waitFor: [{ eventType: EVENT_NAME_CHANGE, id: 'image' }],
+  expected: ''
+}, {
+  desc: 'Description from @aria-describedby attribute when @alt (used for ' +
+        'name) and @aria-describedby are not the same but @title and ' +
+        'aria-describedby are',
+  attrs: [{
+    attr: 'aria-describedby',
+    value: 'description2'
+  }],
+  waitFor: [{ eventType: EVENT_DESCRIPTION_CHANGE, id: 'image' }],
+  expected: 'another description'
+}];
+
+/**
+ * Test caching of accessible object description
+ */
+addAccessibleTask(`
+  <p id="description">aria description</p>
+  <p id="description2">another description</p>
+  <img id="image" />`,
+  function*(browser, accDoc) {
+    let imgAcc = findAccessibleChildByID(accDoc, 'image');
+
+    for (let { desc, waitFor, attrs, expected } of tests) {
+      info(desc);
+      let onUpdate;
+      if (waitFor) {
+        onUpdate = waitForMultipleEvents(waitFor);
+      }
+      if (attrs) {
+        for (let { attr, value } of attrs) {
+          yield invokeSetAttribute(browser, 'image', attr, value);
+        }
+      }
+      yield onUpdate;
+      // When attribute change (alt) triggers reorder event, accessible will
+      // become defunct.
+      if (isDefunct(imgAcc)) {
+        imgAcc = findAccessibleChildByID(accDoc, 'image');
+      }
+      testDescr(imgAcc, expected);
+    }
+  }
+);
--- a/accessible/tests/browser/events.js
+++ b/accessible/tests/browser/events.js
@@ -4,26 +4,29 @@
 
 'use strict';
 
 /* global nsIAccessibleEvent, nsIAccessibleDocument,
           nsIAccessibleStateChangeEvent, nsIAccessibleTextChangeEvent */
 
 /* exported EVENT_REORDER, EVENT_SHOW, EVENT_TEXT_INSERTED, EVENT_TEXT_REMOVED,
             EVENT_DOCUMENT_LOAD_COMPLETE, EVENT_HIDE, EVENT_TEXT_CARET_MOVED,
-            EVENT_STATE_CHANGE, waitForEvent, waitForMultipleEvents */
+            EVENT_DESCRIPTION_CHANGE, EVENT_NAME_CHANGE, EVENT_STATE_CHANGE,
+            waitForEvent, waitForMultipleEvents */
 
 const EVENT_DOCUMENT_LOAD_COMPLETE = nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_COMPLETE;
 const EVENT_HIDE = nsIAccessibleEvent.EVENT_HIDE;
 const EVENT_REORDER = nsIAccessibleEvent.EVENT_REORDER;
 const EVENT_SHOW = nsIAccessibleEvent.EVENT_SHOW;
 const EVENT_STATE_CHANGE = nsIAccessibleEvent.EVENT_STATE_CHANGE;
 const EVENT_TEXT_CARET_MOVED = nsIAccessibleEvent.EVENT_TEXT_CARET_MOVED;
 const EVENT_TEXT_INSERTED = nsIAccessibleEvent.EVENT_TEXT_INSERTED;
 const EVENT_TEXT_REMOVED = nsIAccessibleEvent.EVENT_TEXT_REMOVED;
+const EVENT_DESCRIPTION_CHANGE = nsIAccessibleEvent.EVENT_DESCRIPTION_CHANGE;
+const EVENT_NAME_CHANGE = nsIAccessibleEvent.EVENT_NAME_CHANGE;
 
 /**
  * Describe an event in string format.
  * @param  {nsIAccessibleEvent}  event  event to strigify
  */
 function eventToString(event) {
   let type = eventTypeToString(event.eventType);
   let info = `Event type: ${type}`;
--- a/accessible/tests/browser/head.js
+++ b/accessible/tests/browser/head.js
@@ -82,23 +82,29 @@ let Logger = {
 };
 
 /**
  * Check if an accessible object has a defunct test.
  * @param  {nsIAccessible}  accessible object to test defunct state for
  * @return {Boolean}        flag indicating defunct state
  */
 function isDefunct(accessible) {
+  let defunct = false;
   try {
     let extState = {};
     accessible.getState({}, extState);
-    return extState.value & Ci.nsIAccessibleStates.EXT_STATE_DEFUNCT;
+    defunct = extState.value & Ci.nsIAccessibleStates.EXT_STATE_DEFUNCT;
   } catch (x) {
-    return true;
+    defunct = true;
+  } finally {
+    if (defunct) {
+      Logger.log(`Defunct accessible: ${prettyName(accessible)}`);
+    }
   }
+  return defunct;
 }
 
 /**
  * Asynchronously set or remove content element's attribute (in content process
  * if e10s is enabled).
  * @param  {Object}  browser  current "tabbrowser" element
  * @param  {String}  id       content element id
  * @param  {String}  attr     attribute name