diff options
Diffstat (limited to 'accessible/tests/browser/e10s/events.js')
-rw-r--r-- | accessible/tests/browser/e10s/events.js | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/accessible/tests/browser/e10s/events.js b/accessible/tests/browser/e10s/events.js new file mode 100644 index 000000000..39dd743ef --- /dev/null +++ b/accessible/tests/browser/e10s/events.js @@ -0,0 +1,127 @@ +/* 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 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_DESCRIPTION_CHANGE, EVENT_NAME_CHANGE, EVENT_STATE_CHANGE, + EVENT_VALUE_CHANGE, EVENT_TEXT_VALUE_CHANGE, EVENT_FOCUS, + 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; +const EVENT_VALUE_CHANGE = nsIAccessibleEvent.EVENT_VALUE_CHANGE; +const EVENT_TEXT_VALUE_CHANGE = nsIAccessibleEvent.EVENT_TEXT_VALUE_CHANGE; +const EVENT_FOCUS = nsIAccessibleEvent.EVENT_FOCUS; + +/** + * 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}`; + + if (event instanceof nsIAccessibleStateChangeEvent) { + let stateStr = statesToString(event.isExtraState ? 0 : event.state, + event.isExtraState ? event.state : 0); + info += `, state: ${stateStr}, is enabled: ${event.isEnabled}`; + } else if (event instanceof nsIAccessibleTextChangeEvent) { + let tcType = event.isInserted ? 'inserted' : 'removed'; + info += `, start: ${event.start}, length: ${event.length}, ${tcType} text: ${event.modifiedText}`; + } + + info += `. Target: ${prettyName(event.accessible)}`; + return info; +} + +/** + * A helper function that returns a promise that resolves when an accessible + * event of the given type with the given target (defined by its id or + * accessible) is observed. + * @param {String|nsIAccessible} expectedIdOrAcc expected content element id + * for the event + * @param {Number} eventType expected accessible event + * type + * @return {Promise} promise that resolves to an + * event + */ +function waitForEvent(eventType, expectedIdOrAcc) { + return new Promise(resolve => { + let eventObserver = { + observe(subject, topic, data) { + if (topic !== 'accessible-event') { + return; + } + + let event = subject.QueryInterface(nsIAccessibleEvent); + if (Logger.enabled) { + // Avoid calling eventToString if the logger isn't enabled in order + // to avoid an intermittent crash (bug 1307645). + Logger.log(eventToString(event)); + } + + // If event type does not match expected type, skip the event. + if (event.eventType !== eventType) { + return; + } + + let acc = event.accessible; + let id = getAccessibleDOMNodeID(acc); + let isID = typeof expectedIdOrAcc === 'string'; + let actualIdOrAcc = isID ? id : acc; + // If event's accessible does not match expected DOMNode id or + // accessible, skip the event. + if (actualIdOrAcc === expectedIdOrAcc) { + if (isID) { + Logger.log(`Correct event DOMNode id: ${id}`); + } else { + Logger.log(`Correct event accessible: ${prettyName(acc)}`); + } + Logger.log(`Correct event type: ${eventTypeToString(eventType)}`); + ok(event.accessibleDocument instanceof nsIAccessibleDocument, + 'Accessible document present.'); + + Services.obs.removeObserver(this, 'accessible-event'); + resolve(event); + } + } + }; + Services.obs.addObserver(eventObserver, 'accessible-event', false); + }); +} + +/** + * A helper function that waits for a sequence of accessible events in + * specified order. + * @param {Array} events a list of events to wait (same format as + * waitForEvent arguments) + */ +function waitForMultipleEvents(events) { + // Next expected event index. + let currentIdx = 0; + + return Promise.all(events.map(({ eventType, id }, idx) => + // In addition to waiting for an event, attach an order checker for the + // event. + waitForEvent(eventType, id).then(resolvedEvent => { + // Verify that event happens in order and increment expected index. + is(idx, currentIdx++, + `Unexpected event order: ${eventToString(resolvedEvent)}`); + return resolvedEvent; + }) + )); +} |