1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Include test fixture.
GEN_INCLUDE(['../testing/chromevox_e2e_test_base.js']);
GEN_INCLUDE(['../../../common/testing/documents.js']);
/** Test fixture for ChromeVoxRange. */
ChromeVoxRangeTest = class extends ChromeVoxE2ETest {
/** @override */
async setUpDeferred() {
await super.setUpDeferred();
globalThis.RoleType = chrome.automation.RoleType;
}
};
AX_TEST_F('ChromeVoxRangeTest', 'Observer', async function() {
const root =
await this.runWithLoadedTree(Documents.button + Documents.slider);
const button = root.find({role: RoleType.BUTTON});
assertNotNullNorUndefined(button);
const slider = root.find({role: RoleType.SLIDER});
assertNotNullNorUndefined(slider);
const observer = new class extends ChromeVoxRangeObserver {
onCurrentRangeChanged(range, opt_fromEditing) {
this.capturedRange = range;
this.capturedFromEditing = opt_fromEditing;
}
}
();
ChromeVoxRange.addObserver(observer);
// Test when range changes not from editing.
const buttonRange = CursorRange.fromNode(button);
ChromeVoxRange.set(buttonRange);
assertEquals(buttonRange, observer.capturedRange);
assertUndefined(observer.capturedFromEditing);
// Test when range change is from editing.
const sliderRange = CursorRange.fromNode(slider);
ChromeVoxRange.set(sliderRange, true);
assertEquals(sliderRange, observer.capturedRange);
assertTrue(observer.capturedFromEditing);
// Test removeObserver.
ChromeVoxRange.removeObserver(observer);
delete observer.capturedRange;
ChromeVoxRange.set(buttonRange);
assertUndefined(observer.capturedRange);
});
AX_TEST_F(
'ChromeVoxRangeTest', 'GetCurrentRangeWithoutRecovery', async function() {
const root = await this.runWithLoadedTree('');
ChromeVoxRange.instance.current_ = CursorRange.fromNode(root);
ChromeVoxRange.instance.current_.isValid = () => false;
assertNotNullNorUndefined(
ChromeVoxRange.getCurrentRangeWithoutRecovery());
});
AX_TEST_F('ChromeVoxRangeTest', 'Current', async function() {
const root = await this.runWithLoadedTree('');
ChromeVoxRange.instance.current_ = null;
assertEquals(null, ChromeVoxRange.current, 'First');
ChromeVoxRange.instance.current_ = CursorRange.fromNode(root);
assertEquals(
ChromeVoxRange.instance.current_, ChromeVoxRange.current, 'Second');
ChromeVoxRange.instance.current_.isValid = () => false;
assertEquals(null, ChromeVoxRange.current, 'Third');
});
AX_TEST_F('ChromeVoxRangeTest', 'Set', async function() {
const root = await this.runWithLoadedTree(Documents.button);
const rootRange = CursorRange.fromNode(root);
const button = root.find({role: RoleType.BUTTON});
assertNotNullNorUndefined(button);
const buttonRange = CursorRange.fromNode(button);
const desktopRange = CursorRange.fromNode(this.desktop_);
let hasThawed;
ChromeVox.braille.thaw = () => hasThawed = true;
let lastFocusBounds;
FocusBounds.set = bounds => lastFocusBounds = bounds;
const reset = () => {
hasThawed = false;
lastFocusBounds = null;
ChromeVoxRange.instance.current_ = null;
ChromeVoxRange.instance.previous_ = rootRange;
ChromeVoxState.position = {};
};
// When setting to null and the previous is already null, it returns early.
reset();
ChromeVoxRange.instance.current_ = null;
ChromeVoxRange.set(null);
assertTrue(hasThawed);
assertTrue(lastFocusBounds instanceof Array);
assertEquals(0, lastFocusBounds.length);
assertNotNullNorUndefined(ChromeVoxRange.instance.previous_);
assertEquals(0, Object.keys(ChromeVoxState.position).length);
// When the new range is not valid, it returns early.
reset();
const invalidRange = CursorRange.fromNode(root);
invalidRange.isValid = () => false;
ChromeVoxRange.set(invalidRange);
assertTrue(hasThawed);
assertTrue(lastFocusBounds instanceof Array);
assertEquals(0, lastFocusBounds.length);
assertEquals(0, Object.keys(ChromeVoxState.position).length);
// When the new range is null, set the previous and current and then return.
reset();
ChromeVoxRange.instance.current_ = buttonRange;
ChromeVoxRange.set(null);
assertTrue(hasThawed);
assertTrue(lastFocusBounds instanceof Array);
assertEquals(0, lastFocusBounds.length);
assertEquals(buttonRange, ChromeVoxRange.instance.previous_);
assertEquals(null, ChromeVoxRange.instance.current_);
assertEquals(0, Object.keys(ChromeVoxState.position).length);
// When the node's root is the desktop, don't set a position.
reset();
ChromeVoxRange.set(desktopRange);
assertTrue(hasThawed);
assertEquals(null, ChromeVoxRange.instance.previous_);
assertEquals(desktopRange, ChromeVoxRange.instance.current_);
assertEquals(0, Object.keys(ChromeVoxState.position).length);
// Check that the position is set when the focus is in a webpage.
reset();
ChromeVoxRange.set(buttonRange);
assertTrue(hasThawed);
assertEquals(null, ChromeVoxRange.instance.previous_);
assertEquals(buttonRange, ChromeVoxRange.instance.current_);
assertEquals(1, Object.keys(ChromeVoxState.position).length);
});
TEST_F('ChromeVoxRangeTest', 'MaybeResetFromFocus', async function() {
const root = await this.runWithLoadedTree(Documents.button);
const button = root.find({role: RoleType.BUTTON});
let focusNode = null;
chrome.automation.getFocus = callback => callback(focusNode);
// If there's no focused node, the range is set to null.
ChromeVoxRange.instance.current_ = CursorRange.fromNode(button);
ChromeVoxRange.maybeResetFromFocus();
assertEquals(null, ChromeVoxRange.instance.current_);
// If the current node is nod valid and there's a current focus, set the
// current range to be the focus.
const invalidRange = CursorRange.fromNode(button);
invalidRange.isValid = () => false;
ChromeVoxRange.instance.current_ = invalidRange;
focusNode = root;
ChromeVoxRange.maybeResetFromFocus();
assertEquals(focusNode, ChromeVoxRange.instance.current_);
// If talkback is enabled, clear the range.
ChromeVoxState.instance.talkBackEnabled = true;
focusNode = this.desktop_.find({role: RoleType.CLIENT});
assertNotNullNorUndefined(focusNode);
ChromeVoxRange.maybeResetFromFocus();
assertEquals(null, ChromeVoxRange.instance.current_);
});
|