blob: 1d9864570b37bdce36edb02b3b49367ce9ea6ca8 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
GEN_INCLUDE(['dictation_test_base.js']);
DictationFocusHandlerTest = class extends DictationE2ETestBase {
/** @override */
async setUpDeferred() {
await super.setUpDeferred();
await importModule(
'FocusHandler', '/accessibility_common/dictation/focus_handler.js');
}
/** @return {!FocusHandler} */
getFocusHandler() {
return accessibilityCommon.dictation_.focusHandler_;
}
/** @return {!Promise} */
async activateFocusHandler() {
await this.getFocusHandler().refresh();
assertTrue(this.getFocusHandler().active_);
assertNotNullNorUndefined(this.getFocusHandler().deactivateTimeoutId_);
}
/**
* @param {boolean} active
* @return {!Promise}
*/
async waitForFocusHandlerActive(active) {
const focusHandler = this.getFocusHandler();
const activeOk = () => {
return focusHandler.active_ === active;
};
if (activeOk()) {
return;
}
await new Promise(resolve => {
const onActiveChanged = () => {
if (activeOk()) {
focusHandler.onActiveChangedForTesting_ = null;
resolve();
}
};
focusHandler.onActiveChangedForTesting_ = onActiveChanged;
});
}
/**
* @param {!AutomationNode} target
* @return {!Promise}
*/
async waitForFocus(target) {
const focusHandler = this.getFocusHandler();
const isTargetFocused = () => {
return focusHandler.editableNode_ === target;
};
if (isTargetFocused()) {
return;
}
await new Promise(resolve => {
const onFocusChanged = () => {
if (isTargetFocused()) {
focusHandler.onFocusChangedForTesting_ = null;
resolve();
}
};
focusHandler.onFocusChangedForTesting_ = onFocusChanged;
});
}
/** @return {string} */
simpleSite() {
return `
<button autofocus>Start</button>
<input id="first" type="text"></input>
`;
}
};
// This test ensures that FocusHandler activates when Dictation is toggled on.
AX_TEST_F('DictationFocusHandlerTest', 'Activate', async function() {
const root = await this.runWithLoadedTree(this.simpleSite());
const input = root.find({role: chrome.automation.RoleType.TEXT_FIELD});
assertTrue(Boolean(input));
// FocusHandler should not be activated until Dictation is toggled on.
assertFalse(this.getFocusHandler().active_);
assertEquals(null, this.getFocusHandler().editableNode_);
input.focus();
this.toggleDictationOn();
await this.waitForFocusHandlerActive(true);
});
// This test ensures that FocusHandler deactivates automatically after a
// period of inactivity.
AX_TEST_F('DictationFocusHandlerTest', 'Deactivate', async function() {
// Shorten timeout for testing.
FocusHandler.DEACTIVATE_TIMEOUT_MS_ = 1000;
await this.activateFocusHandler();
await this.waitForFocusHandlerActive(false);
});
// This test ensures that FocusHandler tracks focus once it's been activated.
AX_TEST_F('DictationFocusHandlerTest', 'OnFocusChanged', async function() {
await this.activateFocusHandler();
const root = await this.runWithLoadedTree(this.simpleSite());
const input = root.find({role: chrome.automation.RoleType.TEXT_FIELD});
assertTrue(Boolean(input));
input.focus();
await this.waitForFocus(input);
});
// This test ensures that the timeout to deactivate FocusHandler is reset
// whenever Dictation toggles on.
AX_TEST_F(
'DictationFocusHandlerTest', 'ResetDeactivateTimeout', async function() {
this.mockSetTimeoutMethod();
this.toggleDictationOn();
await this.waitForFocusHandlerActive(true);
let callback =
this.getCallbackWithDelay(FocusHandler.DEACTIVATE_TIMEOUT_MS_);
assertNotNullNorUndefined(callback);
this.clearSetTimeoutData();
this.toggleDictationOff();
this.toggleDictationOn();
// Toggling Dictation on should set a new timeout to deactivate
// FocusHandler.
callback = this.getCallbackWithDelay(FocusHandler.DEACTIVATE_TIMEOUT_MS_);
assertNotNullNorUndefined(callback);
// Running `callback` should deactivate FocusHandler.
callback();
await this.waitForFocusHandlerActive(false);
});