Bug 1312816 - Preemptively start a11y in chrome when raisesAccessibilityExceptions marionette capability is set. r=ato

MozReview-Commit-ID: KshEWHvz8SD

--HG--
extra : rebase_source : 88e7d86bbe525ea635f22bd03b6b501ad3e6e9b0
This commit is contained in:
Yura Zenevich 2016-11-07 12:15:08 -05:00
Родитель 4e2ad82fdd
Коммит 1d865a477d
2 изменённых файлов: 49 добавлений и 27 удалений

Просмотреть файл

@ -9,6 +9,8 @@ const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Log.jsm");
const logger = Log.repository.getLogger("Marionette");
Cu.import("chrome://marionette/content/error.js");
XPCOMUtils.defineLazyModuleGetter(
@ -16,13 +18,20 @@ XPCOMUtils.defineLazyModuleGetter(
XPCOMUtils.defineLazyModuleGetter(
this, "clearInterval", "resource://gre/modules/Timer.jsm");
XPCOMUtils.defineLazyGetter(this, "service",
() => Cc["@mozilla.org/accessibilityService;1"].getService(Ci.nsIAccessibilityService));
XPCOMUtils.defineLazyGetter(this, "service", () => {
let service;
try {
service = Cc["@mozilla.org/accessibilityService;1"].getService(
Ci.nsIAccessibilityService);
} catch (e) {
logger.warn("Accessibility module is not present");
} finally {
return service;
}
});
this.EXPORTED_SYMBOLS = ["accessibility"];
const logger = Log.repository.getLogger("Marionette");
/**
* Number of attempts to get an accessible object for an element.
* We attempt more than once because accessible tree can be out of sync
@ -36,7 +45,11 @@ const GET_ACCESSIBLE_ATTEMPTS = 100;
*/
const GET_ACCESSIBLE_ATTEMPT_INTERVAL = 10;
this.accessibility = {};
this.accessibility = {
get service() {
return service;
}
};
/**
* Accessible states used to check element"s state from the accessiblity API
@ -123,30 +136,32 @@ accessibility.Checks = class {
* Flag indicating that the element must have an accessible object.
* Defaults to not require this.
*
* @return {nsIAccessible}
* Accessibility object for the given element.
* @return {Promise: nsIAccessible}
* Promise with an accessibility object for the given element.
*/
getAccessible(element, mustHaveAccessible = false) {
if (!this.strict) {
return Promise.resolve();
}
return new Promise((resolve, reject) => {
let acc = service.getAccessibleFor(element);
// if accessible object is found, return it;
// if it is not required, also resolve
if (acc || !mustHaveAccessible) {
resolve(acc);
// if we must have an accessible but are strict,
// reject now and avoid polling for an accessible object
} else if (mustHaveAccessible && !this.strict) {
if (!accessibility.service) {
reject();
return;
}
// if we require an accessible object, we need to poll for it
// because accessible tree might be
// out of sync with DOM tree for a short time
let acc = accessibility.service.getAccessibleFor(element);
if (acc || !mustHaveAccessible) {
// if accessible object is found, return it;
// if it is not required, also resolve
resolve(acc);
} else {
// if we require an accessible object, we need to poll for it
// because accessible tree might be
// out of sync with DOM tree for a short time
let attempts = GET_ACCESSIBLE_ATTEMPTS;
let intervalId = setInterval(() => {
let acc = service.getAccessibleFor(element);
let acc = accessibility.service.getAccessibleFor(element);
if (acc || --attempts <= 0) {
clearInterval(intervalId);
if (acc) {
@ -174,7 +189,7 @@ accessibility.Checks = class {
*/
isActionableRole(accessible) {
return accessibility.ActionableRoles.has(
service.getStringRole(accessible.role));
accessibility.service.getStringRole(accessible.role));
}
/**
@ -412,17 +427,15 @@ accessibility.Checks = class {
* If |strict| is true.
*/
error(message, element) {
if (!message) {
if (!message || !this.strict) {
return;
}
if (element) {
let {id, tagName, className} = element;
message += `: id: ${id}, tagName: ${tagName}, className: ${className}`;
}
if (this.strict) {
throw new ElementNotAccessibleError(message);
}
logger.debug(message);
throw new ElementNotAccessibleError(message);
}
};

Просмотреть файл

@ -17,6 +17,7 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyServiceGetter(
this, "cookieManager", "@mozilla.org/cookiemanager;1", "nsICookieManager2");
Cu.import("chrome://marionette/content/accessibility.js");
Cu.import("chrome://marionette/content/atom.js");
Cu.import("chrome://marionette/content/browser.js");
Cu.import("chrome://marionette/content/element.js");
@ -484,6 +485,14 @@ GeckoDriver.prototype.newSession = function*(cmd, resp) {
this.newSessionCommandId = cmd.id;
this.setSessionCapabilities(cmd.parameters.capabilities);
// If we are testing accessibility with marionette, start a11y service in
// chrome first. This will ensure that we do not have any content-only
// services hanging around.
if (this.sessionCapabilities.raisesAccessibilityExceptions &&
accessibility.service) {
logger.info("Preemptively starting accessibility service in Chrome");
}
this.scriptTimeout = 10000;
let registerBrowsers = this.registerPromise();