зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1459677 - Promisify, simplify, and unabstract jsat content tests. r=yzen
This commit is contained in:
Родитель
4ea509a01c
Коммит
abb7638965
|
@ -166,7 +166,7 @@ var AccessFu = {
|
|||
},
|
||||
|
||||
_output: function _output(aPresentationData, aBrowser) {
|
||||
if (!aPresentationData || typeof aPresentationData == "string") {
|
||||
if (!aPresentationData) {
|
||||
// Either no android events to send or a string used for testing only.
|
||||
return;
|
||||
}
|
||||
|
@ -176,6 +176,10 @@ var AccessFu = {
|
|||
}
|
||||
|
||||
for (let evt of aPresentationData) {
|
||||
if (typeof evt == "string") {
|
||||
continue;
|
||||
}
|
||||
|
||||
Utils.win.WindowEventDispatcher.sendRequest({
|
||||
...evt,
|
||||
type: "GeckoView:AccessibilityEvent"
|
||||
|
|
|
@ -172,7 +172,7 @@ class AndroidPresentor {
|
|||
* @param {nsIAccessible} aObject the object that has been selected.
|
||||
*/
|
||||
selectionChanged(aObject) {
|
||||
return "todo.selection-changed";
|
||||
return ["todo.selection-changed"];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -181,7 +181,7 @@ class AndroidPresentor {
|
|||
* @param {nsIAccessible} aAccessible the object whose value has changed.
|
||||
*/
|
||||
nameChanged(aAccessible) {
|
||||
return "todo.name-changed";
|
||||
return ["todo.name-changed"];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -190,7 +190,7 @@ class AndroidPresentor {
|
|||
* @param {nsIAccessible} aAccessible the object whose value has changed.
|
||||
*/
|
||||
valueChanged(aAccessible) {
|
||||
return "todo.value-changed";
|
||||
return ["todo.value-changed"];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -11,9 +11,6 @@ skip-if = (os == 'win' && (os_version == '5.1' || os_version == '5.2'))
|
|||
|
||||
[test_alive.html]
|
||||
[test_content_integration.html]
|
||||
skip-if = buildapp == 'mulet'
|
||||
[test_content_text.html]
|
||||
skip-if = buildapp == 'mulet'
|
||||
[test_explicit_names.html]
|
||||
[test_hints.html]
|
||||
[test_landmarks.html]
|
||||
|
@ -21,5 +18,9 @@ skip-if = buildapp == 'mulet'
|
|||
[test_output_mathml.html]
|
||||
[test_output.html]
|
||||
[test_tables.html]
|
||||
[test_text_editable_navigation.html]
|
||||
[test_text_editing.html]
|
||||
[test_text_navigation_focus.html]
|
||||
[test_text_navigation.html]
|
||||
[test_traversal.html]
|
||||
[test_traversal_helper.html]
|
||||
|
|
|
@ -16,45 +16,10 @@
|
|||
"</body>" +
|
||||
"</html>";
|
||||
|
||||
function showAlert() {
|
||||
document.getElementById("alert").hidden = false;
|
||||
}
|
||||
|
||||
function hideAlert() {
|
||||
document.getElementById("alert").hidden = true;
|
||||
}
|
||||
|
||||
function ariaShowBack() {
|
||||
document.getElementById("back").setAttribute("aria-hidden", false);
|
||||
}
|
||||
|
||||
function ariaHideBack() {
|
||||
document.getElementById("back").setAttribute("aria-hidden", true);
|
||||
}
|
||||
|
||||
function ariaShowIframe() {
|
||||
document.getElementById("iframe").setAttribute("aria-hidden", false);
|
||||
}
|
||||
|
||||
function ariaHideIframe() {
|
||||
document.getElementById("iframe").setAttribute("aria-hidden", true);
|
||||
}
|
||||
|
||||
function renameFruit() {
|
||||
document.getElementById("fruit").setAttribute("aria-label", "banana");
|
||||
}
|
||||
|
||||
function renameSlider() {
|
||||
document.getElementById("slider").setAttribute(
|
||||
"aria-label", "mover");
|
||||
}
|
||||
|
||||
function changeSliderValue() {
|
||||
document.getElementById("slider").setAttribute("aria-valuenow", "5");
|
||||
document.getElementById("slider").setAttribute(
|
||||
"aria-valuetext", "medium");
|
||||
}
|
||||
|
||||
function toggleLight() {
|
||||
var lightSwitch = document.getElementById("light");
|
||||
lightSwitch.setAttribute("aria-checked",
|
||||
|
|
|
@ -19,6 +19,13 @@ ChromeUtils.import("resource://gre/modules/accessibility/Utils.jsm");
|
|||
ChromeUtils.import("resource://gre/modules/accessibility/EventManager.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/accessibility/Constants.jsm");
|
||||
|
||||
const MovementGranularity = {
|
||||
CHARACTER: 1,
|
||||
WORD: 2,
|
||||
LINE: 4,
|
||||
PARAGRAPH: 8
|
||||
};
|
||||
|
||||
var AccessFuTest = {
|
||||
|
||||
addFunc: function AccessFuTest_addFunc(aFunc) {
|
||||
|
@ -164,506 +171,263 @@ var AccessFuTest = {
|
|||
}
|
||||
};
|
||||
|
||||
function AccessFuContentTest(aFuncResultPairs) {
|
||||
this.queue = aFuncResultPairs;
|
||||
}
|
||||
|
||||
AccessFuContentTest.prototype = {
|
||||
expected: [],
|
||||
currentAction: null,
|
||||
actionNum: -1,
|
||||
class AccessFuContentTestRunner {
|
||||
constructor() {
|
||||
this.listenersMap = new Map();
|
||||
let frames = Array.from(currentTabDocument().querySelectorAll("iframe"));
|
||||
this.mms = [Utils.getMessageManager(currentBrowser()),
|
||||
...frames.map(f => Utils.getMessageManager(f)).filter(mm => !!mm)];
|
||||
}
|
||||
|
||||
start(aFinishedCallback) {
|
||||
Logger.logLevel = Logger.DEBUG;
|
||||
this.finishedCallback = aFinishedCallback;
|
||||
var self = this;
|
||||
|
||||
// Get top content message manager, and set it up.
|
||||
this.mms = [Utils.getMessageManager(currentBrowser())];
|
||||
this.setupMessageManager(this.mms[0], function() {
|
||||
// Get child message managers and set them up
|
||||
var frames = currentTabDocument().querySelectorAll("iframe");
|
||||
if (frames.length === 0) {
|
||||
self.pump();
|
||||
return;
|
||||
}
|
||||
|
||||
var toSetup = 0;
|
||||
for (var i = 0; i < frames.length; i++ ) {
|
||||
var mm = Utils.getMessageManager(frames[i]);
|
||||
if (mm) {
|
||||
toSetup++;
|
||||
self.mms.push(mm);
|
||||
self.setupMessageManager(mm, function() {
|
||||
if (--toSetup === 0) {
|
||||
// All message managers are loaded and ready to go.
|
||||
self.pump();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
return Promise.all(this.mms.map(mm => this.setupMessageManager(mm)));
|
||||
}
|
||||
|
||||
finish() {
|
||||
Logger.logLevel = Logger.INFO;
|
||||
this.listenersMap.clear();
|
||||
for (var mm of this.mms) {
|
||||
mm.sendAsyncMessage("AccessFu:Stop");
|
||||
mm.removeMessageListener("AccessFu:Present", this);
|
||||
mm.removeMessageListener("AccessFu:Input", this);
|
||||
mm.removeMessageListener("AccessFu:CursorCleared", this);
|
||||
mm.removeMessageListener("AccessFu:Focused", this);
|
||||
mm.removeMessageListener("AccessFu:AriaHidden", this);
|
||||
mm.removeMessageListener("AccessFu:Ready", this);
|
||||
mm.removeMessageListener("AccessFu:ContentStarted", this);
|
||||
}
|
||||
if (this.finishedCallback) {
|
||||
this.finishedCallback();
|
||||
mm.sendAsyncMessage("AccessFu:Stop");
|
||||
mm.removeMessageListener("AccessFu:Present", this);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
setupMessageManager(aMessageManager, aCallback) {
|
||||
sendMessage(message) {
|
||||
// First message manager is the top-level one.
|
||||
this.mms[0].sendAsyncMessage(message.name, message.data);
|
||||
}
|
||||
|
||||
androidEvent(eventType) {
|
||||
return new Promise(resolve => {
|
||||
if (!this.listenersMap.has(eventType)) {
|
||||
this.listenersMap.set(eventType, [resolve]);
|
||||
} else {
|
||||
this.listenersMap.get(eventType).push(resolve);
|
||||
}
|
||||
}).then(evt => {
|
||||
if (this.debug) {
|
||||
info("Resolving event: " + evt.eventType);
|
||||
}
|
||||
return evt;
|
||||
});
|
||||
}
|
||||
|
||||
isFocused(aExpected) {
|
||||
var doc = currentTabDocument();
|
||||
SimpleTest.is(doc.activeElement, doc.querySelector(aExpected),
|
||||
"Correct element is focused: " + aExpected);
|
||||
}
|
||||
|
||||
async setupMessageManager(aMessageManager) {
|
||||
function contentScript() {
|
||||
addMessageListener("AccessFuTest:Focus", function(aMessage) {
|
||||
var elem = content.document.querySelector(aMessage.json.selector);
|
||||
addMessageListener("AccessFuTest:Focus", aMessage => {
|
||||
var elem = content.document.querySelector(aMessage.data.selector);
|
||||
if (elem) {
|
||||
if (aMessage.json.blur) {
|
||||
elem.blur();
|
||||
} else {
|
||||
elem.focus();
|
||||
}
|
||||
elem.focus();
|
||||
}
|
||||
});
|
||||
|
||||
addMessageListener("AccessFuTest:Blur", () => {
|
||||
content.document.activeElement.blur();
|
||||
});
|
||||
}
|
||||
|
||||
aMessageManager.addMessageListener("AccessFu:Present", this);
|
||||
aMessageManager.addMessageListener("AccessFu:Input", this);
|
||||
aMessageManager.addMessageListener("AccessFu:CursorCleared", this);
|
||||
aMessageManager.addMessageListener("AccessFu:Focused", this);
|
||||
aMessageManager.addMessageListener("AccessFu:AriaHidden", this);
|
||||
aMessageManager.addMessageListener("AccessFu:Ready", function() {
|
||||
aMessageManager.addMessageListener("AccessFu:ContentStarted", aCallback);
|
||||
aMessageManager.sendAsyncMessage("AccessFu:Start",
|
||||
{ buildApp: "browser",
|
||||
androidSdkVersion: Utils.AndroidSdkVersion,
|
||||
logLevel: "DEBUG",
|
||||
inTest: true });
|
||||
});
|
||||
aMessageManager.loadFrameScript(
|
||||
"data:,(" + contentScript.toString() + ")();", false);
|
||||
|
||||
let readyPromise = new Promise(resolve =>
|
||||
aMessageManager.addMessageListener("AccessFu:Ready", resolve));
|
||||
|
||||
aMessageManager.loadFrameScript(
|
||||
"chrome://global/content/accessibility/content-script.js", false);
|
||||
aMessageManager.loadFrameScript(
|
||||
"data:,(" + contentScript.toString() + ")();", false);
|
||||
},
|
||||
|
||||
pump() {
|
||||
this.expected.shift();
|
||||
if (this.expected.length) {
|
||||
return;
|
||||
}
|
||||
await readyPromise;
|
||||
|
||||
var currentPair = this.queue.shift();
|
||||
let startedPromise = new Promise(resolve =>
|
||||
aMessageManager.addMessageListener("AccessFu:ContentStarted", resolve));
|
||||
|
||||
if (currentPair) {
|
||||
this.actionNum++;
|
||||
this.currentAction = currentPair[0];
|
||||
if (typeof this.currentAction === "function") {
|
||||
this.currentAction(this.mms[0]);
|
||||
} else if (this.currentAction) {
|
||||
this.mms[0].sendAsyncMessage(this.currentAction.name,
|
||||
this.currentAction.json);
|
||||
}
|
||||
aMessageManager.sendAsyncMessage("AccessFu:Start",
|
||||
{ buildApp: "browser",
|
||||
androidSdkVersion: Utils.AndroidSdkVersion,
|
||||
logLevel: "DEBUG",
|
||||
inTest: true });
|
||||
|
||||
this.expected = currentPair.slice(1, currentPair.length);
|
||||
await startedPromise;
|
||||
|
||||
if (!this.expected[0]) {
|
||||
this.pump();
|
||||
}
|
||||
} else {
|
||||
this.finish();
|
||||
}
|
||||
},
|
||||
aMessageManager.addMessageListener("AccessFu:Present", this);
|
||||
}
|
||||
|
||||
receiveMessage(aMessage) {
|
||||
var expected = this.expected[0];
|
||||
|
||||
if (!expected) {
|
||||
if (aMessage.name != "AccessFu:Present" || !aMessage.data) {
|
||||
return;
|
||||
}
|
||||
|
||||
var actionsString = typeof this.currentAction === "function" ?
|
||||
this.currentAction.toString() : JSON.stringify(this.currentAction);
|
||||
|
||||
if (typeof expected === "string") {
|
||||
ok(true, "Got " + expected + " after " + actionsString);
|
||||
this.pump();
|
||||
} else if (expected.ignore && !expected.ignore(aMessage)) {
|
||||
expected.is(aMessage.json, "after " + actionsString +
|
||||
" (" + this.actionNum + ")");
|
||||
expected.is_correct_focus();
|
||||
this.pump();
|
||||
for (let evt of aMessage.data) {
|
||||
if (this.debug) {
|
||||
info("Android event: " + JSON.stringify(evt));
|
||||
}
|
||||
let listener = (this.listenersMap.get(evt.eventType || evt) || []).shift();
|
||||
if (listener) {
|
||||
listener(evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Common content messages
|
||||
async expectAndroidEvents(aFunc, ...aExpectedEvents) {
|
||||
let events = Promise.all(aExpectedEvents.map(e => this.androidEvent(e)));
|
||||
aFunc();
|
||||
let gotEvents = await events;
|
||||
return gotEvents.length == 1 ? gotEvents[0] : gotEvents;
|
||||
}
|
||||
|
||||
var ContentMessages = {
|
||||
simpleMoveFirst: {
|
||||
name: "AccessFu:MoveCursor",
|
||||
json: {
|
||||
action: "moveFirst",
|
||||
rule: "Simple",
|
||||
inputType: "gesture",
|
||||
origin: "top"
|
||||
}
|
||||
},
|
||||
moveCursor(aArgs, ...aExpectedEvents) {
|
||||
return this.expectAndroidEvents(() => {
|
||||
this.sendMessage({
|
||||
name: "AccessFu:MoveCursor",
|
||||
data: {
|
||||
inputType: "gesture",
|
||||
origin: "top",
|
||||
...aArgs
|
||||
}
|
||||
});
|
||||
}, ...aExpectedEvents);
|
||||
}
|
||||
|
||||
simpleMoveLast: {
|
||||
name: "AccessFu:MoveCursor",
|
||||
json: {
|
||||
action: "moveLast",
|
||||
rule: "Simple",
|
||||
inputType: "gesture",
|
||||
origin: "top"
|
||||
}
|
||||
},
|
||||
moveNext(aRule, ...aExpectedEvents) {
|
||||
return this.moveCursor({ action: "moveNext", rule: aRule },
|
||||
...aExpectedEvents);
|
||||
}
|
||||
|
||||
simpleMoveNext: {
|
||||
name: "AccessFu:MoveCursor",
|
||||
json: {
|
||||
action: "moveNext",
|
||||
rule: "Simple",
|
||||
inputType: "gesture",
|
||||
origin: "top"
|
||||
}
|
||||
},
|
||||
movePrevious(aRule, ...aExpectedEvents) {
|
||||
return this.moveCursor({ action: "movePrevious", rule: aRule },
|
||||
...aExpectedEvents);
|
||||
}
|
||||
|
||||
simpleMovePrevious: {
|
||||
name: "AccessFu:MoveCursor",
|
||||
json: {
|
||||
action: "movePrevious",
|
||||
rule: "Simple",
|
||||
inputType: "gesture",
|
||||
origin: "top"
|
||||
}
|
||||
},
|
||||
moveFirst(aRule, ...aExpectedEvents) {
|
||||
return this.moveCursor({ action: "moveFirst", rule: aRule },
|
||||
...aExpectedEvents);
|
||||
}
|
||||
|
||||
clearCursor: {
|
||||
name: "AccessFu:ClearCursor",
|
||||
json: {
|
||||
origin: "top"
|
||||
}
|
||||
},
|
||||
moveLast(aRule, ...aExpectedEvents) {
|
||||
return this.moveCursor({ action: "moveLast", rule: aRule },
|
||||
...aExpectedEvents);
|
||||
}
|
||||
|
||||
moveOrAdjustUp: function moveOrAdjustUp(aRule) {
|
||||
return {
|
||||
name: "AccessFu:MoveCursor",
|
||||
json: {
|
||||
origin: "top",
|
||||
action: "movePrevious",
|
||||
inputType: "gesture",
|
||||
rule: (aRule || "Simple"),
|
||||
adjustRange: true
|
||||
}
|
||||
};
|
||||
},
|
||||
async clearCursor() {
|
||||
return new Promise(resolve => {
|
||||
let _listener = (msg) => {
|
||||
this.mms.forEach(
|
||||
mm => mm.removeMessageListener("AccessFu:CursorCleared", _listener));
|
||||
resolve();
|
||||
};
|
||||
this.mms.forEach(
|
||||
mm => mm.addMessageListener("AccessFu:CursorCleared", _listener));
|
||||
this.sendMessage({
|
||||
name: "AccessFu:ClearCursor",
|
||||
data: {
|
||||
origin: "top"
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
moveOrAdjustDown: function moveOrAdjustUp(aRule) {
|
||||
return {
|
||||
name: "AccessFu:MoveCursor",
|
||||
json: {
|
||||
origin: "top",
|
||||
action: "moveNext",
|
||||
inputType: "gesture",
|
||||
rule: (aRule || "Simple"),
|
||||
adjustRange: true
|
||||
}
|
||||
};
|
||||
},
|
||||
focusSelector(aSelector, ...aExpectedEvents) {
|
||||
return this.expectAndroidEvents(() => {
|
||||
this.sendMessage({
|
||||
name: "AccessFuTest:Focus",
|
||||
data: {
|
||||
selector: aSelector
|
||||
}
|
||||
});
|
||||
}, ...aExpectedEvents);
|
||||
}
|
||||
|
||||
androidScrollForward: function adjustUp() {
|
||||
return {
|
||||
blur(...aExpectedEvents) {
|
||||
return this.expectAndroidEvents(() => {
|
||||
this.sendMessage({ name: "AccessFuTest:Blur" });
|
||||
}, ...aExpectedEvents);
|
||||
}
|
||||
|
||||
activateCurrent(aOffset, ...aExpectedEvents) {
|
||||
return this.expectAndroidEvents(() => {
|
||||
this.sendMessage({
|
||||
name: "AccessFu:Activate",
|
||||
data: {
|
||||
origin: "top",
|
||||
offset: aOffset
|
||||
}
|
||||
});
|
||||
}, ...aExpectedEvents);
|
||||
}
|
||||
|
||||
typeKey(aKey, ...aExpectedEvents) {
|
||||
return this.expectAndroidEvents(() => {
|
||||
synthesizeKey(aKey, {}, currentTabWindow());
|
||||
}, ...aExpectedEvents);
|
||||
}
|
||||
|
||||
eventTextMatches(aEvent, aExpected) {
|
||||
isDeeply(aEvent.text, aExpected,
|
||||
"Event text matches. " +
|
||||
`Got ${JSON.stringify(aEvent.text)}, expected ${JSON.stringify(aExpected)}.`);
|
||||
}
|
||||
|
||||
androidScrollForward() {
|
||||
this.sendMessage({
|
||||
name: "AccessFu:AndroidScroll",
|
||||
json: { origin: "top", direction: "forward" }
|
||||
};
|
||||
},
|
||||
data: { origin: "top", direction: "forward" }
|
||||
});
|
||||
}
|
||||
|
||||
androidScrollBackward: function adjustDown() {
|
||||
return {
|
||||
androidScrollBackward() {
|
||||
this.sendMessage({
|
||||
name: "AccessFu:AndroidScroll",
|
||||
json: { origin: "top", direction: "backward" }
|
||||
};
|
||||
},
|
||||
|
||||
focusSelector: function focusSelector(aSelector, aBlur) {
|
||||
return {
|
||||
name: "AccessFuTest:Focus",
|
||||
json: {
|
||||
selector: aSelector,
|
||||
blur: aBlur
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
activateCurrent: function activateCurrent(aOffset) {
|
||||
return {
|
||||
name: "AccessFu:Activate",
|
||||
json: {
|
||||
origin: "top",
|
||||
offset: aOffset
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
moveNextBy: function moveNextBy(aGranularity) {
|
||||
return {
|
||||
name: "AccessFu:MoveByGranularity",
|
||||
json: {
|
||||
direction: "Next",
|
||||
granularity: this._granularityMap[aGranularity]
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
movePreviousBy: function movePreviousBy(aGranularity) {
|
||||
return {
|
||||
name: "AccessFu:MoveByGranularity",
|
||||
json: {
|
||||
direction: "Previous",
|
||||
granularity: this._granularityMap[aGranularity]
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
moveCaretNextBy: function moveCaretNextBy(aGranularity) {
|
||||
return {
|
||||
name: "AccessFu:MoveCaret",
|
||||
json: {
|
||||
direction: "Next",
|
||||
granularity: this._granularityMap[aGranularity]
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
moveCaretPreviousBy: function moveCaretPreviousBy(aGranularity) {
|
||||
return {
|
||||
name: "AccessFu:MoveCaret",
|
||||
json: {
|
||||
direction: "Previous",
|
||||
granularity: this._granularityMap[aGranularity]
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
_granularityMap: {
|
||||
"character": 1, // MOVEMENT_GRANULARITY_CHARACTER
|
||||
"word": 2, // MOVEMENT_GRANULARITY_WORD
|
||||
"paragraph": 8 // MOVEMENT_GRANULARITY_PARAGRAPH
|
||||
}
|
||||
};
|
||||
|
||||
function ExpectedMessage(aName, aOptions) {
|
||||
this.name = aName;
|
||||
this.options = aOptions || {};
|
||||
this.json = {};
|
||||
}
|
||||
|
||||
ExpectedMessage.prototype.lazyCompare = function(aReceived, aExpected, aInfo) {
|
||||
if (aExpected && !aReceived) {
|
||||
return [false, "Expected something but got nothing -- " + aInfo];
|
||||
data: { origin: "top", direction: "backward" }
|
||||
});
|
||||
}
|
||||
|
||||
if (typeof aReceived === "string" || typeof aExpected === "string") {
|
||||
return [aReceived == aExpected, `String comparison: Got '${aReceived}.', expected: ${aExpected} -- ${aInfo}`];
|
||||
moveByGranularity(aDirection, aGranularity, ...aExpectedEvents) {
|
||||
return this.expectAndroidEvents(() => {
|
||||
this.sendMessage({
|
||||
name: "AccessFu:MoveByGranularity",
|
||||
data: {
|
||||
direction: aDirection,
|
||||
granularity: aGranularity
|
||||
}
|
||||
});
|
||||
}, ...aExpectedEvents);
|
||||
}
|
||||
|
||||
var matches = true;
|
||||
var delta = [];
|
||||
for (var attr in aExpected) {
|
||||
var expected = aExpected[attr];
|
||||
var received = aReceived[attr];
|
||||
if (typeof expected === "object") {
|
||||
var [childMatches, childDelta] = this.lazyCompare(received, expected);
|
||||
if (!childMatches) {
|
||||
delta.push(attr + " [ " + childDelta + " ]");
|
||||
matches = false;
|
||||
}
|
||||
} else if (received !== expected) {
|
||||
delta.push(
|
||||
attr + " [ expected " + JSON.stringify(expected) +
|
||||
" got " + JSON.stringify(received) + " ]");
|
||||
matches = false;
|
||||
}
|
||||
moveNextByGranularity(aGranularity, ...aExpectedEvents) {
|
||||
return this.moveByGranularity("Next", aGranularity, ...aExpectedEvents);
|
||||
}
|
||||
|
||||
var msg = delta.length ? delta.join(" ") : "Structures lazily match";
|
||||
return [matches, msg + " -- " + aInfo];
|
||||
};
|
||||
|
||||
ExpectedMessage.prototype.is = function(aReceived, aInfo) {
|
||||
var checkFunc = this.options.todo ? "todo" : "ok";
|
||||
SimpleTest[checkFunc].apply(
|
||||
SimpleTest, this.lazyCompare(aReceived, this.json, aInfo));
|
||||
};
|
||||
|
||||
ExpectedMessage.prototype.is_correct_focus = function(aInfo) {
|
||||
if (!this.options.focused) {
|
||||
return;
|
||||
movePreviousByGranularity(aGranularity, ...aExpectedEvents) {
|
||||
return this.moveByGranularity("Previous", aGranularity, ...aExpectedEvents);
|
||||
}
|
||||
|
||||
var checkFunc = this.options.focused_todo ? "todo_is" : "is";
|
||||
var doc = currentTabDocument();
|
||||
SimpleTest[checkFunc].apply(SimpleTest,
|
||||
[ doc.activeElement, doc.querySelector(this.options.focused),
|
||||
"Correct element is focused: " + this.options.focused + " -- " + aInfo ]);
|
||||
};
|
||||
|
||||
ExpectedMessage.prototype.ignore = function(aMessage) {
|
||||
return aMessage.name !== this.name;
|
||||
};
|
||||
|
||||
function ExpectedPresent(aAndroidEvents, aOptions) {
|
||||
ExpectedMessage.call(this, "AccessFu:Present", aOptions);
|
||||
this.expectedEvents = aAndroidEvents;
|
||||
}
|
||||
|
||||
ExpectedPresent.prototype = Object.create(ExpectedMessage.prototype);
|
||||
|
||||
ExpectedPresent.prototype.is = function(aReceived, aInfo) {
|
||||
if (typeof this.expectedEvents == "string") {
|
||||
// This is an event we have yet to implement, do a simple string comparison.
|
||||
if (this.expectedEvents == aReceived) {
|
||||
SimpleTest.todo(false, `${aInfo} (${aReceived})`);
|
||||
return;
|
||||
}
|
||||
// XXX: moveCaret* methods will go away soon as we fold it into the
|
||||
// granularity messages above.
|
||||
moveCaret(aDirection, aGranularity, ...aExpectedEvents) {
|
||||
return this.expectAndroidEvents(() => {
|
||||
this.sendMessage({
|
||||
name: "AccessFu:MoveCaret",
|
||||
data: {
|
||||
direction: aDirection,
|
||||
granularity: aGranularity
|
||||
}
|
||||
});
|
||||
}, ...aExpectedEvents);
|
||||
}
|
||||
|
||||
SimpleTest[this.options.todo ? "todo" : "ok"].apply(SimpleTest,
|
||||
this.lazyCompare(aReceived, this.expectedEvents, aInfo + " aReceived: " +
|
||||
JSON.stringify(aReceived) + " evt: " + JSON.stringify(this.expectedEvents)));
|
||||
};
|
||||
|
||||
ExpectedPresent.prototype.ignore = function(aMessage) {
|
||||
if (!aMessage.json || ExpectedMessage.prototype.ignore.call(this, aMessage)) {
|
||||
return true;
|
||||
moveCaretNext(aGranularity, ...aExpectedEvents) {
|
||||
return this.moveCaret("Next", aGranularity, ...aExpectedEvents);
|
||||
}
|
||||
|
||||
let firstEvent = (aMessage.json || [])[0];
|
||||
|
||||
return firstEvent && firstEvent.eventType === AndroidEvents.VIEW_SCROLLED;
|
||||
};
|
||||
|
||||
function ExpectedCursorChange(aSpeech, aOptions) {
|
||||
ExpectedPresent.call(this, [{
|
||||
eventType: 0x8000, // VIEW_ACCESSIBILITY_FOCUSED
|
||||
}], aOptions);
|
||||
moveCaretPrevious(aGranularity, ...aExpectedEvents) {
|
||||
return this.moveCaret("Previous", aGranularity, ...aExpectedEvents);
|
||||
}
|
||||
}
|
||||
|
||||
ExpectedCursorChange.prototype = Object.create(ExpectedPresent.prototype);
|
||||
|
||||
function ExpectedCursorTextChange(aSpeech, aStartOffset, aEndOffset, aOptions) {
|
||||
ExpectedPresent.call(this, [{
|
||||
eventType: AndroidEvents.VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
|
||||
fromIndex: aStartOffset,
|
||||
toIndex: aEndOffset
|
||||
}], aOptions);
|
||||
|
||||
// bug 980509
|
||||
this.options.b2g_todo = true;
|
||||
}
|
||||
|
||||
ExpectedCursorTextChange.prototype =
|
||||
Object.create(ExpectedCursorChange.prototype);
|
||||
|
||||
function ExpectedClickAction(aOptions) {
|
||||
ExpectedPresent.call(this, [{
|
||||
eventType: AndroidEvents.VIEW_CLICKED
|
||||
}], aOptions);
|
||||
}
|
||||
|
||||
ExpectedClickAction.prototype = Object.create(ExpectedPresent.prototype);
|
||||
|
||||
function ExpectedCheckAction(aChecked, aOptions) {
|
||||
ExpectedPresent.call(this, [{
|
||||
eventType: AndroidEvents.VIEW_CLICKED,
|
||||
checked: aChecked
|
||||
}], aOptions);
|
||||
}
|
||||
|
||||
ExpectedCheckAction.prototype = Object.create(ExpectedPresent.prototype);
|
||||
|
||||
function ExpectedSwitchAction(aSwitched, aOptions) {
|
||||
ExpectedPresent.call(this, [{
|
||||
eventType: AndroidEvents.VIEW_CLICKED,
|
||||
checked: aSwitched
|
||||
}], aOptions);
|
||||
}
|
||||
|
||||
ExpectedSwitchAction.prototype = Object.create(ExpectedPresent.prototype);
|
||||
|
||||
// XXX: Implement Android event?
|
||||
function ExpectedNameChange(aName, aOptions) {
|
||||
ExpectedPresent.call(this, "todo.name-changed", aOptions);
|
||||
}
|
||||
|
||||
ExpectedNameChange.prototype = Object.create(ExpectedPresent.prototype);
|
||||
|
||||
// XXX: Implement Android event?
|
||||
function ExpectedValueChange(aValue, aOptions) {
|
||||
ExpectedPresent.call(this, "todo.value-changed", aOptions);
|
||||
}
|
||||
|
||||
ExpectedValueChange.prototype = Object.create(ExpectedPresent.prototype);
|
||||
|
||||
// XXX: Implement Android event?
|
||||
function ExpectedTextChanged(aValue, aOptions) {
|
||||
ExpectedPresent.call(this, [{
|
||||
eventType: AndroidEvents.VIEW_TEXT_CHANGED
|
||||
}], aOptions);
|
||||
}
|
||||
|
||||
ExpectedTextChanged.prototype = Object.create(ExpectedPresent.prototype);
|
||||
|
||||
function ExpectedEditState(aEditState, aOptions) {
|
||||
ExpectedMessage.call(this, "AccessFu:Input", aOptions);
|
||||
this.json = aEditState;
|
||||
}
|
||||
|
||||
ExpectedEditState.prototype = Object.create(ExpectedMessage.prototype);
|
||||
|
||||
function ExpectedTextSelectionChanged(aStart, aEnd, aOptions) {
|
||||
ExpectedPresent.call(this, [{
|
||||
eventType: AndroidEvents.VIEW_TEXT_SELECTION_CHANGED,
|
||||
}], aOptions);
|
||||
}
|
||||
|
||||
ExpectedTextSelectionChanged.prototype =
|
||||
Object.create(ExpectedPresent.prototype);
|
||||
|
||||
function ExpectedTextCaretChanged(aFrom, aTo, aOptions) {
|
||||
ExpectedPresent.call(this, [{
|
||||
eventType: AndroidEvents.VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
|
||||
fromIndex: aFrom,
|
||||
toIndex: aTo
|
||||
}], aOptions);
|
||||
}
|
||||
|
||||
ExpectedTextCaretChanged.prototype = Object.create(ExpectedPresent.prototype);
|
||||
|
||||
function ExpectedAnnouncement(aAnnouncement, aOptions) {
|
||||
ExpectedPresent.call(this, [{
|
||||
eventType: AndroidEvents.ANNOUNCEMENT,
|
||||
text: [ aAnnouncement],
|
||||
addedCount: aAnnouncement.length
|
||||
}], aOptions);
|
||||
}
|
||||
|
||||
ExpectedAnnouncement.prototype = Object.create(ExpectedPresent.prototype);
|
||||
|
||||
// XXX: Implement Android event?
|
||||
function ExpectedNoMove(aOptions) {
|
||||
ExpectedPresent.call(this, null, aOptions);
|
||||
}
|
||||
|
||||
ExpectedNoMove.prototype = Object.create(ExpectedPresent.prototype);
|
||||
|
|
|
@ -21,289 +21,412 @@
|
|||
<script type="application/javascript" src="jsatcommon.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
async function testSimpleNavigation(doc, runner) {
|
||||
let evt;
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Traversal Rule test document", "Phone status bar"]);
|
||||
runner.isFocused("body");
|
||||
|
||||
evt = await runner.movePrevious("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
is(evt.exitView, "movePrevious");
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Back", "button"]);
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["such app", "wow", "heading level 1"]);
|
||||
runner.isFocused("iframe");
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["many option", "not checked", "check button", "First item", "list", "1 item"]);
|
||||
|
||||
evt = await runner.activateCurrent(0,
|
||||
AndroidEvents.VIEW_CLICKED,
|
||||
AndroidEvents.VIEW_CLICKED);
|
||||
is(evt[1].checked, true, "checkbox is checked");
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["much range", "label"]);
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["much range", "5", "slider"]);
|
||||
|
||||
expectedMsg = runner.androidEvent("todo.value-changed");
|
||||
runner.androidScrollBackward();
|
||||
evt = await expectedMsg;
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Home", "button"]);
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["apple", "button"]);
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Light", "off", "switch"]);
|
||||
|
||||
evt = await runner.activateCurrent(0,
|
||||
AndroidEvents.VIEW_CLICKED,
|
||||
AndroidEvents.VIEW_CLICKED);
|
||||
is(evt[1].checked, true, "checkbox is checked");
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["slider", "0", "slider", "live"]);
|
||||
|
||||
evt = await runner.movePrevious("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Light", "on", "switch"]);
|
||||
|
||||
evt = await runner.activateCurrent(0,
|
||||
AndroidEvents.VIEW_CLICKED,
|
||||
AndroidEvents.VIEW_CLICKED);
|
||||
is(evt[1].checked, false, "checkbox is checked");
|
||||
|
||||
evt = await runner.movePrevious("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["apple", "button"]);
|
||||
|
||||
evt = await runner.movePrevious("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Home", "button"]);
|
||||
|
||||
evt = await runner.movePrevious("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["such app", "much range", "4", "slider"]);
|
||||
|
||||
expectedMsg = runner.androidEvent("todo.value-changed");
|
||||
runner.androidScrollForward();
|
||||
evt = await expectedMsg;
|
||||
|
||||
expectedMsg = runner.androidEvent("todo.value-changed");
|
||||
runner.androidScrollBackward();
|
||||
evt = await expectedMsg;
|
||||
|
||||
evt = await runner.movePrevious("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["much range", "label"]);
|
||||
|
||||
evt = await runner.movePrevious("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["many option", "checked", "check button", "First item", "list", "1 item"]);
|
||||
|
||||
evt = await runner.activateCurrent(0,
|
||||
AndroidEvents.VIEW_CLICKED,
|
||||
AndroidEvents.VIEW_CLICKED);
|
||||
is(evt[1].checked, false, "checkbox is checked");
|
||||
|
||||
evt = await runner.movePrevious("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["wow", "heading level 1"]);
|
||||
|
||||
evt = await runner.movePrevious("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Back", "button"]);
|
||||
|
||||
evt = await runner.movePrevious("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Phone status bar"]);
|
||||
|
||||
// Reached top
|
||||
evt = await runner.movePrevious("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
is(evt.exitView, "movePrevious");
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Back", "button"]);
|
||||
|
||||
// Moving to the absolute last item from an embedded document
|
||||
// fails. Bug 972035.
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["such app", "wow", "heading level 1"]);
|
||||
|
||||
// Move from an inner frame to the last element in the parent doc
|
||||
|
||||
evt = await runner.moveLast("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["much range", "4", "slider"]);
|
||||
|
||||
await runner.clearCursor();
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Traversal Rule test document", "Phone status bar"]);
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Back", "button"]);
|
||||
|
||||
evt = await runner.moveNext("FormElement",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["such app", "many option", "not checked", "check button", "First item", "list", "1 item"]);
|
||||
|
||||
evt = await runner.moveNext("FormElement",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["much range", "4", "slider"]);
|
||||
|
||||
evt = await runner.movePrevious("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["much range", "label"]);
|
||||
|
||||
evt = await runner.movePrevious("FormElement",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["many option", "not checked", "check button", "First item", "list", "1 item"]);
|
||||
|
||||
evt = await runner.movePrevious("FormElement",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Back", "button"]);
|
||||
|
||||
await runner.clearCursor();
|
||||
|
||||
|
||||
// Moving to the absolute first item from an embedded document
|
||||
// fails. Bug 972035.
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Traversal Rule test document", "Phone status bar"]);
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Back", "button"]);
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["such app", "wow", "heading level 1"]);
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["many option", "not checked", "check button", "First item", "list", "1 item"]);
|
||||
|
||||
evt = await runner.moveFirst("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
todo_is(evt.text[0], "Phone status bar");
|
||||
|
||||
await runner.clearCursor();
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Traversal Rule test document", "Phone status bar"]);
|
||||
|
||||
evt = await runner.focusSelector("button#fruit",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["apple", "button"]);
|
||||
|
||||
// Current virtual cursor's position's name changes
|
||||
expectedMsg = runner.androidEvent("todo.name-changed");
|
||||
doc.getElementById("fruit").setAttribute("aria-label", "banana");
|
||||
evt = await expectedMsg;
|
||||
|
||||
// Name and value changes inside a live-region (no cursor present)
|
||||
expectedMsg = runner.androidEvent("todo.name-changed");
|
||||
doc.getElementById("slider").setAttribute("aria-label", "mover");
|
||||
evt = await expectedMsg;
|
||||
|
||||
expectedMsg = runner.androidEvent("todo.value-changed");
|
||||
doc.getElementById("slider").setAttribute("aria-valuenow", "5");
|
||||
doc.getElementById("slider").setAttribute("aria-valuetext", "medium");
|
||||
evt = await expectedMsg;
|
||||
|
||||
// Blur button and reset cursor
|
||||
runner.blur();
|
||||
await runner.clearCursor();
|
||||
|
||||
// Move cursor with focus in outside document
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Traversal Rule test document", "Phone status bar"]);
|
||||
|
||||
evt = await runner.focusSelector("button#home",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Home", "button"]);
|
||||
|
||||
// Blur button and reset cursor
|
||||
runner.blur();
|
||||
await runner.clearCursor();
|
||||
|
||||
// Set focus on element outside of embedded frame while cursor is in frame
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Traversal Rule test document", "Phone status bar"]);
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Back", "button"]);
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["such app", "wow", "heading level 1"]);
|
||||
|
||||
evt = await runner.focusSelector("button#home",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Home", "button"]);
|
||||
|
||||
// Blur button and reset cursor
|
||||
runner.blur();
|
||||
await runner.clearCursor();
|
||||
|
||||
// XXX: Set focus on iframe itself.
|
||||
// XXX: Set focus on element in iframe when cursor is outside of it.
|
||||
// XXX: Set focus on element in iframe when cursor is in iframe.
|
||||
|
||||
// aria-hidden element that the virtual cursor is positioned on
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Traversal Rule test document", "Phone status bar"]);
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Back", "button"]);
|
||||
|
||||
evt = await runner.expectAndroidEvents(() => {
|
||||
doc.getElementById("back").setAttribute("aria-hidden", true);
|
||||
}, AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["such app", "wow", "heading level 1"]);
|
||||
|
||||
// Changing aria-hidden attribute twice and making sure that the event
|
||||
// is fired only once when the actual change happens.
|
||||
doc.getElementById("back").setAttribute("aria-hidden", true);
|
||||
doc.getElementById("back").setAttribute("aria-hidden", false);
|
||||
evt = await runner.movePrevious("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Back", "button"]);
|
||||
await runner.clearCursor();
|
||||
|
||||
// aria-hidden on the iframe that has the vc.
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Traversal Rule test document", "Phone status bar"]);
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Back", "button"]);
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["such app", "wow", "heading level 1"]);
|
||||
|
||||
|
||||
evt = await runner.expectAndroidEvents(() => {
|
||||
doc.getElementById("iframe").setAttribute("aria-hidden", true);
|
||||
}, AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Home", "button"]);
|
||||
|
||||
doc.getElementById("iframe").setAttribute("aria-hidden", false);
|
||||
await runner.clearCursor();
|
||||
|
||||
// aria-hidden element and auto Move
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Traversal Rule test document", "Phone status bar"]);
|
||||
|
||||
doc.getElementById("back").setAttribute("aria-hidden", true);
|
||||
evt = await runner.focusSelector("button#back",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["such app", "wow", "heading level 1"]);
|
||||
|
||||
doc.getElementById("back").setAttribute("aria-hidden", false);
|
||||
runner.blur();
|
||||
await runner.clearCursor();
|
||||
|
||||
// Open dialog in outer doc, while cursor is also in outer doc
|
||||
evt = await runner.moveLast("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Traversal Rule test document", "mover", "medium", "slider", "live"]);
|
||||
|
||||
evt = await runner.expectAndroidEvents(() => {
|
||||
doc.getElementById("alert").hidden = false;
|
||||
}, AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["This is an alert!", "heading level 1", "dialog"]);
|
||||
|
||||
evt = await runner.expectAndroidEvents(() => {
|
||||
doc.getElementById("alert").hidden = true;
|
||||
}, AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Traversal Rule test document", "mover", "medium", "slider", "live"]);
|
||||
|
||||
await runner.clearCursor();
|
||||
|
||||
// Open dialog in outer doc, while cursor is in inner frame
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Traversal Rule test document", "Phone status bar"]);
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Back", "button"]);
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["such app", "wow", "heading level 1"]);
|
||||
evt = await runner.expectAndroidEvents(() => {
|
||||
doc.getElementById("alert").hidden = false;
|
||||
}, AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["This is an alert!", "heading level 1", "dialog"]);
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Do you agree?"]);
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Yes", "button"]);
|
||||
|
||||
evt = await runner.activateCurrent(0,
|
||||
AndroidEvents.VIEW_CLICKED,
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt[1], ["such app", "wow", "heading level 1"]);
|
||||
|
||||
await runner.clearCursor();
|
||||
|
||||
// Open dialog, then focus on something when closing
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Traversal Rule test document", "Phone status bar"]);
|
||||
evt = await runner.expectAndroidEvents(() => {
|
||||
doc.getElementById("alert").hidden = false;
|
||||
}, AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["This is an alert!", "heading level 1", "dialog"]);
|
||||
|
||||
evt = await runner.expectAndroidEvents(() => {
|
||||
doc.getElementById("alert").hidden = true;
|
||||
doc.querySelector("button#home").focus();
|
||||
}, AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Traversal Rule test document", "Home", "button"]);
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["banana", "button"]);
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Light", "off", "switch"]);
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["mover", "medium", "slider", "live"]);
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
is(evt.exitView, "moveNext", "Reached end of content");
|
||||
}
|
||||
|
||||
function doTest() {
|
||||
var doc = currentTabDocument();
|
||||
var iframe = doc.createElement("iframe");
|
||||
iframe.id = "iframe";
|
||||
iframe.mozbrowser = true;
|
||||
iframe.addEventListener("mozbrowserloadend", function() {
|
||||
var contentTest = new AccessFuContentTest(
|
||||
[
|
||||
// Simple traversal forward
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(
|
||||
["Traversal Rule test document", "Phone status bar"],
|
||||
{ focused: "body" })],
|
||||
[ContentMessages.simpleMovePrevious, new ExpectedNoMove()],
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["Back", {"string": "pushbutton"}])],
|
||||
[ContentMessages.simpleMoveNext, new ExpectedCursorChange(
|
||||
["such app", "wow", {"string": "headingLevel", "args": [1]}],
|
||||
{ focused: "iframe" })],
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["many option", {"string": "stateNotChecked"},
|
||||
{"string": "checkbutton"}, {"string": "listStart"},
|
||||
{"string": "list"}, {"string": "listItemsCount", "count": 1}])],
|
||||
addA11yLoadEvent(async function() {
|
||||
let runner = new AccessFuContentTestRunner();
|
||||
await runner.start();
|
||||
|
||||
// check checkbox
|
||||
[ContentMessages.activateCurrent(),
|
||||
new ExpectedClickAction(),
|
||||
new ExpectedCheckAction(true)],
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["much range", {"string": "label"}])],
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["much range", "5", {"string": "slider"}])],
|
||||
[ContentMessages.moveOrAdjustUp(), new ExpectedValueChange("6")],
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["Home", {"string": "pushbutton"}])],
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["apple", {"string": "pushbutton"}])],
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["Light", {"string": "stateOff"}, {"string": "switch"}])],
|
||||
// switch on
|
||||
[ContentMessages.activateCurrent(),
|
||||
new ExpectedClickAction(),
|
||||
new ExpectedSwitchAction(true)],
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["slider", "0", {"string": "slider"}])],
|
||||
await testSimpleNavigation(doc, runner);
|
||||
|
||||
// Simple traversal backward
|
||||
[ContentMessages.simpleMovePrevious,
|
||||
new ExpectedCursorChange(["Light", {"string": "stateOn"}, {"string": "switch"}])],
|
||||
// switch off
|
||||
[ContentMessages.activateCurrent(),
|
||||
new ExpectedClickAction(),
|
||||
new ExpectedSwitchAction(false)],
|
||||
[ContentMessages.simpleMovePrevious,
|
||||
new ExpectedCursorChange(["apple", {"string": "pushbutton"}])],
|
||||
[ContentMessages.simpleMovePrevious,
|
||||
new ExpectedCursorChange(["Home", {"string": "pushbutton"}])],
|
||||
[ContentMessages.simpleMovePrevious,
|
||||
new ExpectedCursorChange(["such app", "much range", "6", {"string": "slider"}])],
|
||||
[ContentMessages.moveOrAdjustDown(), new ExpectedValueChange("5")],
|
||||
[ContentMessages.androidScrollForward(), new ExpectedValueChange("6")],
|
||||
[ContentMessages.androidScrollBackward(), new ExpectedValueChange("5")],
|
||||
[ContentMessages.simpleMovePrevious,
|
||||
new ExpectedCursorChange(["much range", {"string": "label"}])],
|
||||
[ContentMessages.simpleMovePrevious,
|
||||
new ExpectedCursorChange(["many option", {"string": "stateChecked"},
|
||||
{"string": "checkbutton"}, {"string": "listStart"},
|
||||
{"string": "list"}, {"string": "listItemsCount", "count": 1}])],
|
||||
// uncheck checkbox
|
||||
[ContentMessages.activateCurrent(),
|
||||
new ExpectedClickAction(),
|
||||
new ExpectedCheckAction(false)],
|
||||
[ContentMessages.simpleMovePrevious,
|
||||
new ExpectedCursorChange(["wow", {"string": "headingLevel", "args": [1]}])],
|
||||
[ContentMessages.simpleMovePrevious,
|
||||
new ExpectedCursorChange(["Back", {"string": "pushbutton"}])],
|
||||
[ContentMessages.simpleMovePrevious,
|
||||
new ExpectedCursorChange(["Phone status bar"])],
|
||||
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["Back", {"string": "pushbutton"}])],
|
||||
// Moving to the absolute last item from an embedded document
|
||||
// fails. Bug 972035.
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(
|
||||
["such app", "wow", {"string": "headingLevel", "args": [1]}])],
|
||||
// Move from an inner frame to the last element in the parent doc
|
||||
[ContentMessages.simpleMoveLast,
|
||||
new ExpectedCursorChange(
|
||||
["slider", "0", {"string": "slider"}])],
|
||||
|
||||
[ContentMessages.clearCursor, "AccessFu:CursorCleared"],
|
||||
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["Traversal Rule test document", "Phone status bar"])],
|
||||
[ContentMessages.moveOrAdjustDown("FormElement"),
|
||||
new ExpectedCursorChange(["Back", {"string": "pushbutton"}])],
|
||||
[ContentMessages.moveOrAdjustDown("FormElement"),
|
||||
new ExpectedCursorChange(["such app", "many option", {"string": "stateNotChecked"},
|
||||
{"string": "checkbutton"}, {"string": "listStart"},
|
||||
{"string": "list"}, {"string": "listItemsCount", "count": 1}])],
|
||||
[ContentMessages.moveOrAdjustDown("FormElement"),
|
||||
new ExpectedCursorChange(["much range", "5", {"string": "slider"}])],
|
||||
// Calling AdjustOrMove should adjust the range.
|
||||
[ContentMessages.moveOrAdjustDown("FormElement"),
|
||||
new ExpectedValueChange("4")],
|
||||
[ContentMessages.moveOrAdjustUp("FormElement"),
|
||||
new ExpectedValueChange("5")],
|
||||
[ContentMessages.simpleMovePrevious,
|
||||
new ExpectedCursorChange(["much range", {"string": "label"}])],
|
||||
[ContentMessages.moveOrAdjustUp("FormElement"),
|
||||
new ExpectedCursorChange(["many option", {"string": "stateNotChecked"},
|
||||
{"string": "checkbutton"}, {"string": "listStart"},
|
||||
{"string": "list"}, {"string": "listItemsCount", "count": 1}])],
|
||||
[ContentMessages.moveOrAdjustUp("FormElement"),
|
||||
new ExpectedCursorChange(["Back", {"string": "pushbutton"}])],
|
||||
|
||||
[ContentMessages.clearCursor, "AccessFu:CursorCleared"],
|
||||
|
||||
// Moving to the absolute first item from an embedded document
|
||||
// fails. Bug 972035.
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["Traversal Rule test document", "Phone status bar"])],
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["Back", {"string": "pushbutton"}])],
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["such app", "wow", {"string": "headingLevel", "args": [1]}])],
|
||||
[ContentMessages.simpleMoveNext, new ExpectedCursorChange(
|
||||
["many option", {"string": "stateNotChecked"},
|
||||
{"string": "checkbutton"}, {"string": "listStart"},
|
||||
{"string": "list"}, {"string": "listItemsCount", "count": 1}])],
|
||||
[ContentMessages.simpleMoveFirst,
|
||||
new ExpectedCursorChange(["Phone status bar"])],
|
||||
|
||||
// Reset cursors
|
||||
[ContentMessages.clearCursor, "AccessFu:CursorCleared"],
|
||||
|
||||
// Current virtual cursor's position's name changes
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["Traversal Rule test document", "Phone status bar"])],
|
||||
[ContentMessages.focusSelector("button#fruit", false),
|
||||
new ExpectedCursorChange(["apple", {"string": "pushbutton"}])],
|
||||
[doc.defaultView.renameFruit, new ExpectedNameChange("banana")],
|
||||
|
||||
// Name and value changes inside a live-region (no cursor present)
|
||||
[doc.defaultView.renameSlider,
|
||||
new ExpectedNameChange("mover")],
|
||||
[doc.defaultView.changeSliderValue,
|
||||
new ExpectedValueChange("medium")],
|
||||
|
||||
// Blur button and reset cursor
|
||||
[ContentMessages.focusSelector("button#fruit", true), null],
|
||||
[ContentMessages.clearCursor, "AccessFu:CursorCleared"],
|
||||
|
||||
// Move cursor with focus in outside document
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["Traversal Rule test document", "Phone status bar"])],
|
||||
[ContentMessages.focusSelector("button#home", false),
|
||||
new ExpectedCursorChange(["Home", {"string": "pushbutton"}])],
|
||||
|
||||
// Blur button and reset cursor
|
||||
[ContentMessages.focusSelector("button#home", true), null],
|
||||
[ContentMessages.clearCursor, "AccessFu:CursorCleared"],
|
||||
|
||||
// Set focus on element outside of embedded frame while
|
||||
// cursor is in frame
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["Traversal Rule test document", "Phone status bar"])],
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["Back", {"string": "pushbutton"}])],
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["such app", "wow", {"string": "headingLevel", "args": [1]}])],
|
||||
[ContentMessages.focusSelector("button#home", false),
|
||||
new ExpectedCursorChange(["Home", {"string": "pushbutton"}])],
|
||||
|
||||
// Blur button and reset cursor
|
||||
[ContentMessages.focusSelector("button#home", true), null],
|
||||
[ContentMessages.clearCursor, "AccessFu:CursorCleared"],
|
||||
|
||||
// XXX: Set focus on iframe itself.
|
||||
// XXX: Set focus on element in iframe when cursor is outside of it.
|
||||
// XXX: Set focus on element in iframe when cursor is in iframe.
|
||||
|
||||
// aria-hidden element that the virtual cursor is positioned on
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["Traversal Rule test document", "Phone status bar"])],
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["Back", {"string": "pushbutton"}])],
|
||||
[doc.defaultView.ariaHideBack,
|
||||
new ExpectedCursorChange(
|
||||
["such app", "wow", {"string": "headingLevel", "args": [1]}])],
|
||||
// Changing aria-hidden attribute twice and making sure that the event
|
||||
// is fired only once when the actual change happens.
|
||||
[doc.defaultView.ariaHideBack],
|
||||
[doc.defaultView.ariaShowBack],
|
||||
[ContentMessages.simpleMovePrevious,
|
||||
new ExpectedCursorChange(["Back", {"string": "pushbutton"}])],
|
||||
[ContentMessages.clearCursor, "AccessFu:CursorCleared"],
|
||||
|
||||
// aria-hidden on the iframe that has the vc.
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["Traversal Rule test document", "Phone status bar"])],
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["Back", {"string": "pushbutton"}])],
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["such app", "wow", {"string": "headingLevel", "args": [1]}])],
|
||||
[doc.defaultView.ariaHideIframe,
|
||||
new ExpectedCursorChange(["Home", {"string": "pushbutton"}])],
|
||||
[doc.defaultView.ariaShowIframe],
|
||||
[ContentMessages.clearCursor, "AccessFu:CursorCleared"],
|
||||
|
||||
// aria-hidden element and auto Move
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["Traversal Rule test document", "Phone status bar"])],
|
||||
[doc.defaultView.ariaHideBack],
|
||||
[ContentMessages.focusSelector("button#back", false),
|
||||
// Must not speak Back button as it is aria-hidden
|
||||
new ExpectedCursorChange(
|
||||
["such app", "wow", {"string": "headingLevel", "args": [1]}])],
|
||||
[doc.defaultView.ariaShowBack],
|
||||
[ContentMessages.focusSelector("button#back", true), null],
|
||||
[ContentMessages.clearCursor, "AccessFu:CursorCleared"],
|
||||
|
||||
// Open dialog in outer doc, while cursor is also in outer doc
|
||||
[ContentMessages.simpleMoveLast,
|
||||
new ExpectedCursorChange(["Traversal Rule test document", "mover",
|
||||
"medium", {"string": "slider"}])],
|
||||
[doc.defaultView.showAlert,
|
||||
new ExpectedCursorChange(["This is an alert!",
|
||||
{"string": "headingLevel", "args": [1]},
|
||||
{"string": "dialog"}])],
|
||||
|
||||
[doc.defaultView.hideAlert,
|
||||
new ExpectedCursorChange(["Traversal Rule test document", "mover",
|
||||
"medium", {"string": "slider"}])],
|
||||
|
||||
[ContentMessages.clearCursor, "AccessFu:CursorCleared"],
|
||||
|
||||
// Open dialog in outer doc, while cursor is in inner frame
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["Traversal Rule test document", "Phone status bar"])],
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["Back", {"string": "pushbutton"}])],
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(
|
||||
["such app", "wow", {"string": "headingLevel", "args": [1]}])],
|
||||
[doc.defaultView.showAlert, new ExpectedCursorChange(["This is an alert!",
|
||||
{"string": "headingLevel", "args": [1]},
|
||||
{"string": "dialog"}])],
|
||||
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["Do you agree?"])],
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["Yes", {"string": "pushbutton"}])],
|
||||
[ContentMessages.activateCurrent(),
|
||||
new ExpectedClickAction(),
|
||||
new ExpectedCursorChange(
|
||||
["such app", "wow", {"string": "headingLevel", "args": [1]}])],
|
||||
|
||||
[ContentMessages.clearCursor, "AccessFu:CursorCleared"],
|
||||
|
||||
// Open dialog, then focus on something when closing
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["Traversal Rule test document", "Phone status bar"])],
|
||||
[doc.defaultView.showAlert,
|
||||
new ExpectedCursorChange(["This is an alert!",
|
||||
{"string": "headingLevel", "args": [1]}, {"string": "dialog"}])],
|
||||
|
||||
[function hideAlertAndFocusHomeButton() {
|
||||
doc.defaultView.hideAlert();
|
||||
doc.querySelector("button#home").focus();
|
||||
}, new ExpectedCursorChange(["Traversal Rule test document",
|
||||
"Home", {"string": "pushbutton"}])],
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["banana", {"string": "pushbutton"}])]
|
||||
[ContentMessages.simpleMoveNext, new ExpectedNoMove()]
|
||||
]);
|
||||
|
||||
addA11yLoadEvent(function() {
|
||||
contentTest.start(function() {
|
||||
closeBrowserWindow();
|
||||
SimpleTest.finish();
|
||||
});
|
||||
runner.finish();
|
||||
closeBrowserWindow();
|
||||
SimpleTest.finish();
|
||||
}, doc.defaultView);
|
||||
});
|
||||
iframe.src = "data:text/html;charset=utf-8," + doc.defaultView.frameContents;
|
||||
|
@ -335,7 +458,7 @@
|
|||
|
||||
<a target="_blank"
|
||||
title="Add tests for OOP message handling and general integration"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=972047">Mozilla Bug 933808</a>
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1459677">Mozilla Bug 1459677</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
|
|
|
@ -1,311 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Tests AccessFu content integration</title>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
|
||||
</script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js">
|
||||
</script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/chrome-harness.js">
|
||||
</script>
|
||||
|
||||
<script type="application/javascript" src="../common.js"></script>
|
||||
<script type="application/javascript" src="../browser.js"></script>
|
||||
<script type="application/javascript" src="../events.js"></script>
|
||||
<script type="application/javascript" src="../role.js"></script>
|
||||
<script type="application/javascript" src="../states.js"></script>
|
||||
<script type="application/javascript" src="../layout.js"></script>
|
||||
<script type="application/javascript" src="jsatcommon.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function doTest() {
|
||||
var doc = currentTabDocument();
|
||||
var textTest = new AccessFuContentTest(
|
||||
[
|
||||
// Read-only text tests
|
||||
[ContentMessages.simpleMoveFirst,
|
||||
new ExpectedCursorChange(
|
||||
["Text content test document", "These are my awards, Mother. " +
|
||||
"From Army. The seal is for marksmanship, and the gorilla is " +
|
||||
"for sand racing."])],
|
||||
[ContentMessages.moveNextBy("word"),
|
||||
new ExpectedCursorTextChange("These", 0, 5)],
|
||||
[ContentMessages.moveNextBy("word"),
|
||||
new ExpectedCursorTextChange("are", 6, 9)],
|
||||
[ContentMessages.moveNextBy("word"),
|
||||
new ExpectedCursorTextChange("my", 10, 12)],
|
||||
[ContentMessages.moveNextBy("word"),
|
||||
new ExpectedCursorTextChange("awards,", 13, 20)],
|
||||
[ContentMessages.moveNextBy("word"),
|
||||
new ExpectedCursorTextChange("Mother.", 21, 28)],
|
||||
[ContentMessages.movePreviousBy("word"),
|
||||
new ExpectedCursorTextChange("awards,", 13, 20)],
|
||||
[ContentMessages.movePreviousBy("word"),
|
||||
new ExpectedCursorTextChange("my", 10, 12)],
|
||||
[ContentMessages.movePreviousBy("word"),
|
||||
new ExpectedCursorTextChange("are", 6, 9)],
|
||||
[ContentMessages.movePreviousBy("word"),
|
||||
new ExpectedCursorTextChange("These", 0, 5)],
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(["You're a good guy, mon frere. " +
|
||||
"That means brother in French. " +
|
||||
"I don't know how I know that. " +
|
||||
"I took four years of Spanish."])],
|
||||
// XXX: Word boundary should be past the apostraphe.
|
||||
[ContentMessages.moveNextBy("word"),
|
||||
new ExpectedCursorTextChange("You're", 0, 6,
|
||||
{ todo: true /* Bug 980512 */})],
|
||||
|
||||
// Editable text tests.
|
||||
[ContentMessages.focusSelector("textarea"),
|
||||
new ExpectedAnnouncement("editing"),
|
||||
new ExpectedEditState({
|
||||
editing: true,
|
||||
multiline: true,
|
||||
atStart: true,
|
||||
atEnd: false
|
||||
}),
|
||||
new ExpectedCursorChange(
|
||||
["Please refrain from Mayoneggs during this salmonella scare.",
|
||||
{string: "textarea"}]),
|
||||
new ExpectedTextSelectionChanged(0, 0)
|
||||
],
|
||||
[ContentMessages.activateCurrent(10),
|
||||
new ExpectedTextCaretChanged(0, 10),
|
||||
new ExpectedEditState({ editing: true,
|
||||
multiline: true,
|
||||
atStart: false,
|
||||
atEnd: false }),
|
||||
new ExpectedTextSelectionChanged(10, 10)],
|
||||
[ContentMessages.activateCurrent(20),
|
||||
new ExpectedTextCaretChanged(10, 20),
|
||||
new ExpectedTextSelectionChanged(20, 20)
|
||||
],
|
||||
[ContentMessages.moveCaretNextBy("word"),
|
||||
new ExpectedTextCaretChanged(20, 29),
|
||||
new ExpectedTextSelectionChanged(29, 29)
|
||||
],
|
||||
[ContentMessages.moveCaretNextBy("word"),
|
||||
new ExpectedTextCaretChanged(29, 36),
|
||||
new ExpectedTextSelectionChanged(36, 36)
|
||||
],
|
||||
[ContentMessages.moveCaretNextBy("character"),
|
||||
new ExpectedTextCaretChanged(36, 37),
|
||||
new ExpectedTextSelectionChanged(37, 37)
|
||||
],
|
||||
[ContentMessages.moveCaretNextBy("character"),
|
||||
new ExpectedTextCaretChanged(37, 38),
|
||||
new ExpectedTextSelectionChanged(38, 38)
|
||||
],
|
||||
[ContentMessages.moveCaretNextBy("paragraph"),
|
||||
new ExpectedTextCaretChanged(38, 59),
|
||||
new ExpectedTextSelectionChanged(59, 59)
|
||||
],
|
||||
[ContentMessages.moveCaretPreviousBy("word"),
|
||||
new ExpectedTextCaretChanged(53, 59),
|
||||
new ExpectedTextSelectionChanged(53, 53)
|
||||
],
|
||||
|
||||
// bug xxx
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(
|
||||
["So we don't get dessert?", {string: "label"}],
|
||||
{ focused: "html"}),
|
||||
new ExpectedAnnouncement("navigating"),
|
||||
new ExpectedEditState({
|
||||
editing: false,
|
||||
multiline: false,
|
||||
atStart: true,
|
||||
atEnd: false })],
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(
|
||||
[{ string: "entry" }],
|
||||
{ focused: "html"})],
|
||||
[ContentMessages.activateCurrent(0),
|
||||
new ExpectedClickAction(),
|
||||
new ExpectedAnnouncement("editing"),
|
||||
new ExpectedEditState({
|
||||
editing: true,
|
||||
multiline: false,
|
||||
atStart: true,
|
||||
atEnd: true
|
||||
}, { focused: "input[type=text]" }),
|
||||
new ExpectedTextSelectionChanged(0, 0)
|
||||
],
|
||||
[ContentMessages.simpleMovePrevious,
|
||||
new ExpectedCursorChange(
|
||||
["So we don't get dessert?", {string: "label"}]),
|
||||
new ExpectedAnnouncement("navigating"),
|
||||
new ExpectedEditState({
|
||||
editing: false,
|
||||
multiline: false,
|
||||
atStart: true,
|
||||
atEnd: false
|
||||
}, { focused: "html" })
|
||||
],
|
||||
[ContentMessages.simpleMoveNext,
|
||||
new ExpectedCursorChange(
|
||||
[{ string: "entry" }],
|
||||
{ focused: "html"})],
|
||||
[ContentMessages.activateCurrent(0),
|
||||
new ExpectedClickAction(),
|
||||
new ExpectedAnnouncement("editing"),
|
||||
new ExpectedEditState({
|
||||
editing: true,
|
||||
multiline: false,
|
||||
atStart: true,
|
||||
atEnd: true
|
||||
},
|
||||
{ focused: "input[type=text]" }),
|
||||
new ExpectedTextSelectionChanged(0, 0,
|
||||
// Bug 1455749: Fix granularity control in text entries.
|
||||
{ todo: true }
|
||||
)],
|
||||
[ContentMessages.simpleMovePrevious,
|
||||
new ExpectedCursorChange(
|
||||
[ "So we don't get dessert?", {string: "label"} ]),
|
||||
new ExpectedAnnouncement("navigating"),
|
||||
new ExpectedEditState({
|
||||
editing: false,
|
||||
multiline: false,
|
||||
atStart: true,
|
||||
atEnd: false
|
||||
}, { focused: "html" })],
|
||||
|
||||
[ContentMessages.focusSelector("input"),
|
||||
new ExpectedAnnouncement("editing"),
|
||||
new ExpectedEditState({
|
||||
editing: true,
|
||||
multiline: false,
|
||||
atStart: true,
|
||||
atEnd: true
|
||||
}),
|
||||
new ExpectedCursorChange([{string: "entry"}]),
|
||||
new ExpectedTextSelectionChanged(0, 0)
|
||||
],
|
||||
[function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [[KEYBOARD_ECHO_SETTING, 3]]}, typeKey("a")());
|
||||
},
|
||||
new ExpectedTextChanged("a"),
|
||||
new ExpectedTextSelectionChanged(1, 1),
|
||||
new ExpectedValueChange(),
|
||||
],
|
||||
[typeKey("b"),
|
||||
new ExpectedTextChanged("b"),
|
||||
new ExpectedValueChange(),
|
||||
new ExpectedTextSelectionChanged(2, 2),
|
||||
],
|
||||
[typeKey("c"),
|
||||
new ExpectedTextChanged("c"),
|
||||
new ExpectedValueChange(),
|
||||
new ExpectedTextSelectionChanged(3, 3),
|
||||
],
|
||||
[typeKey("d"),
|
||||
new ExpectedTextChanged("d"),
|
||||
new ExpectedValueChange(),
|
||||
new ExpectedTextSelectionChanged(4, 4),
|
||||
],
|
||||
[typeKey(" "),
|
||||
new ExpectedTextChanged(" abcd"),
|
||||
new ExpectedValueChange(),
|
||||
new ExpectedTextSelectionChanged(5, 5),
|
||||
],
|
||||
[typeKey("e"),
|
||||
new ExpectedTextChanged("e"),
|
||||
new ExpectedValueChange(),
|
||||
new ExpectedTextSelectionChanged(6, 6),
|
||||
],
|
||||
[function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [[KEYBOARD_ECHO_SETTING, 2]]}, typeKey("a")());
|
||||
},
|
||||
new ExpectedTextChanged(""),
|
||||
new ExpectedValueChange(),
|
||||
new ExpectedTextSelectionChanged(7, 7),
|
||||
],
|
||||
[typeKey("d"),
|
||||
new ExpectedTextChanged(""),
|
||||
new ExpectedValueChange(),
|
||||
new ExpectedTextSelectionChanged(8, 8),
|
||||
],
|
||||
[typeKey(" "),
|
||||
new ExpectedTextChanged(" ead"),
|
||||
new ExpectedValueChange(),
|
||||
new ExpectedTextSelectionChanged(9, 9),
|
||||
],
|
||||
[function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [[KEYBOARD_ECHO_SETTING, 1]]}, typeKey("f")());
|
||||
},
|
||||
new ExpectedTextChanged("f"),
|
||||
new ExpectedValueChange(),
|
||||
new ExpectedTextSelectionChanged(10, 10),
|
||||
],
|
||||
[typeKey("g"),
|
||||
new ExpectedTextChanged("g"),
|
||||
new ExpectedValueChange(),
|
||||
new ExpectedTextSelectionChanged(11, 11),
|
||||
],
|
||||
[typeKey(" "),
|
||||
new ExpectedTextChanged(" "),
|
||||
new ExpectedValueChange(),
|
||||
new ExpectedTextSelectionChanged(12, 12),
|
||||
],
|
||||
[function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [[KEYBOARD_ECHO_SETTING, 0]]}, typeKey("f")());
|
||||
},
|
||||
new ExpectedTextChanged(""),
|
||||
new ExpectedValueChange(),
|
||||
new ExpectedTextSelectionChanged(13, 13),
|
||||
],
|
||||
[typeKey("g"),
|
||||
new ExpectedTextChanged(""),
|
||||
new ExpectedValueChange(),
|
||||
new ExpectedTextSelectionChanged(14, 14),
|
||||
],
|
||||
[typeKey(" "),
|
||||
new ExpectedTextChanged(""),
|
||||
new ExpectedValueChange(),
|
||||
new ExpectedTextSelectionChanged(15, 15),
|
||||
],
|
||||
]);
|
||||
|
||||
const KEYBOARD_ECHO_SETTING = "accessibility.accessfu.keyboard_echo";
|
||||
function typeKey(key) {
|
||||
let func = function() { synthesizeKey(key, {}, currentTabWindow()); };
|
||||
func.toString = () => `typeKey('${key}')`;
|
||||
return func;
|
||||
}
|
||||
|
||||
addA11yLoadEvent(function() {
|
||||
textTest.start(function() {
|
||||
closeBrowserWindow();
|
||||
SimpleTest.finish();
|
||||
});
|
||||
}, doc.defaultView);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(
|
||||
function() {
|
||||
openBrowserWindow(
|
||||
doTest,
|
||||
getRootDirectory(window.location.href) + "doc_content_text.html");
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body id="body">
|
||||
|
||||
<a target="_blank"
|
||||
title="Add tests for text editing and navigating"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=972047">Mozilla Bug 933808</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,129 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Tests AccessFu navigation in focused editable</title>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
|
||||
</script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js">
|
||||
</script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/chrome-harness.js">
|
||||
</script>
|
||||
|
||||
<script type="application/javascript" src="../common.js"></script>
|
||||
<script type="application/javascript" src="../browser.js"></script>
|
||||
<script type="application/javascript" src="../events.js"></script>
|
||||
<script type="application/javascript" src="../role.js"></script>
|
||||
<script type="application/javascript" src="../states.js"></script>
|
||||
<script type="application/javascript" src="../layout.js"></script>
|
||||
<script type="application/javascript" src="jsatcommon.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function checkMoveCaret(aMoveEvent, aSelectionEvent, aFrom, aTo) {
|
||||
is(aMoveEvent.fromIndex, Math.min(aFrom, aTo), "Move to offset (fromIndex)");
|
||||
is(aMoveEvent.toIndex, Math.max(aFrom, aTo), "Move to offset (toIndex)");
|
||||
is(aSelectionEvent.fromIndex, aTo, "Caret offset (fromIndex)");
|
||||
is(aSelectionEvent.toIndex, aTo, "Caret offset (toIndex)");
|
||||
}
|
||||
|
||||
async function testEditableTextNavigation(doc, runner) {
|
||||
// Editable text tests.
|
||||
let evt;
|
||||
|
||||
evt = await runner.focusSelector("textarea",
|
||||
AndroidEvents.ANNOUNCEMENT,
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED,
|
||||
AndroidEvents.VIEW_TEXT_SELECTION_CHANGED);
|
||||
// XXX: Get rid of announcements, and send focus events instead
|
||||
runner.eventTextMatches(evt[0], ["editing"]);
|
||||
runner.eventTextMatches(evt[1],
|
||||
["Text content test document",
|
||||
"Please refrain from Mayoneggs during this salmonella scare.",
|
||||
"text area"]);
|
||||
is(evt[2].fromIndex, 0, "Correct fromIndex");
|
||||
is(evt[2].toIndex, 0, "Correct toIndex");
|
||||
|
||||
evt = await runner.activateCurrent(10,
|
||||
AndroidEvents.VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
|
||||
AndroidEvents.VIEW_TEXT_SELECTION_CHANGED);
|
||||
checkMoveCaret(...evt, 0, 10);
|
||||
|
||||
evt = await runner.activateCurrent(20,
|
||||
AndroidEvents.VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
|
||||
AndroidEvents.VIEW_TEXT_SELECTION_CHANGED);
|
||||
checkMoveCaret(...evt, 10, 20);
|
||||
|
||||
evt = await runner.moveCaretNext(MovementGranularity.WORD,
|
||||
AndroidEvents.VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
|
||||
AndroidEvents.VIEW_TEXT_SELECTION_CHANGED);
|
||||
checkMoveCaret(...evt, 20, 29);
|
||||
|
||||
evt = await runner.moveCaretNext(MovementGranularity.WORD,
|
||||
AndroidEvents.VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
|
||||
AndroidEvents.VIEW_TEXT_SELECTION_CHANGED);
|
||||
checkMoveCaret(...evt, 29, 36);
|
||||
|
||||
evt = await runner.moveCaretNext(MovementGranularity.CHARACTER,
|
||||
AndroidEvents.VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
|
||||
AndroidEvents.VIEW_TEXT_SELECTION_CHANGED);
|
||||
checkMoveCaret(...evt, 36, 37);
|
||||
|
||||
evt = await runner.moveCaretNext(MovementGranularity.CHARACTER,
|
||||
AndroidEvents.VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
|
||||
AndroidEvents.VIEW_TEXT_SELECTION_CHANGED);
|
||||
checkMoveCaret(...evt, 37, 38);
|
||||
|
||||
evt = await runner.moveCaretNext(MovementGranularity.PARAGRAPH,
|
||||
AndroidEvents.VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
|
||||
AndroidEvents.VIEW_TEXT_SELECTION_CHANGED);
|
||||
checkMoveCaret(...evt, 38, 59);
|
||||
|
||||
evt = await runner.moveCaretPrevious(MovementGranularity.WORD,
|
||||
AndroidEvents.VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
|
||||
AndroidEvents.VIEW_TEXT_SELECTION_CHANGED);
|
||||
checkMoveCaret(...evt, 59, 53);
|
||||
|
||||
evt = await runner.blur(AndroidEvents.ANNOUNCEMENT);
|
||||
runner.eventTextMatches(evt, ["navigating"]);
|
||||
}
|
||||
|
||||
function doTest() {
|
||||
var doc = currentTabDocument();
|
||||
|
||||
addA11yLoadEvent(async function() {
|
||||
let runner = new AccessFuContentTestRunner();
|
||||
await runner.start();
|
||||
|
||||
await testEditableTextNavigation(doc, runner);
|
||||
|
||||
runner.finish();
|
||||
closeBrowserWindow();
|
||||
SimpleTest.finish();
|
||||
}, doc.defaultView);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(
|
||||
function() {
|
||||
openBrowserWindow(
|
||||
doTest,
|
||||
getRootDirectory(window.location.href) + "doc_content_text.html");
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body id="body">
|
||||
|
||||
<a target="_blank"
|
||||
title="Add tests for text editing and navigating"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1459677">Mozilla Bug 1459677</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,148 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Tests AccessFu text editing</title>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
|
||||
</script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js">
|
||||
</script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/chrome-harness.js">
|
||||
</script>
|
||||
|
||||
<script type="application/javascript" src="../common.js"></script>
|
||||
<script type="application/javascript" src="../browser.js"></script>
|
||||
<script type="application/javascript" src="../events.js"></script>
|
||||
<script type="application/javascript" src="../role.js"></script>
|
||||
<script type="application/javascript" src="../states.js"></script>
|
||||
<script type="application/javascript" src="../layout.js"></script>
|
||||
<script type="application/javascript" src="jsatcommon.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
async function testTextEditing(doc, runner) {
|
||||
function checkInsert(textChangeEvent, testSelEvent, text, insertIndex, addedCount) {
|
||||
runner.eventTextMatches(textChangeEvent, text);
|
||||
is(textChangeEvent.addedCount, addedCount);
|
||||
is(textChangeEvent.fromIndex, insertIndex);
|
||||
runner.eventTextMatches(testSelEvent, text);
|
||||
is(testSelEvent.toIndex, insertIndex + addedCount);
|
||||
is(testSelEvent.fromIndex, insertIndex + addedCount);
|
||||
}
|
||||
|
||||
let evt;
|
||||
|
||||
evt = await runner.focusSelector("input",
|
||||
AndroidEvents.ANNOUNCEMENT,
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED,
|
||||
AndroidEvents.VIEW_TEXT_SELECTION_CHANGED);
|
||||
// XXX: Get rid of announcements, and send focus events instead
|
||||
runner.eventTextMatches(evt[0], ["editing"]);
|
||||
runner.eventTextMatches(evt[1], ["Text content test document", "entry"]);
|
||||
is(evt[2].fromIndex, 0, "Caret at start (fromIndex)");
|
||||
is(evt[2].toIndex, 0, "Caret at start (toIndex)");
|
||||
|
||||
evt = await runner.typeKey("B",
|
||||
AndroidEvents.VIEW_TEXT_CHANGED,
|
||||
AndroidEvents.VIEW_TEXT_SELECTION_CHANGED,
|
||||
"todo.value-changed");
|
||||
checkInsert(evt[0], evt[1], ["B"], 0, 1);
|
||||
|
||||
evt = await runner.typeKey("o",
|
||||
AndroidEvents.VIEW_TEXT_CHANGED,
|
||||
AndroidEvents.VIEW_TEXT_SELECTION_CHANGED,
|
||||
"todo.value-changed");
|
||||
checkInsert(evt[0], evt[1], ["Bo"], 1, 1);
|
||||
|
||||
evt = await runner.typeKey("b",
|
||||
AndroidEvents.VIEW_TEXT_CHANGED,
|
||||
AndroidEvents.VIEW_TEXT_SELECTION_CHANGED,
|
||||
"todo.value-changed");
|
||||
checkInsert(evt[0], evt[1], ["Bob"], 2, 1);
|
||||
|
||||
evt = await runner.typeKey(" ",
|
||||
AndroidEvents.VIEW_TEXT_CHANGED,
|
||||
AndroidEvents.VIEW_TEXT_SELECTION_CHANGED,
|
||||
"todo.value-changed");
|
||||
checkInsert(evt[0], evt[1], ["Bob "], 3, 1);
|
||||
|
||||
evt = await runner.typeKey("L",
|
||||
AndroidEvents.VIEW_TEXT_CHANGED,
|
||||
AndroidEvents.VIEW_TEXT_SELECTION_CHANGED,
|
||||
"todo.value-changed");
|
||||
checkInsert(evt[0], evt[1], ["Bob L"], 4, 1);
|
||||
|
||||
evt = await runner.typeKey("o",
|
||||
AndroidEvents.VIEW_TEXT_CHANGED,
|
||||
AndroidEvents.VIEW_TEXT_SELECTION_CHANGED,
|
||||
"todo.value-changed");
|
||||
checkInsert(evt[0], evt[1], ["Bob Lo"], 5, 1);
|
||||
|
||||
evt = await runner.typeKey("b",
|
||||
AndroidEvents.VIEW_TEXT_CHANGED,
|
||||
AndroidEvents.VIEW_TEXT_SELECTION_CHANGED,
|
||||
"todo.value-changed");
|
||||
checkInsert(evt[0], evt[1], ["Bob Lob"], 6, 1);
|
||||
|
||||
evt = await runner.typeKey("l",
|
||||
AndroidEvents.VIEW_TEXT_CHANGED,
|
||||
AndroidEvents.VIEW_TEXT_SELECTION_CHANGED,
|
||||
"todo.value-changed");
|
||||
checkInsert(evt[0], evt[1], ["Bob Lobl"], 7, 1);
|
||||
|
||||
evt = await runner.typeKey("a",
|
||||
AndroidEvents.VIEW_TEXT_CHANGED,
|
||||
AndroidEvents.VIEW_TEXT_SELECTION_CHANGED,
|
||||
"todo.value-changed");
|
||||
checkInsert(evt[0], evt[1], ["Bob Lobla"], 8, 1);
|
||||
|
||||
evt = await runner.typeKey("w",
|
||||
AndroidEvents.VIEW_TEXT_CHANGED,
|
||||
AndroidEvents.VIEW_TEXT_SELECTION_CHANGED,
|
||||
"todo.value-changed");
|
||||
checkInsert(evt[0], evt[1], ["Bob Loblaw"], 9, 1);
|
||||
|
||||
evt = await runner.blur(AndroidEvents.ANNOUNCEMENT);
|
||||
runner.eventTextMatches(evt, ["navigating"]);
|
||||
}
|
||||
|
||||
|
||||
function doTest() {
|
||||
var doc = currentTabDocument();
|
||||
|
||||
addA11yLoadEvent(async function() {
|
||||
let runner = new AccessFuContentTestRunner();
|
||||
await runner.start();
|
||||
|
||||
await testTextEditing(doc, runner);
|
||||
|
||||
runner.finish();
|
||||
closeBrowserWindow();
|
||||
SimpleTest.finish();
|
||||
}, doc.defaultView);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(
|
||||
function() {
|
||||
openBrowserWindow(
|
||||
doTest,
|
||||
getRootDirectory(window.location.href) + "doc_content_text.html");
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body id="body">
|
||||
|
||||
<a target="_blank"
|
||||
title="Add tests for text editing and navigating"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1459677">Mozilla Bug 1459677</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,134 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Tests AccessFu text navigation</title>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
|
||||
</script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js">
|
||||
</script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/chrome-harness.js">
|
||||
</script>
|
||||
|
||||
<script type="application/javascript" src="../common.js"></script>
|
||||
<script type="application/javascript" src="../browser.js"></script>
|
||||
<script type="application/javascript" src="../events.js"></script>
|
||||
<script type="application/javascript" src="../role.js"></script>
|
||||
<script type="application/javascript" src="../states.js"></script>
|
||||
<script type="application/javascript" src="../layout.js"></script>
|
||||
<script type="application/javascript" src="jsatcommon.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function checkFromToIndex(aEvent, aFrom, aTo) {
|
||||
is(aEvent.fromIndex, aFrom, "Correct fromIndex");
|
||||
is(aEvent.toIndex, aTo, "Correct toIndex");
|
||||
}
|
||||
|
||||
async function testTextNavigation(doc, runner) {
|
||||
let evt;
|
||||
|
||||
// Read-only text tests
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Text content test document",
|
||||
"These are my awards, Mother. From Army. " +
|
||||
"The seal is for marksmanship, and the gorilla is for sand racing."]);
|
||||
|
||||
// "These"
|
||||
evt = await runner.moveNextByGranularity(MovementGranularity.WORD,
|
||||
AndroidEvents.VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY);
|
||||
checkFromToIndex(evt, 0, 5);
|
||||
|
||||
// "are"
|
||||
evt = await runner.moveNextByGranularity(MovementGranularity.WORD,
|
||||
AndroidEvents.VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY);
|
||||
checkFromToIndex(evt, 6, 9);
|
||||
|
||||
// "my"
|
||||
evt = await runner.moveNextByGranularity(MovementGranularity.WORD,
|
||||
AndroidEvents.VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY);
|
||||
checkFromToIndex(evt, 10, 12);
|
||||
|
||||
// "awards,"
|
||||
evt = await runner.moveNextByGranularity(MovementGranularity.WORD,
|
||||
AndroidEvents.VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY);
|
||||
checkFromToIndex(evt, 13, 20);
|
||||
|
||||
// "Mother."
|
||||
evt = await runner.moveNextByGranularity(MovementGranularity.WORD,
|
||||
AndroidEvents.VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY);
|
||||
checkFromToIndex(evt, 21, 28);
|
||||
|
||||
// "awards,"
|
||||
evt = await runner.movePreviousByGranularity(MovementGranularity.WORD,
|
||||
AndroidEvents.VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY);
|
||||
checkFromToIndex(evt, 13, 20);
|
||||
|
||||
// "my"
|
||||
evt = await runner.movePreviousByGranularity(MovementGranularity.WORD,
|
||||
AndroidEvents.VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY);
|
||||
checkFromToIndex(evt, 10, 12);
|
||||
|
||||
// "are"
|
||||
evt = await runner.movePreviousByGranularity(MovementGranularity.WORD,
|
||||
AndroidEvents.VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY);
|
||||
checkFromToIndex(evt, 6, 9);
|
||||
|
||||
// "These"
|
||||
evt = await runner.movePreviousByGranularity(MovementGranularity.WORD,
|
||||
AndroidEvents.VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY);
|
||||
checkFromToIndex(evt, 0, 5);
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["You're a good guy, mon frere. " +
|
||||
"That means brother in French. I don't know how I know that. " +
|
||||
"I took four years of Spanish."]);
|
||||
|
||||
// "You're"
|
||||
evt = await runner.moveNextByGranularity(MovementGranularity.WORD,
|
||||
AndroidEvents.VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY);
|
||||
is(evt.fromIndex, 0, "Correct fromIndex");
|
||||
todo_is(evt.toIndex, 6, "Word boundary should be past the apostraphe");
|
||||
}
|
||||
|
||||
function doTest() {
|
||||
var doc = currentTabDocument();
|
||||
|
||||
addA11yLoadEvent(async function() {
|
||||
let runner = new AccessFuContentTestRunner();
|
||||
await runner.start();
|
||||
|
||||
await testTextNavigation(doc, runner);
|
||||
|
||||
runner.finish();
|
||||
closeBrowserWindow();
|
||||
SimpleTest.finish();
|
||||
}, doc.defaultView);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(
|
||||
function() {
|
||||
openBrowserWindow(
|
||||
doTest,
|
||||
getRootDirectory(window.location.href) + "doc_content_text.html");
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body id="body">
|
||||
|
||||
<a target="_blank"
|
||||
title="Add tests for text editing and navigating"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1459677">Mozilla Bug 1459677</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,118 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Tests AccessFu text entry focus and a11y focus</title>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
|
||||
</script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js">
|
||||
</script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/chrome-harness.js">
|
||||
</script>
|
||||
|
||||
<script type="application/javascript" src="../common.js"></script>
|
||||
<script type="application/javascript" src="../browser.js"></script>
|
||||
<script type="application/javascript" src="../events.js"></script>
|
||||
<script type="application/javascript" src="../role.js"></script>
|
||||
<script type="application/javascript" src="../states.js"></script>
|
||||
<script type="application/javascript" src="../layout.js"></script>
|
||||
<script type="application/javascript" src="jsatcommon.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
async function testTextNavigationFocus(doc, runner) {
|
||||
let evt;
|
||||
|
||||
evt = await runner.focusSelector("textarea",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED,
|
||||
AndroidEvents.ANNOUNCEMENT);
|
||||
// XXX: Get rid of announcements, and send focus events instead
|
||||
runner.eventTextMatches(evt[0],
|
||||
["Text content test document",
|
||||
"Please refrain from Mayoneggs during this salmonella scare.",
|
||||
"text area"]);
|
||||
runner.eventTextMatches(evt[1], ["editing"]);
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED,
|
||||
AndroidEvents.ANNOUNCEMENT);
|
||||
runner.eventTextMatches(evt[0], ["So we don't get dessert?", "label"]);
|
||||
runner.eventTextMatches(evt[1], ["navigating"]);
|
||||
runner.isFocused("html");
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["entry"]);
|
||||
runner.isFocused("html");
|
||||
|
||||
evt = await runner.activateCurrent(0,
|
||||
AndroidEvents.VIEW_CLICKED,
|
||||
AndroidEvents.ANNOUNCEMENT,
|
||||
AndroidEvents.VIEW_TEXT_SELECTION_CHANGED);
|
||||
runner.eventTextMatches(evt[1], ["editing"]);
|
||||
is(evt[2].fromIndex, 0, "Cursor at start");
|
||||
runner.isFocused("input[type=text]");
|
||||
|
||||
evt = await runner.movePrevious("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED,
|
||||
AndroidEvents.ANNOUNCEMENT);
|
||||
runner.eventTextMatches(evt[0], ["So we don't get dessert?", "label"]);
|
||||
runner.eventTextMatches(evt[1], ["navigating"]);
|
||||
runner.isFocused("html");
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["entry"]);
|
||||
runner.isFocused("html");
|
||||
|
||||
// XXX: TEXT_SELECTION_CHANGED should be fired here
|
||||
evt = await runner.activateCurrent(0,
|
||||
AndroidEvents.VIEW_CLICKED,
|
||||
AndroidEvents.ANNOUNCEMENT);
|
||||
runner.eventTextMatches(evt[1], ["editing"]);
|
||||
runner.isFocused("input[type=text]");
|
||||
|
||||
evt = await runner.blur(AndroidEvents.ANNOUNCEMENT);
|
||||
runner.eventTextMatches(evt, ["navigating"]);
|
||||
}
|
||||
|
||||
|
||||
function doTest() {
|
||||
var doc = currentTabDocument();
|
||||
|
||||
addA11yLoadEvent(async function() {
|
||||
let runner = new AccessFuContentTestRunner();
|
||||
await runner.start();
|
||||
|
||||
await testTextNavigationFocus(doc, runner);
|
||||
|
||||
runner.finish();
|
||||
closeBrowserWindow();
|
||||
SimpleTest.finish();
|
||||
}, doc.defaultView);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(
|
||||
function() {
|
||||
openBrowserWindow(
|
||||
doTest,
|
||||
getRootDirectory(window.location.href) + "doc_content_text.html");
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body id="body">
|
||||
|
||||
<a target="_blank"
|
||||
title="Add tests for text editing and navigating"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1459677">Mozilla Bug 1459677</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче