Commit b159c717 authored by Zach Helfinstein's avatar Zach Helfinstein Committed by Commit Bot

Fix compile issue, typo


Reland "Update existing Switch Access tests"

This is a reland of d4860fed

Original change's description:
> Update existing Switch Access tests
>
> Bug: 897365
> Change-Id: Ic8ff1ea5511f3d6cc907a880fffdffa7c5fdbcc9
> Reviewed-on: https://chromium-review.googlesource.com/c/1306787
> Reviewed-by: David Tseng <dtseng@chromium.org>
> Commit-Queue: Zach Helfinstein <zhelfins@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#605719}

Bug: 897365
Change-Id: Ic0b73345f79bf5a075fd42cbea69a74b0e890257
Reviewed-on: https://chromium-review.googlesource.com/c/1320027Reviewed-by: default avatarDavid Tseng <dtseng@chromium.org>
Commit-Queue: Zach Helfinstein <zhelfins@chromium.org>
Cr-Commit-Position: refs/heads/master@{#605844}
parent 65b6625b
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
# found in the LICENSE file. # found in the LICENSE file.
import("//build/config/features.gni") import("//build/config/features.gni")
import("//chrome/common/features.gni")
import("//testing/test.gni") import("//testing/test.gni")
import("//chrome/test/base/js2gtest.gni") import("//chrome/test/base/js2gtest.gni")
import("//chrome/browser/resources/chromeos/chromevox/run_jsbundler.gni") import("//chrome/browser/resources/chromeos/chromevox/run_jsbundler.gni")
...@@ -55,23 +56,43 @@ run_jsbundler("switch_access_copied_files") { ...@@ -55,23 +56,43 @@ run_jsbundler("switch_access_copied_files") {
] ]
} }
test("switch_access_tests") { source_set("browser_tests") {
testonly = true
assert(enable_extensions)
deps = [ deps = [
":switch_access_webuijs_tests", ":switch_access_extjs_tests",
"//chrome/test:browser_tests_runner", ]
data = [
"//chrome/browser/resources/chromeos/chromevox/",
"//chrome/browser/resources/chromeos/switch_access/",
"//chrome/third_party/mock4js/",
"//third_party/accessibility-audit/axs_testing.js",
"//third_party/chaijs/chai.js",
"//ui/webui/resources/js/cr.js",
] ]
} }
js2gtest("switch_access_webuijs_tests") { js2gtest("switch_access_extjs_tests") {
test_type = "webui" test_type = "extension"
sources = [ sources = [
"auto_scan_manager_unittest.gtestjs", "auto_scan_manager_test.extjs",
"switch_access_predicate_unittest.gtestjs", "switch_access_predicate_test.extjs",
] ]
extra_js_files = [ gen_include_files = [
"auto_scan_manager.js", "../chromevox/testing/callback_helper.js",
"switch_access_predicate.js", "switch_access_e2e_test_base.js",
"test_support.js", ]
# The test base classes generate C++ code with these deps.
deps = [
"//ash",
"//base",
"//chrome/browser/chromeos",
"//chrome/common",
"//chromeos",
"//ui/keyboard",
] ]
defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
} }
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
GEN_INCLUDE(['switch_access_e2e_test_base.js']);
UNDEFINED_INTERVAL_DELAY = -1;
/**
* @constructor
* @extends {SwitchAccessE2ETest}
*/
function SwitchAccessAutoScanManagerTest() {
SwitchAccessE2ETest.call(this);
}
SwitchAccessAutoScanManagerTest.prototype = {
__proto__: SwitchAccessE2ETest.prototype,
/** @override */
setUp: function() {
// Use intervalCount and intervalDelay to check how many intervals are
// currently running (should be no more than 1) and the current delay.
window.intervalCount = 0;
window.intervalDelay = UNDEFINED_INTERVAL_DELAY;
window.defaultSetInterval = window.setInterval;
window.defaultClearInterval = window.clearInterval;
window.switchAccess.defaultMoveForward = window.switchAccess.moveForward;
window.switchAccess.moveForwardCount = 0;
window.setInterval = function(func, delay) {
window.intervalCount++;
window.intervalDelay = delay;
// Override the delay to 1 ms to speed up the test.
return window.defaultSetInterval(func, 1);
};
window.clearInterval = function(intervalId) {
if (intervalId)
window.intervalCount--;
window.defaultClearInterval(intervalId);
};
window.switchAccess.moveForward = function() {
window.switchAccess.moveForwardCount++;
window.switchAccess.defaultMoveForward();
};
this.autoScanManager = window.switchAccess.autoScanManager_;
switchAccess.onMoveForwardForTesting_ = null;
}
};
TEST_F('SwitchAccessAutoScanManagerTest', 'SetEnabled', function() {
this.runWithLoadedTree('data:text/html;charset=utf-8,',
function(desktop) {
assertFalse(this.autoScanManager.isRunning());
assertEquals(0, switchAccess.moveForwardCount);
assertEquals(0, intervalCount);
switchAccess.onMoveForwardForTesting_ =
this.newCallback(function() {
assertTrue(this.autoScanManager.isRunning());
assertGT(switchAccess.moveForwardCount, 0);
assertEquals(1, intervalCount);
});
this.autoScanManager.setEnabled(true);
assertTrue(this.autoScanManager.isRunning());
assertEquals(1, intervalCount);
}
);
});
TEST_F('SwitchAccessAutoScanManagerTest', 'SetEnabledMultiple', function() {
this.runWithLoadedTree('data:text/html;charset=utf-8,',
function(desktop) {
assertFalse(this.autoScanManager.isRunning());
assertEquals(0, intervalCount);
this.autoScanManager.setEnabled(true);
this.autoScanManager.setEnabled(true);
this.autoScanManager.setEnabled(true);
assertTrue(this.autoScanManager.isRunning());
assertEquals(1, intervalCount);
}
);
});
TEST_F('SwitchAccessAutoScanManagerTest', 'EnableAndDisable', function() {
this.runWithLoadedTree('data:text/html;charset=utf-8,',
function(desktop) {
assertFalse(this.autoScanManager.isRunning());
assertEquals(0, intervalCount);
this.autoScanManager.setEnabled(true);
assertTrue(this.autoScanManager.isRunning());
assertEquals(1, intervalCount);
this.autoScanManager.setEnabled(false);
assertFalse(this.autoScanManager.isRunning());
assertEquals(0, intervalCount);
}
);
});
TEST_F('SwitchAccessAutoScanManagerTest', 'RestartIfRunningMultiple', function() {
this.runWithLoadedTree('data:text/html;charset=utf-8,',
function(desktop) {
assertFalse(this.autoScanManager.isRunning());
assertEquals(0, switchAccess.moveForwardCount);
assertEquals(0, intervalCount);
this.autoScanManager.setEnabled(true);
this.autoScanManager.restartIfRunning();
this.autoScanManager.restartIfRunning();
this.autoScanManager.restartIfRunning();
assertTrue(this.autoScanManager.isRunning());
assertEquals(1, intervalCount);
}
);
});
TEST_F('SwitchAccessAutoScanManagerTest', 'RestartIfRunningWhenOff', function() {
this.runWithLoadedTree('data:text/html;charset=utf-8,',
function(desktop) {
assertFalse(this.autoScanManager.isRunning());
this.autoScanManager.restartIfRunning();
assertFalse(this.autoScanManager.isRunning());
}
);
});
TEST_F('SwitchAccessAutoScanManagerTest', 'SetScanTime', function() {
this.runWithLoadedTree('data:text/html;charset=utf-8,',
function(desktop) {
assertFalse(this.autoScanManager.isRunning());
assertEquals(UNDEFINED_INTERVAL_DELAY, intervalDelay);
this.autoScanManager.setScanTime(2);
assertFalse(this.autoScanManager.isRunning());
assertEquals(2, this.autoScanManager.scanTime_);
assertEquals(UNDEFINED_INTERVAL_DELAY, intervalDelay);
this.autoScanManager.setEnabled(true);
assertTrue(this.autoScanManager.isRunning());
assertEquals(2, this.autoScanManager.scanTime_);
assertEquals(2, intervalDelay);
this.autoScanManager.setScanTime(5);
assertTrue(this.autoScanManager.isRunning());
assertEquals(5, this.autoScanManager.scanTime_);
assertEquals(5, intervalDelay);
}
);
});
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @implements {SwitchAccessInterface}
*/
function FakeSwitchAccess() {
this.moveToNextCount = 0;
this.getNumberPref = function(key) {
if (key === 'autoScanTime')
return 1;
};
this.getBooleanPref = function(key) {
if (key === 'enableAutoScan')
return false;
};
};
FakeSwitchAccess.prototype = {
/** @override */
moveForward: function() {
this.moveToNextCount += 1;
},
};
/**
* Test fixture for auto_scan_manager.js.
* @constructor
* @extends {testing.Test}
*/
function AutoScanManagerUnitTest() {
testing.Test.call(this);
};
AutoScanManagerUnitTest.prototype = {
__proto__: testing.Test.prototype,
/** @override */
extraLibraries: [
'auto_scan_manager.js',
],
/** @override */
isAsync: true,
/** @override */
browsePreload: DUMMY_URL,
/** @override */
setUp: function() {
// Use intervalCount and intervalDelay to check how many intervals are
// currently running (should be 1 at most) and what the current delay is.
window.intervalCount = 0;
window.intervalDelay = undefined;
window.realSetInterval = window.setInterval;
window.realClearInterval = window.clearInterval;
window.setInterval = function(func, delay) {
window.intervalCount += 1;
window.intervalDelay = delay;
// Set the actual delay to 1 ms to speed up the test.
return window.realSetInterval(func, 1);
};
window.clearInterval = function(intervalID) {
if (intervalID)
window.intervalCount -= 1;
window.realClearInterval(intervalID);
};
}
};
TEST_F('AutoScanManagerUnitTest', 'SetEnabled', function() {
let switchAccess = new FakeSwitchAccess();
let autoScanManager = new AutoScanManager(switchAccess);
assertFalse(autoScanManager.isRunning());
assertEquals(0, switchAccess.moveToNextCount);
assertEquals(0, window.intervalCount);
autoScanManager.setEnabled(true);
window.setTimeout(function() {
assertTrue(autoScanManager.isRunning());
assertGT(switchAccess.moveToNextCount, 1);
assertEquals(1, window.intervalCount);
testDone();
}, 10);
});
TEST_F('AutoScanManagerUnitTest', 'EnableMultiple', function() {
let switchAccess = new FakeSwitchAccess();
let autoScanManager = new AutoScanManager(switchAccess);
assertFalse(autoScanManager.isRunning());
assertEquals(0, switchAccess.moveToNextCount);
assertEquals(0, window.intervalCount);
autoScanManager.setEnabled(true);
autoScanManager.setEnabled(true);
autoScanManager.setEnabled(true);
window.setTimeout(function() {
assertTrue(autoScanManager.isRunning());
assertGT(switchAccess.moveToNextCount, 1);
assertEquals(1, window.intervalCount);
testDone();
}, 10);
});
TEST_F('AutoScanManagerUnitTest', 'EnableAndDisable', function() {
let switchAccess = new FakeSwitchAccess();
let autoScanManager = new AutoScanManager(switchAccess);
assertFalse(autoScanManager.isRunning());
autoScanManager.setEnabled(true);
assertTrue(autoScanManager.isRunning());
autoScanManager.setEnabled(false);
assertFalse(autoScanManager.isRunning());
testDone();
});
TEST_F('AutoScanManagerUnitTest', 'RestartMultiple', function() {
let switchAccess = new FakeSwitchAccess();
let autoScanManager = new AutoScanManager(switchAccess);
assertFalse(autoScanManager.isRunning());
assertEquals(0, switchAccess.moveToNextCount);
assertEquals(0, window.intervalCount);
autoScanManager.setEnabled(true);
autoScanManager.restartIfRunning();
autoScanManager.restartIfRunning();
autoScanManager.restartIfRunning();
window.setTimeout(function() {
assertTrue(autoScanManager.isRunning());
assertGT(switchAccess.moveToNextCount, 1);
assertEquals(1, window.intervalCount);
testDone();
}, 10);
});
TEST_F('AutoScanManagerUnitTest', 'RestartWhenOff', function() {
let switchAccess = new FakeSwitchAccess();
let autoScanManager = new AutoScanManager(switchAccess);
assertFalse(autoScanManager.isRunning());
autoScanManager.restartIfRunning();
assertFalse(autoScanManager.isRunning());
testDone();
});
TEST_F('AutoScanManagerUnitTest', 'SetScanTime', function() {
let switchAccess = new FakeSwitchAccess();
let autoScanManager = new AutoScanManager(switchAccess);
assertFalse(autoScanManager.isRunning());
assertEquals(1, autoScanManager.scanTime_);
assertEquals(undefined, window.intervalDelay);
autoScanManager.setScanTime(2);
assertFalse(autoScanManager.isRunning());
assertEquals(2, autoScanManager.scanTime_);
assertEquals(undefined, window.intervalDelay);
autoScanManager.setEnabled(true);
assertTrue(autoScanManager.isRunning());
assertEquals(2, autoScanManager.scanTime_);
assertEquals(2, window.intervalDelay);
autoScanManager.setScanTime(5);
assertTrue(autoScanManager.isRunning());
assertEquals(5, autoScanManager.scanTime_);
assertEquals(5, window.intervalDelay);
testDone();
});
...@@ -41,6 +41,12 @@ class SwitchAccess { ...@@ -41,6 +41,12 @@ class SwitchAccess {
*/ */
this.navigationManager_ = null; this.navigationManager_ = null;
/**
* Callback for testing use only.
* @private {?function()}
*/
this.onMoveForwardForTesting_ = null;
this.init_(); this.init_();
} }
...@@ -78,6 +84,7 @@ class SwitchAccess { ...@@ -78,6 +84,7 @@ class SwitchAccess {
moveForward() { moveForward() {
if (this.navigationManager_) if (this.navigationManager_)
this.navigationManager_.moveForward(); this.navigationManager_.moveForward();
this.onMoveForwardForTesting_ && this.onMoveForwardForTesting_();
} }
/** /**
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
GEN_INCLUDE(['../chromevox/testing/callback_helper.js']);
/**
* Base class for browser tests for Switch Access.
* @constructor
*/
function SwitchAccessE2ETest() {
this.callbackHelper_ = new CallbackHelper(this);
}
SwitchAccessE2ETest.prototype = {
__proto__: testing.Test.prototype,
/**
* @override
* No UI in the background context.
*/
runAccessibilityChecks: false,
/** @override */
isAsync: true,
/** @override */
browsePreload: null,
/** @override */
testGenCppIncludes: function() {
GEN_BLOCK(function() { /*!
#include "ash/accessibility/accessibility_delegate.h"
#include "ash/shell.h"
#include "base/bind.h"
#include "base/callback.h"
#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
#include "chrome/common/extensions/extension_constants.h"
#include "ui/accessibility/accessibility_switches.h"
#include "ui/keyboard/keyboard_util.h"
*/ });
},
/** @override */
testGenPreamble: function() {
GEN_BLOCK(function() { /*!
//keyboard::SetRequestedKeyboardState(keyboard::KEYBOARD_STATE_ENABLED);
//ash::Shell::Get()->CreateKeyboard();
base::Closure load_cb =
base::Bind(&chromeos::AccessibilityManager::SetSwitchAccessEnabled,
base::Unretained(chromeos::AccessibilityManager::Get()),
true);
base::CommandLine::ForCurrentProcess()->AppendSwitch(
::switches::kEnableExperimentalAccessibilityFeatures);
chromeos::AccessibilityManager::Get()->SetSwitchAccessEnabled(true);
WaitForExtension(extension_misc::kSwitchAccessExtensionId, load_cb);
*/ });
},
/**
* Creates a callback that optionally calls {@code opt_callback} when
* called. If this method is called one or more times, then
* {@code testDone()} will be called when all callbacks have been called.
* @param {Function=} opt_callback Wrapped callback that will have its this
* reference bound to the test fixture.
* @return {Function}
*/
newCallback: function(opt_callback) {
return this.callbackHelper_.wrap(opt_callback);
},
/**
* From chromevox_next_e2e_test_base.js
* Gets the desktop from the automation API and Launches a new tab with
* the given document, and runs |callback| with the desktop when a load
* complete fires on the created tab.
* Arranges to call |testDone()| after |callback| returns.
* NOTE: Callbacks created inside |callback| must be wrapped with
* |this.newCallback| if passed to asynchonous calls. Otherwise, the test
* will be finished prematurely.
* @param {string} url Url to load and wait for.
* @param {function(chrome.automation.AutomationNode)} callback Called with
* the desktop node once the document is ready.
*/
runWithLoadedTree: function(url, callback) {
callback = this.newCallback(callback);
chrome.automation.getDesktop(function(desktopRootNode) {
var createParams = {active: true, url: url};
chrome.tabs.create(createParams, function(unused_tab) {
chrome.automation.getTree(function(returnedRootNode) {
rootNode = returnedRootNode;
if (rootNode.docLoaded) {
callback && callback(desktopRootNode);
callback = null;
return;
}
rootNode.addEventListener('loadComplete', function(evt) {
if (evt.target.root.url != url)
return;
callback && callback(desktopRootNode);
callback = null;
});
});
});
}.bind(this));
},
};
...@@ -185,8 +185,6 @@ const SwitchAccessPredicate = { ...@@ -185,8 +185,6 @@ const SwitchAccessPredicate = {
} }
// Check various indicators that the node is actionable. // Check various indicators that the node is actionable.
// TODO(zhelfins): Update tests to reflect this updated behavior.
if (defaultActionVerb && defaultActionVerb !== 'none' && if (defaultActionVerb && defaultActionVerb !== 'none' &&
defaultActionVerb !== DefaultActionVerb.CLICK_ANCESTOR) defaultActionVerb !== DefaultActionVerb.CLICK_ANCESTOR)
return true; return true;
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
GEN_INCLUDE(['switch_access_e2e_test_base.js']);
/**
* @constructor
* @extends {SwitchAccessE2ETest}
*/
function SwitchAccessPredicateTest() {
SwitchAccessE2ETest.call(this);
}
SwitchAccessPredicateTest.prototype = {
__proto__: SwitchAccessE2ETest.prototype,
setDesktop: function(desktop) {
this.desktop = desktop;
},
getNodeByName: function(name) {
assertTrue(this.desktop != undefined);
const node = new AutomationTreeWalker(this.desktop, constants.Dir.FORWARD,
{ visit:
function(node) { return node.name === this.name; }.bind({name})
}).next().node;
assertTrue(node != null);
return node;
},
getNodesForRole: function(role) {
return new AutomationTreeWalker(this.desktop, constants.Dir.FORWARD,
{ visit: (node) => node.role === role });
}
};
function fakeLoc(x) {
return {left: x, top: x, width: x, height: x};
}
// This page has a 1:1 correlation between DOM nodes and accessibility nodes.
function testWebsite() {
return 'data:text/html;charset=utf-8,' +
'<div aria-label="upper1">' +
'<div aria-label="lower1">' +
'<button>leaf1</button>' +
'<p aria-label="leaf2">leaf2</p>' +
'<button>leaf3</button>' +
'</div><div aria-label="lower2">' +
'<p aria-label="leaf4">leaf4</p>' +
'<button>leaf5</button>' +
'</div>' +
'</div><div aria-label="upper2" role="button">' +
'<div aria-label="lower3" >' +
'<p aria-label="leaf6">leaf6</p>' +
'<p aria-label="leaf7">leaf7</p>';
}
function getTree(desktop) {
const root = new AutomationTreeWalker(desktop, constants.Dir.FORWARD,
{ visit: (node) =>
node.role === chrome.automation.RoleType.ROOT_WEB_AREA &&
node.firstChild && node.firstChild.name === "upper1"
}
).next().node;
assertTrue(root != null);
const upper1 = root.firstChild;
assertTrue(upper1 && upper1.name === "upper1");
const upper2 = upper1.nextSibling;
assertTrue(upper2 && upper2.name === "upper2");
const lower1 = upper1.firstChild;
assertTrue(lower1 && lower1.name === "lower1");
const lower2 = lower1.nextSibling;
assertTrue(lower2 && lower2.name === "lower2");
const lower3 = upper2.firstChild;
assertTrue(lower3 && lower3.name === "lower3");
const leaf1 = lower1.firstChild;
assertTrue(leaf1 && leaf1.name === "leaf1");
const leaf2 = leaf1.nextSibling;
assertTrue(leaf2 && leaf2.name === "leaf2");
const leaf3 = leaf2.nextSibling;
assertTrue(leaf3 && leaf3.name === "leaf3");
const leaf4 = lower2.firstChild;
assertTrue(leaf4 && leaf4.name === "leaf4");
const leaf5 = leaf4.nextSibling;
assertTrue(leaf5 && leaf5.name === "leaf5");
const leaf6 = lower3.firstChild;
assertTrue(leaf6 && leaf6.name === "leaf6");
const leaf7 = leaf6.nextSibling;
assertTrue(leaf7 && leaf7.name === "leaf7");
return { root, upper1, upper2, lower1, lower2, lower3, leaf1, leaf2, leaf3,
leaf4, leaf5, leaf6, leaf7 };
}
TEST_F('SwitchAccessPredicateTest', 'IsSubtreeLeaf', function() {
this.runWithLoadedTree(testWebsite(),
function(desktop) {
const t = getTree(desktop);
assertTrue(SwitchAccessPredicate.isSubtreeLeaf(t.root, t.root));
assertTrue(SwitchAccessPredicate.isSubtreeLeaf(t.upper1, t.root));
assertTrue(SwitchAccessPredicate.isSubtreeLeaf(t.upper2, t.root));
assertTrue(SwitchAccessPredicate.isSubtreeLeaf(t.lower1, t.upper1));
assertFalse(SwitchAccessPredicate.isSubtreeLeaf(t.lower2, t.upper1));
assertFalse(SwitchAccessPredicate.isSubtreeLeaf(t.lower3, t.root));
assertTrue(SwitchAccessPredicate.isSubtreeLeaf(t.leaf1, t.lower1));
assertFalse(SwitchAccessPredicate.isSubtreeLeaf(t.leaf2, t.lower1));
assertTrue(SwitchAccessPredicate.isSubtreeLeaf(t.leaf3, t.lower1));
assertFalse(SwitchAccessPredicate.isSubtreeLeaf(t.leaf4, t.upper1));
assertTrue(SwitchAccessPredicate.isSubtreeLeaf(t.leaf5, t.upper1));
assertFalse(SwitchAccessPredicate.isSubtreeLeaf(t.leaf6, t.lower3));
assertFalse(SwitchAccessPredicate.isSubtreeLeaf(t.leaf7, t.lower3));
}
);
});
TEST_F('SwitchAccessPredicateTest', 'IsGroup', function() {
this.runWithLoadedTree(testWebsite(),
function(desktop) {
const t = getTree(desktop);
assertTrue(SwitchAccessPredicate.isGroup(t.root, t.root));
assertTrue(SwitchAccessPredicate.isGroup(t.upper1, t.root));
assertFalse(SwitchAccessPredicate.isGroup(t.upper2, t.root));
assertTrue(SwitchAccessPredicate.isGroup(t.lower1, t.upper1));
assertFalse(SwitchAccessPredicate.isGroup(t.lower2, t.upper1));
assertFalse(SwitchAccessPredicate.isGroup(t.lower3, t.root));
assertFalse(SwitchAccessPredicate.isGroup(t.leaf1, t.lower1));
assertFalse(SwitchAccessPredicate.isGroup(t.leaf2, t.lower1));
assertFalse(SwitchAccessPredicate.isGroup(t.leaf3, t.lower1));
assertFalse(SwitchAccessPredicate.isGroup(t.leaf4, t.upper1));
assertFalse(SwitchAccessPredicate.isGroup(t.leaf5, t.upper1));
assertFalse(SwitchAccessPredicate.isGroup(t.leaf6, t.lower3));
assertFalse(SwitchAccessPredicate.isGroup(t.leaf7, t.lower3));
}
);
});
TEST_F('SwitchAccessPredicateTest', 'IsInterestingSubtree', function() {
this.runWithLoadedTree(testWebsite(),
function(desktop) {
const t = getTree(desktop);
assertTrue(SwitchAccessPredicate.isInterestingSubtree(t.root));
assertTrue(SwitchAccessPredicate.isInterestingSubtree(t.upper1));
assertTrue(SwitchAccessPredicate.isInterestingSubtree(t.upper2));
assertTrue(SwitchAccessPredicate.isInterestingSubtree(t.lower1));
assertTrue(SwitchAccessPredicate.isInterestingSubtree(t.lower2));
assertFalse(SwitchAccessPredicate.isInterestingSubtree(t.lower3));
assertTrue(SwitchAccessPredicate.isInterestingSubtree(t.leaf1));
assertFalse(SwitchAccessPredicate.isInterestingSubtree(t.leaf2));
assertTrue(SwitchAccessPredicate.isInterestingSubtree(t.leaf3));
assertFalse(SwitchAccessPredicate.isInterestingSubtree(t.leaf4));
assertTrue(SwitchAccessPredicate.isInterestingSubtree(t.leaf5));
assertFalse(SwitchAccessPredicate.isInterestingSubtree(t.leaf6));
assertFalse(SwitchAccessPredicate.isInterestingSubtree(t.leaf7));
}
);
});
TEST_F('SwitchAccessPredicateTest', 'IsActionable', function() {
const treeString =
'<button style="position:absolute; top:-100px;">button1</button>' +
'<button disabled>button2</button>' +
'<a href="https://www.google.com/" aria-label="link1">link1</a>' +
'<input type="text" aria-label="input1">input1</input>' +
'<button>button3</button>' +
'<div aria-label="div1"><p>p1</p></div>'
this.runWithLoadedTree('data:text/html;charset=utf-8,' + treeString,
function(desktop) {
this.setDesktop(desktop);
// Objects that are offscreen should not be actionable.
const button1 = this.getNodeByName('button1');
assertFalse(SwitchAccessPredicate.isActionable(button1));
// Disabled objects are not actionable.
const button2 = this.getNodeByName('button2');
assertFalse(SwitchAccessPredicate.isActionable(button2));
// Root web areas are not directly actionable.
const treeWalker = this.getNodesForRole(
chrome.automation.RoleType.ROOT_WEB_AREA);
while (treeWalker.node) {
assertFalse(SwitchAccessPredicate.isActionable(treeWalker.node));
treeWalker.next();
}
// Links are considered actionable.
const link1 = this.getNodeByName('link1');
assertTrue(SwitchAccessPredicate.isActionable(link1));
// Inputs are also considered actionable.
const input1 = this.getNodeByName('input1');
assertTrue(SwitchAccessPredicate.isActionable(input1));
// Buttons are generally actionable.
const button3 = this.getNodeByName('button3');
assertTrue(SwitchAccessPredicate.isActionable(button3));
// Divs are not generally actionable.
const div1 = this.getNodeByName('div1');
assertFalse(SwitchAccessPredicate.isActionable(div1));
// Static text is not actionable.
const p1 = this.getNodeByName('p1');
assertFalse(SwitchAccessPredicate.isActionable(p1));
}
);
});
TEST_F('SwitchAccessPredicateTest', 'LeafPredicate', function() {
this.runWithLoadedTree(testWebsite(),
function(desktop) {
const t = getTree(desktop);
// Start with root as scope
let leaf = SwitchAccessPredicate.leaf(t.root);
assertFalse(leaf(t.root));
assertTrue(leaf(t.upper1));
assertTrue(leaf(t.upper2));
// Set upper1 as scope
leaf = SwitchAccessPredicate.leaf(t.upper1);
assertFalse(leaf(t.upper1));
assertTrue(leaf(t.lower1));
assertTrue(leaf(t.leaf4));
assertTrue(leaf(t.leaf5));
// Set lower1 as scope
leaf = SwitchAccessPredicate.leaf(t.lower1);
assertFalse(leaf(t.lower1));
assertTrue(leaf(t.leaf1));
assertTrue(leaf(t.leaf2));
assertTrue(leaf(t.leaf3));
}
);
});
TEST_F('SwitchAccessPredicateTest', 'RootPredicate', function() {
this.runWithLoadedTree(testWebsite(),
function(desktop) {
const t = getTree(desktop);
// Start with root as scope
let root = SwitchAccessPredicate.root(t.root);
assertTrue(root(t.root));
assertFalse(root(t.upper1));
assertFalse(root(t.upper2));
// Set upper1 as scope
root = SwitchAccessPredicate.root(t.upper1);
assertTrue(root(t.upper1));
assertFalse(root(t.lower1));
assertFalse(root(t.lower2));
// Set lower1 as scope
root = SwitchAccessPredicate.root(t.lower1);
assertTrue(root(t.lower1));
assertFalse(root(t.leaf1));
assertFalse(root(t.leaf2));
assertFalse(root(t.leaf3));
}
);
});
TEST_F('SwitchAccessPredicateTest', 'VisitPredicate', function() {
this.runWithLoadedTree(testWebsite(),
function(desktop) {
const t = getTree(desktop);
// Start with root as scope
let visit = SwitchAccessPredicate.visit(t.root);
assertTrue(visit(t.root));
assertTrue(visit(t.upper1));
assertTrue(visit(t.upper2));
// Set upper1 as scope
visit = SwitchAccessPredicate.visit(t.upper1);
assertTrue(visit(t.upper1));
assertTrue(visit(t.lower1));
assertFalse(visit(t.lower2));
assertFalse(visit(t.leaf4));
assertTrue(visit(t.leaf5));
// Set lower1 as scope
visit = SwitchAccessPredicate.visit(t.lower1);
assertTrue(visit(t.lower1));
assertTrue(visit(t.leaf1));
assertFalse(visit(t.leaf2));
assertTrue(visit(t.leaf3));
// An uninteresting subtree should return false, regardless of scope
assertFalse(visit(t.lower3));
assertFalse(visit(t.leaf6));
assertFalse(visit(t.leaf7));
}
);
});
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* Test fixture for switch_access_predicate.js.
* @constructor
* @extends {testing.Test}
*/
function SwitchAccessPredicateUnitTest () {
testing.Test.call(this);
};
SwitchAccessPredicateUnitTest.prototype = {
__proto__: testing.Test.prototype,
/** @override */
extraLibraries: [
'switch_access_predicate.js',
'test_support.js'
],
/** @override */
browsePreload: DUMMY_URL,
/** @override */
setUp: function() {
chrome.automation = {
RoleType: {
CLIENT: 'client', DESKTOP: 'desktop', ROOT_WEB_AREA: 'rootWebArea',
TAB: 'tab', TAB_LIST: 'tabList', WEB_VIEW: 'webView'
},
StateType: {FOCUSABLE: 'focusable', OFFSCREEN: 'offscreen'}
};
},
fakeLoc: function(x) {
return {left: x, top: x, width: x, height: x};
},
getSampleTree: function() {
// - = interesting, (g) = group
// root (g)
// upper1 (g)
// lower1 (g)
// leaf1 -
// leaf2
// leaf3 -
// lower2
// leaf4
// leaf5 -
// upper2 -
// lower3
// leaf6
// leaf7
let root = {location: this.fakeLoc(0), state: {}};
let upper1 = {location: this.fakeLoc(1), state: {}};
let upper2 = {location: this.fakeLoc(2), state: {focusable: true}};
let lower1 = {location: this.fakeLoc(3), state: {}};
let lower2 = {location: this.fakeLoc(4), state: {}};
let lower3 = {location: this.fakeLoc(5), state: {}};
let leaf1 = {location: this.fakeLoc(6), state: {focusable: true}};
let leaf2 = {location: this.fakeLoc(7), state: {}};
let leaf3 = {location: this.fakeLoc(8), state: {focusable: true}};
let leaf4 = {location: this.fakeLoc(9), state: {}};
let leaf5 = {location: this.fakeLoc(10), state: {focusable: true}};
let leaf6 = {location: this.fakeLoc(11), state: {}};
let leaf7 = {location: this.fakeLoc(12), state: {}};
let ts = new TestSupport();
ts.setChildren(root, [upper1, upper2]);
ts.setChildren(upper1, [lower1, lower2]);
ts.setChildren(upper2, [lower3]);
ts.setChildren(lower1, [leaf1, leaf2, leaf3]);
ts.setChildren(lower2, [leaf4, leaf5]);
ts.setChildren(lower3, [leaf6, leaf7]);
return {
root: root,
upper1: upper1,
upper2: upper2,
lower1: lower1,
lower2: lower2,
lower3: lower3,
leaf1: leaf1,
leaf2: leaf2,
leaf3: leaf3,
leaf4: leaf4,
leaf5: leaf5,
leaf6: leaf6,
leaf7: leaf7,
};
},
};
TEST_F('SwitchAccessPredicateUnitTest', 'IsSubtreeLeaf', function() {
let t = this.getSampleTree();
// Make t.leaf6 and t.leaf7 interesting. t.lower3 becomes a group.
t.leaf6.state = {focusable: true};
t.leaf7.state = {focusable: true};
assertTrue(SwitchAccessPredicate.isSubtreeLeaf(t.root, t.root));
assertTrue(SwitchAccessPredicate.isSubtreeLeaf(t.upper1, t.root));
assertTrue(SwitchAccessPredicate.isSubtreeLeaf(t.upper2, t.root));
assertTrue(SwitchAccessPredicate.isSubtreeLeaf(t.lower1, t.upper1));
assertFalse(SwitchAccessPredicate.isSubtreeLeaf(t.lower2, t.upper1));
assertTrue(SwitchAccessPredicate.isSubtreeLeaf(t.lower3, t.root));
assertTrue(SwitchAccessPredicate.isSubtreeLeaf(t.leaf1, t.lower1));
assertFalse(SwitchAccessPredicate.isSubtreeLeaf(t.leaf2, t.lower1));
assertTrue(SwitchAccessPredicate.isSubtreeLeaf(t.leaf3, t.lower1));
assertFalse(SwitchAccessPredicate.isSubtreeLeaf(t.leaf4, t.upper1));
assertTrue(SwitchAccessPredicate.isSubtreeLeaf(t.leaf5, t.upper1));
assertTrue(SwitchAccessPredicate.isSubtreeLeaf(t.leaf6, t.lower3));
assertTrue(SwitchAccessPredicate.isSubtreeLeaf(t.leaf7, t.lower3));
});
TEST_F('SwitchAccessPredicateUnitTest', 'IsGroup', function() {
let t = this.getSampleTree();
// Make t.leaf6 and t.leaf7 interesting. t.lower3 becomes a group.
t.leaf6.state = {focusable: true};
t.leaf7.state = {focusable: true};
assertTrue(SwitchAccessPredicate.isGroup(t.root, t.root));
assertTrue(SwitchAccessPredicate.isGroup(t.upper1, t.root));
assertFalse(SwitchAccessPredicate.isGroup(t.upper2, t.root));
assertTrue(SwitchAccessPredicate.isGroup(t.lower1, t.upper1));
assertFalse(SwitchAccessPredicate.isGroup(t.lower2, t.upper1));
assertTrue(SwitchAccessPredicate.isGroup(t.lower3, t.root));
assertFalse(SwitchAccessPredicate.isGroup(t.leaf1, t.lower1));
assertFalse(SwitchAccessPredicate.isGroup(t.leaf2, t.lower1));
assertFalse(SwitchAccessPredicate.isGroup(t.leaf3, t.lower1));
assertFalse(SwitchAccessPredicate.isGroup(t.leaf4, t.upper1));
assertFalse(SwitchAccessPredicate.isGroup(t.leaf5, t.upper1));
assertFalse(SwitchAccessPredicate.isGroup(t.leaf6, t.lower3));
assertFalse(SwitchAccessPredicate.isGroup(t.leaf7, t.lower3));
// Set location of t.upper1 to equal location of t.root
t.upper1.location = this.fakeLoc(0);
assertFalse(SwitchAccessPredicate.isGroup(t.upper1, t.root));
});
TEST_F('SwitchAccessPredicateUnitTest', 'IsInterestingSubtree', function() {
let t = this.getSampleTree();
assertTrue(SwitchAccessPredicate.isInterestingSubtree(t.root));
assertTrue(SwitchAccessPredicate.isInterestingSubtree(t.upper1));
assertTrue(SwitchAccessPredicate.isInterestingSubtree(t.upper2));
assertTrue(SwitchAccessPredicate.isInterestingSubtree(t.lower1));
assertTrue(SwitchAccessPredicate.isInterestingSubtree(t.lower2));
assertFalse(SwitchAccessPredicate.isInterestingSubtree(t.lower3));
assertTrue(SwitchAccessPredicate.isInterestingSubtree(t.leaf1));
assertFalse(SwitchAccessPredicate.isInterestingSubtree(t.leaf2));
assertTrue(SwitchAccessPredicate.isInterestingSubtree(t.leaf3));
assertFalse(SwitchAccessPredicate.isInterestingSubtree(t.leaf4));
assertTrue(SwitchAccessPredicate.isInterestingSubtree(t.leaf5));
assertFalse(SwitchAccessPredicate.isInterestingSubtree(t.leaf6));
assertFalse(SwitchAccessPredicate.isInterestingSubtree(t.leaf7));
});
TEST_F('SwitchAccessPredicateUnitTest', 'IsInteresting', function() {
// Testing focusable.
let loc1 = {left: 0, top: 0, width: 0, height: 0};
let node1 = {location: loc1, state: {}};
let node2 = {location: loc1, state: {focusable: false}};
let node3 = {location: loc1, state: {focusable: true}};
assertFalse(SwitchAccessPredicate.isActionable(node1));
assertFalse(SwitchAccessPredicate.isActionable(node2));
assertTrue(SwitchAccessPredicate.isActionable(node3));
// Testing onscreen.
let loc2 = {left: -1, top: 0, width: 0, height: 0};
let loc3 = {left: 0, top: -1, width: 0, height: 0};
let node4 = {location: loc2, state: {focusable: true}};
let node5 = {location: loc3, state: {focusable: true}};
let node6 = {location: loc1, state: {focusable: true, offscreen: true}}
assertFalse(SwitchAccessPredicate.isActionable(node4));
assertFalse(SwitchAccessPredicate.isActionable(node5));
assertFalse(SwitchAccessPredicate.isActionable(node6));
// Testing if tab.
let node7 = {location: loc1, role: 'desktop', state: {}};
let node8 = {location: loc1, role: 'tabList', state: {}};
let node9 =
{location: loc1, parent: node8, root: node7, role: 'tab', state: {}};
assertFalse(SwitchAccessPredicate.isActionable(node7));
assertFalse(SwitchAccessPredicate.isActionable(node8));
assertTrue(SwitchAccessPredicate.isActionable(node9));
// Testing if webView or rootWebArea.
let node10 = {location: loc1, role: 'webView', state: {focusable: true}};
let node11 = {location: loc1, role: 'rootWebArea', state: {focusable: true}};
assertFalse(SwitchAccessPredicate.isActionable(node10));
assertFalse(SwitchAccessPredicate.isActionable(node11));
});
TEST_F('SwitchAccessPredicateUnitTest', 'LeafPredicate', function() {
let t = this.getSampleTree();
// Start with root as scope
let leaf = SwitchAccessPredicate.leaf(t.root);
assertFalse(leaf(t.root));
assertTrue(leaf(t.upper1));
assertTrue(leaf(t.upper2));
// upper 1 as scope
leaf = SwitchAccessPredicate.leaf(t.upper1);
assertFalse(leaf(t.upper1));
assertTrue(leaf(t.lower1));
assertTrue(leaf(t.leaf4));
assertTrue(leaf(t.leaf5));
// lower 1 as scope
leaf = SwitchAccessPredicate.leaf(t.lower1);
assertFalse(leaf(t.lower1));
assertTrue(leaf(t.leaf1));
assertTrue(leaf(t.leaf2));
assertTrue(leaf(t.leaf3));
});
TEST_F('SwitchAccessPredicateUnitTest', 'RootPredicate', function() {
let t = this.getSampleTree();
// Start with root as scope
let root = SwitchAccessPredicate.root(t.root);
assertTrue(root(t.root));
assertFalse(root(t.upper1));
assertFalse(root(t.upper2));
// upper 1 as scope
root = SwitchAccessPredicate.root(t.upper1);
assertTrue(root(t.upper1));
assertFalse(root(t.lower1));
assertFalse(root(t.lower2));
// lower 1 as scope
root = SwitchAccessPredicate.root(t.lower1);
assertTrue(root(t.lower1));
assertFalse(root(t.leaf1));
assertFalse(root(t.leaf2));
assertFalse(root(t.leaf3));
});
TEST_F('SwitchAccessPredicateUnitTest', 'VisitPredicate', function() {
let t = this.getSampleTree();
// root as scope
let visit = SwitchAccessPredicate.visit(t.root);
assertTrue(visit(t.root));
assertTrue(visit(t.upper1));
assertTrue(visit(t.upper2));
// upper1 as scope
visit = SwitchAccessPredicate.visit(t.upper1);
assertTrue(visit(t.upper1));
assertTrue(visit(t.lower1));
assertFalse(visit(t.lower2));
assertFalse(visit(t.leaf4));
assertTrue(visit(t.leaf5));
// lower1 as scope
visit = SwitchAccessPredicate.visit(t.lower1);
assertTrue(visit(t.lower1));
assertTrue(visit(t.leaf1));
assertFalse(visit(t.leaf2));
assertTrue(visit(t.leaf3));
// An uninteresting subtree should return false, regardless of scope
assertFalse(visit(t.lower3));
assertFalse(visit(t.leaf6));
assertFalse(visit(t.leaf7));
});
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const TestSupport = {
/**
* Connect |parent| and |children| to each other.
*
* @param {!Object} parent
* @param {Array<Object>} children
*/
setChildren: (parent, children) => {
// Connect parent to its children.
parent.children = children;
parent.firstChild = children[0];
parent.lastChild = children[children.length - 1];
for (const i = 0; i < children.length; i++) {
let child = children[i];
// Connect children to their parent.
child.parent = parent;
// Connect children to each other
if (i < children.length - 1)
child.nextSibling = children[i + 1];
if (i > 0)
child.previousSibling = children[i - 1];
}
},
};
...@@ -1850,6 +1850,7 @@ test("browser_tests") { ...@@ -1850,6 +1850,7 @@ test("browser_tests") {
"//chrome/browser/chromeos:arc_test_support", "//chrome/browser/chromeos:arc_test_support",
"//chrome/browser/resources/chromeos/chromevox:browser_tests", "//chrome/browser/resources/chromeos/chromevox:browser_tests",
"//chrome/browser/resources/chromeos/select_to_speak:browser_tests", "//chrome/browser/resources/chromeos/select_to_speak:browser_tests",
"//chrome/browser/resources/chromeos/switch_access:browser_tests",
"//chrome/services/file_util/public/cpp:browser_tests", "//chrome/services/file_util/public/cpp:browser_tests",
"//chromeos/components/drivefs:test_support", "//chromeos/components/drivefs:test_support",
"//components/arc:arc_test_support", "//components/arc:arc_test_support",
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
# ChromeVox and Select-to-Speak not yet supported. https://crbug.com/594887 # ChromeVox and Select-to-Speak not yet supported. https://crbug.com/594887
-ChromeVox* -ChromeVox*
-SelectToSpeak* -SelectToSpeak*
-SwitchAccess*
# Viz hit testing not supported with Mash https://crbug.com/879308 # Viz hit testing not supported with Mash https://crbug.com/879308
-PDFExtensionHitTestTest.MouseLeave/1 -PDFExtensionHitTestTest.MouseLeave/1
......
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