Commit 788cc609 authored by David Tseng's avatar David Tseng Committed by Commit Bot

Add test coverage for editable events

This change precisely stipulates the events handled for each type of editable
encountered through tests.

R=akihiroota@chromium.org

pressing 'e' would also cause sticky mode to turn off.

Fixed: 1135118
AX-Relnotes: fixes an issue in Smart Sticky mode where jumping to a text field by
Change-Id: I56de4cebc0a1a942d99c5d0c9445b5b33f9d4e00
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2448053Reviewed-by: default avatarAkihiro Ota <akihiroota@chromium.org>
Commit-Queue: David Tseng <dtseng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#814056}
parent 02cd0d95
......@@ -871,6 +871,26 @@ IN_PROC_BROWSER_TEST_P(SpokenFeedbackTest, SmartStickyMode) {
sm_.ExpectSpeech("Sticky mode enabled");
sm_.ExpectSpeech("start");
// Try a few jump commands and linear nav with no Search modifier. We never
// leave sticky mode.
sm_.Call([this]() { SendKeyPress(ui::VKEY_E); });
sm_.ExpectSpeech("Edit text");
sm_.Call([this]() { SendKeyPressWithShift(ui::VKEY_F); });
sm_.ExpectSpeech("Edit text");
sm_.Call([this]() { SendKeyPress(ui::VKEY_RIGHT); });
sm_.ExpectSpeech("end");
sm_.Call([this]() { SendKeyPress(ui::VKEY_F); });
sm_.ExpectSpeech("Edit text");
sm_.Call([this]() { SendKeyPressWithShift(ui::VKEY_E); });
sm_.ExpectSpeech("Edit text");
sm_.Call([this]() { SendKeyPressWithSearch(ui::VKEY_LEFT); });
sm_.ExpectSpeech("start");
// Now, navigate with sticky mode off.
sm_.Call([this]() { SendStickyKeyCommand(); });
sm_.ExpectSpeech("Sticky mode disabled");
......
......@@ -361,14 +361,37 @@ DesktopAutomationHandler = class extends BaseAutomationHandler {
* @private
*/
onEditableChanged_(evt) {
// Document selections only apply to rich editables, text selections to
// non-rich editables.
if (evt.type != EventType.DOCUMENT_SELECTION_CHANGED &&
(evt.target.state[StateType.RICHLY_EDITABLE] ||
evt.target.htmlTag === 'textarea')) {
if (!evt.target.state.editable) {
return;
}
const isInput = evt.target.htmlTag == 'input';
const isTextArea = evt.target.htmlTag == 'textarea';
const isContentEditable = evt.target.state[StateType.RICHLY_EDITABLE];
switch (evt.type) {
case EventType.TEXT_CHANGED:
case EventType.TEXT_SELECTION_CHANGED:
case EventType.VALUE_CHANGED:
// Known to be duplicated by document selection changes for content
// editables and text areas.
if (isContentEditable || isTextArea) {
return;
}
break;
case EventType.DOCUMENT_SELECTION_CHANGED:
// Known to be duplicated by text selection changes.
if (isInput) {
return;
}
break;
case EventType.FOCUS:
// Allowed no matter what.
break;
default:
return;
}
if (!this.createTextEditHandlerIfNeeded_(evt.target)) {
return;
}
......
......@@ -87,14 +87,7 @@ editing.TextEditHandler = class {
* @param {!ChromeVoxEvent} evt
*/
onEvent(evt) {
if (evt.type !== EventType.TEXT_CHANGED &&
evt.type !== EventType.TEXT_SELECTION_CHANGED &&
evt.type !== EventType.DOCUMENT_SELECTION_CHANGED &&
evt.type !== EventType.VALUE_CHANGED && evt.type !== EventType.FOCUS) {
return;
}
if (!evt.target.state.focused || !evt.target.state.editable ||
evt.target != this.node_) {
if (!evt.target.state.focused || evt.target != this.node_) {
return;
}
......
......@@ -21,6 +21,13 @@ ChromeVoxEditingTest = class extends ChromeVoxNextE2ETest {
EventGenerator.sendKeyPress(keyCode, modifiers);
};
}
waitForEditableEvent() {
return new Promise(resolve => {
DesktopAutomationHandler.instance.textEditHandler_.onEvent = (e) =>
resolve(e);
});
}
};
......@@ -96,7 +103,7 @@ TEST_F('ChromeVoxEditingTest', 'TextButNoSelectionChange', function() {
if (input.selectionStart == 0) {
return;
}
console.log('TIM' + 'ER');
input.value = 'text2';
window.clearInterval(timer);
}
......@@ -1470,3 +1477,111 @@ TEST_F('ChromeVoxEditingTest', 'NonBreakingSpaceNewLine', function() {
input.focus();
});
});
TEST_F('ChromeVoxEditingTest', 'InputEvents', function() {
const site = `<input type="text"></input>`;
this.runWithLoadedTree(site, async function(root) {
const input = root.find({role: RoleType.TEXT_FIELD});
input.focus();
await new Promise(resolve => {
this.listenOnce(input, 'focus', resolve);
});
let event = await this.waitForEditableEvent();
assertEquals(EventType.TEXT_SELECTION_CHANGED, event.type);
assertEquals(input, event.target);
assertEquals('', input.value);
this.press(KeyCode.A)();
// Important to note that there's no document selection changes below.
event = await this.waitForEditableEvent();
assertEquals(EventType.VALUE_CHANGED, event.type);
assertEquals(input, event.target);
assertEquals('a', input.value);
event = await this.waitForEditableEvent();
assertEquals(EventType.TEXT_SELECTION_CHANGED, event.type);
assertEquals(input, event.target);
assertEquals('a', input.value);
// TODO(accessibility): this extra value change shouldn't happen.
// http://crbug.com/1135249.
event = await this.waitForEditableEvent();
assertEquals(EventType.VALUE_CHANGED, event.type);
assertEquals(input, event.target);
assertEquals('a', input.value);
this.press(KeyCode.B)();
event = await this.waitForEditableEvent();
assertEquals(EventType.VALUE_CHANGED, event.type);
assertEquals(input, event.target);
assertEquals('ab', input.value);
event = await this.waitForEditableEvent();
assertEquals(EventType.TEXT_SELECTION_CHANGED, event.type);
assertEquals(input, event.target);
assertEquals('ab', input.value);
});
});
TEST_F('ChromeVoxEditingTest', 'TextAreaEvents', function() {
const site = `<textarea></textarea>`;
this.runWithLoadedTree(site, async function(root) {
const textArea = root.find({role: RoleType.TEXT_FIELD});
textArea.focus();
await new Promise(resolve => {
this.listenOnce(textArea, 'focus', resolve);
});
let event = await this.waitForEditableEvent();
assertEquals(EventType.DOCUMENT_SELECTION_CHANGED, event.type);
assertEquals(textArea, event.target);
assertEquals('', textArea.value);
this.press(KeyCode.A)();
event = await this.waitForEditableEvent();
assertEquals(EventType.DOCUMENT_SELECTION_CHANGED, event.type);
assertEquals(textArea, event.target);
assertEquals('a', textArea.value);
this.press(KeyCode.B)();
event = await this.waitForEditableEvent();
assertEquals(EventType.DOCUMENT_SELECTION_CHANGED, event.type);
assertEquals(textArea, event.target);
assertEquals('ab', textArea.value);
});
});
TEST_F('ChromeVoxEditingTest', 'ContentEditableEvents', function() {
const site = `<div role="textbox" contenteditable></div>`;
this.runWithLoadedTree(site, async function(root) {
const contentEditable = root.find({role: RoleType.TEXT_FIELD});
contentEditable.focus();
await new Promise(resolve => {
this.listenOnce(contentEditable, 'focus', resolve);
});
let event = await this.waitForEditableEvent();
assertEquals(EventType.DOCUMENT_SELECTION_CHANGED, event.type);
assertEquals(contentEditable, event.target);
assertEquals('', contentEditable.value);
this.press(KeyCode.A)();
event = await this.waitForEditableEvent();
assertEquals(EventType.DOCUMENT_SELECTION_CHANGED, event.type);
assertEquals(contentEditable, event.target);
assertEquals('a', contentEditable.value);
this.press(KeyCode.B)();
event = await this.waitForEditableEvent();
assertEquals(EventType.DOCUMENT_SELECTION_CHANGED, event.type);
assertEquals(contentEditable, event.target);
assertEquals('ab', contentEditable.value);
});
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment