Bug 1275586 - adding description caching tests. r=eeejay
MozReview-Commit-ID: HFxjW74WnfK
--- 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]
skip-if = e10s
[browser_events_show.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