Commit fa9d3cb6 authored by David Tseng's avatar David Tseng Committed by Commit Bot

Bubble up common accessibility extension test sources into shared common directory

See go/unified-accessibility-component-extensions for additional details.

This creates a new suite, AccessibilityExtension*.*, for common tests for accessibility extensions.

Test: browser_tests --gtest_filter=AccessibilityExtension*.*
Change-Id: I578068985da3793b2bf4ce1c795a4a016b9f4c9c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2076420
Commit-Queue: David Tseng <dtseng@chromium.org>
Reviewed-by: default avatarAnastasia Helfinstein <anastasi@google.com>
Cr-Commit-Position: refs/heads/master@{#747057}
parent 4925eb8d
......@@ -96,3 +96,14 @@ manifest("switch_access_guest_manifest") {
accessibility_strings("accessibility_strings") {
out_dir = accessibility_out_dir
}
group("browser_tests") {
testonly = true
deps = [
"autoclick:browser_tests",
"chromevox:browser_tests",
"common:browser_tests",
"select_to_speak:browser_tests",
"switch_access:browser_tests",
]
}
......@@ -387,7 +387,6 @@ if (is_chromeos) {
sources = [
"background/annotation/node_identifier_test.js",
"background/annotation/user_annotation_handler_test.js",
"background/automation_util_test.js",
"background/background_test.js",
"background/braille_command_data_test.js",
"background/color_test.js",
......@@ -400,7 +399,6 @@ if (is_chromeos) {
"background/logging/log_store_test.js",
"background/output_test.js",
"background/recovery_strategy_test.js",
"background/tree_walker_test.js",
"braille/braille_table_test.js",
"braille/braille_translator_manager_test.js",
"braille/liblouis_test.js",
......
// Copyright 2014 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.
// Include test fixture.
GEN_INCLUDE(['../testing/chromevox_next_e2e_test_base.js']);
GEN_INCLUDE(['../testing/assert_additions.js']);
GEN_INCLUDE(['../testing/snippets.js']);
/**
* Test fixture for automation_util.js.
*/
ChromeVoxAutomationUtilE2ETest = class extends ChromeVoxNextE2ETest {
/** @override */
setUp() {
window.Dir = constants.Dir;
window.RoleType = chrome.automation.RoleType;
/** Filters nodes not rooted by desktop. */
function filterNonDesktopRoot(node) {
return node.root.role != RoleType.DESKTOP;
}
window.getNonDesktopAncestors = function(node) {
return AutomationUtil.getAncestors(node).filter(filterNonDesktopRoot);
};
window.getNonDesktopUniqueAncestors = function(node1, node2) {
return AutomationUtil.getUniqueAncestors(node1, node2)
.filter(filterNonDesktopRoot);
};
}
basicDoc() { /*!
<p><a href='#'></a>hello</p>
<h1><ul><li>a</ul><div role="group"><button></button></div></h1>
*/
}
secondDoc() { /*!
<html>
<head><title>Second doc</title></head>
<body><div>Second</div></body>
</html>
*/
}
iframeDoc() { /*!
<html>
<head><title>Second doc</title></head>
<body>
<iframe src="data:text/html,<p>Inside</p>"></iframe>
</body>
</html>
*/
}
};
TEST_F('ChromeVoxAutomationUtilE2ETest', 'GetAncestors', function() {
this.runWithLoadedTree(this.basicDoc, function(root) {
let expectedLength = 1;
while (root) {
const ancestors = getNonDesktopAncestors(root);
assertEquals(expectedLength++, ancestors.length);
root = root.firstChild;
}
});
});
TEST_F('ChromeVoxAutomationUtilE2ETest', 'GetUniqueAncestors', function() {
this.runWithLoadedTree(this.basicDoc, function(root) {
let leftmost = root, rightmost = root;
while (leftmost.firstChild) {
leftmost = leftmost.firstChild;
}
while (rightmost.lastChild) {
rightmost = rightmost.lastChild;
}
const leftAncestors = getNonDesktopAncestors(leftmost);
const rightAncestors = getNonDesktopAncestors(rightmost);
assertEquals(RoleType.LINK, leftmost.role);
assertEquals(RoleType.BUTTON, rightmost.role);
assertEquals(
1, AutomationUtil.getDivergence(leftAncestors, rightAncestors));
assertEquals(
-1, AutomationUtil.getDivergence(leftAncestors, leftAncestors));
const uniqueAncestorsLeft =
getNonDesktopUniqueAncestors(rightmost, leftmost);
const uniqueAncestorsRight =
getNonDesktopUniqueAncestors(leftmost, rightmost);
assertEquals(2, uniqueAncestorsLeft.length);
assertEquals(RoleType.PARAGRAPH, uniqueAncestorsLeft[0].role);
assertEquals(RoleType.LINK, uniqueAncestorsLeft[1].role);
assertEquals(3, uniqueAncestorsRight.length);
assertEquals(RoleType.HEADING, uniqueAncestorsRight[0].role);
assertEquals(RoleType.GROUP, uniqueAncestorsRight[1].role);
assertEquals(RoleType.BUTTON, uniqueAncestorsRight[2].role);
assertEquals(1, getNonDesktopUniqueAncestors(leftmost, leftmost).length);
}.bind(this));
});
TEST_F('ChromeVoxAutomationUtilE2ETest', 'GetDirection', function() {
this.runWithLoadedTree(this.basicDoc, function(root) {
let left = root, right = root;
// Same node.
assertEquals(Dir.FORWARD, AutomationUtil.getDirection(left, right));
// Ancestry.
left = left.firstChild;
// Upward movement is backward (in dfs).
assertEquals(Dir.BACKWARD, AutomationUtil.getDirection(left, right));
// Downward movement is forward.
assertEquals(Dir.FORWARD, AutomationUtil.getDirection(right, left));
// Ordered.
right = right.lastChild;
assertEquals(Dir.BACKWARD, AutomationUtil.getDirection(right, left));
assertEquals(Dir.FORWARD, AutomationUtil.getDirection(left, right));
});
});
TEST_F('ChromeVoxAutomationUtilE2ETest', 'VisitContainer', function() {
this.runWithLoadedTree(toolbarDoc, function(r) {
const pred = function(n) {
return n.role != 'rootWebArea';
};
const toolbar = AutomationUtil.findNextNode(r, 'forward', pred);
assertEquals('toolbar', toolbar.role);
const back = AutomationUtil.findNextNode(toolbar, 'forward', pred);
assertEquals('Back', back.name);
assertEquals(toolbar, AutomationUtil.findNextNode(back, 'backward', pred));
const forward = AutomationUtil.findNextNode(back, 'forward', pred);
assertEquals('Forward', forward.name);
assertEquals(back, AutomationUtil.findNextNode(forward, 'backward', pred));
});
});
TEST_F('ChromeVoxAutomationUtilE2ETest', 'HitTest', function() {
this.runWithLoadedTree(headingDoc, function(r) {
// Gets the center point of a rect.
function getCP(node) {
const loc = node.location;
return {x: loc.left + loc.width / 2, y: loc.top + loc.height / 2};
}
const [h1, h2, a] = r.findAll({role: 'inlineTextBox'});
assertEquals(h1, AutomationUtil.hitTest(r, getCP(h1)));
assertEquals(h1, AutomationUtil.hitTest(r, getCP(h1.parent)));
assertEquals(
h1.parent.parent, AutomationUtil.hitTest(r, getCP(h1.parent.parent)));
assertEquals(a, AutomationUtil.hitTest(r, getCP(a)));
assertEquals(a, AutomationUtil.hitTest(r, getCP(a.parent)));
assertEquals(
a.parent.parent, AutomationUtil.hitTest(r, getCP(a.parent.parent)));
});
});
TEST_F('ChromeVoxAutomationUtilE2ETest', 'FindLastNodeSimple', function() {
this.runWithLoadedTree(
function() { /*!
<p aria-label=" "><div aria-label="x"></div></p>
*/ },
function(r) {
assertEquals(
'x',
AutomationUtil
.findLastNode(
r,
function(n) {
return n.role == RoleType.GENERIC_CONTAINER;
})
.name);
});
});
TEST_F('ChromeVoxAutomationUtilE2ETest', 'FindLastNodeNonLeaf', function() {
this.runWithLoadedTree(
function() { /*!
<div role="button" aria-label="outer">
<div role="button" aria-label="inner">
</div>
</div>
*/ },
function(r) {
assertEquals(
'outer',
AutomationUtil
.findLastNode(
r,
function(n) {
return n.role == RoleType.BUTTON;
})
.name);
});
});
TEST_F('ChromeVoxAutomationUtilE2ETest', 'FindLastNodeLeaf', function() {
this.runWithLoadedTree(
function() { /*!
<p>start</p>
<div aria-label="outer"><div aria-label="inner"></div></div>
<p>end</p>
*/ },
function(r) {
assertEquals(
'inner',
AutomationUtil
.findLastNode(
r,
function(n) {
return n.role == RoleType.GENERIC_CONTAINER;
})
.name);
});
});
// Copyright 2015 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.
// Include test fixture.
GEN_INCLUDE([
'//chrome/browser/resources/chromeos/accessibility/chromevox/testing/chromevox_next_e2e_test_base.js'
]);
GEN_INCLUDE([
'//chrome/browser/resources/chromeos/accessibility/chromevox/testing/snippets.js'
]);
/**
* Test fixture for tree_walker.js.
*/
ChromeVoxAutomationTreeWalkerTest = class extends ChromeVoxNextE2ETest {
/** @override */
testGenCppIncludes() {
ChromeVoxE2ETest.prototype.testGenCppIncludes.call(this);
// See https://crbug.com/981953 for details.
GEN(`
#if !defined(NDEBUG)
#define MAYBE_Forward DISABLED_Forward
#define MAYBE_Backward DISABLED_Backward
#else
#define MAYBE_Forward Forward
#define MAYBE_Backward Backward
#endif
`);
}
flattenTree(node, outResult) {
outResult.push(node);
node = node.firstChild;
while (node) {
// Ensure proper parent/child links.
assertTrue(node.parent.children.some(function(c) {
return node == c;
}));
this.flattenTree(node, outResult);
node = node.nextSibling;
}
}
isAncestor(ancestor, node) {
while (node = node.parent) {
if (node === ancestor) {
return true;
}
}
return false;
}
isDescendant(descendant, node) {
return this.isAncestor(node, descendant);
}
};
TEST_F('ChromeVoxAutomationTreeWalkerTest', 'MAYBE_Forward', function() {
chrome.automation.getDesktop(this.newCallback(function(d) {
const resultList = [];
this.flattenTree(d, resultList);
let it = new AutomationTreeWalker(d, 'forward');
for (let i = 1; i < resultList.length; i++) {
assertEquals(resultList[i], it.next().node);
}
assertEquals(null, it.next().node);
for (let j = 0; j < resultList.length; j++) {
it = new AutomationTreeWalker(resultList[j], 'forward');
const start = it.node;
let cur = it.next().node;
while (cur) {
const isDescendant = this.isDescendant(cur, start);
if (it.phase == 'descendant') {
assertTrue(isDescendant);
} else if (it.phase == 'other') {
assertFalse(isDescendant);
} else {
assertNotReached();
}
cur = it.next().node;
}
}
}.bind(this)));
});
TEST_F('ChromeVoxAutomationTreeWalkerTest', 'MAYBE_Backward', function() {
chrome.automation.getDesktop(this.newCallback(function(d) {
const resultList = [];
this.flattenTree(d, resultList);
let it =
new AutomationTreeWalker(resultList[resultList.length - 1], 'backward');
for (let i = resultList.length - 2; i >= 0; i--) {
assertEquals(resultList[i], it.next().node);
}
for (let j = resultList.length - 1; j >= 0; j--) {
it = new AutomationTreeWalker(resultList[j], 'backward');
const start = it.node;
let cur = it.next().node;
while (cur) {
const isAncestor = this.isAncestor(cur, start);
if (it.phase == 'ancestor') {
assertTrue(isAncestor);
} else if (it.phase == 'other') {
assertFalse(isAncestor);
} else {
assertNotReached();
}
cur = it.next().node;
}
}
}.bind(this)));
});
TEST_F('ChromeVoxAutomationTreeWalkerTest', 'RootLeafRestriction', function() {
this.runWithLoadedTree(
`
<div role="group" aria-label="1">
<div role="group" aria-label="2">
<div role="group" aria-label="3">
<div role="group" aria-label="4"></div>
</div>
<div role="group" aria-label="5"></div>
</div>
<div role="group" aria-label="6"></div>
</div>
`,
function(r) {
const node2 = r.firstChild.firstChild;
assertEquals('2', node2.name);
// Restrict to 2's subtree and consider 3 and 5 leaves.
const leafP = function(n) {
return n.name == '3' || n.name == '5';
};
const rootP = function(n) {
return n.name == '2';
};
// Track the nodes we've visited.
let visited = '';
const visit = function(n) {
visited += n.name;
};
const restrictions = {leaf: leafP, root: rootP, visit};
let walker = new AutomationTreeWalker(node2, 'forward', restrictions);
while (walker.next().node) {
}
assertEquals('35', visited);
assertEquals(AutomationTreeWalkerPhase.OTHER, walker.phase);
// And the reverse.
// Note that walking into a root is allowed.
visited = '';
const node6 = r.lastChild.lastChild;
assertEquals('6', node6.name);
walker = new AutomationTreeWalker(node6, 'backward', restrictions);
while (walker.next().node) {
}
assertEquals('532', visited);
// Test not visiting ancestors of initial node.
const node5 = r.firstChild.firstChild.lastChild;
assertEquals('5', node5.name);
restrictions.root = function(n) {
return n.name == '1';
};
restrictions.leaf = function(n) {
return !n.firstChild;
};
visited = '';
restrictions.skipInitialAncestry = false;
walker = new AutomationTreeWalker(node5, 'backward', restrictions);
while (walker.next().node) {
}
assertEquals('4321', visited);
// 2 and 1 are ancestors; check they get skipped.
visited = '';
restrictions.skipInitialAncestry = true;
walker = new AutomationTreeWalker(node5, 'backward', restrictions);
while (walker.next().node) {
}
assertEquals('43', visited);
// We should skip node 2's subtree.
walker = new AutomationTreeWalker(
node2, 'forward', {skipInitialSubtree: true});
assertEquals(node6, walker.next().node);
});
});
TEST_F(
'ChromeVoxAutomationTreeWalkerTest', 'LeafPredicateSymmetry', function() {
this.runWithLoadedTree(toolbarDoc, function(r) {
const d = r.root.parent.root;
const forwardWalker = new AutomationTreeWalker(d, 'forward');
const forwardNodes = [];
// Get all nodes according to the walker in the forward direction.
do {
forwardNodes.push(forwardWalker.node);
} while (forwardWalker.next().node);
// Now, verify the walker moving backwards matches the forwards list.
const backwardWalker = new AutomationTreeWalker(
forwardNodes[forwardNodes.length - 1], 'backward');
do {
const next = forwardNodes.pop();
assertEquals(next, backwardWalker.node);
} while (backwardWalker.next().node);
});
});
TEST_F('ChromeVoxAutomationTreeWalkerTest', 'RootPredicateEnding', function() {
this.runWithLoadedTree(toolbarDoc, function(r) {
const backwardWalker = new AutomationTreeWalker(r.firstChild, 'backward', {
root(node) {
return node === r;
}
});
assertEquals(r, backwardWalker.next().node);
assertEquals(null, backwardWalker.next().node);
const forwardWalker =
new AutomationTreeWalker(r.firstChild.lastChild, 'forward', {
root(node) {
return node === r;
}
});
// Advance to the static text box of button contains text "Forward".
assertEquals('Forward', forwardWalker.next().node.name);
// Advance to the inline text box of button contains text "Forward".
assertEquals('Forward', forwardWalker.next().node.name);
assertEquals(null, forwardWalker.next().node);
});
});
......@@ -6,6 +6,8 @@ import("//build/config/features.gni")
import(
"//chrome/browser/resources/chromeos/accessibility/chromevox/run_jsbundler.gni")
import("//chrome/common/features.gni")
import("//chrome/test/base/js2gtest.gni")
import("//testing/test.gni")
import("//third_party/closure_compiler/compile_js.gni")
assert(is_chromeos)
......@@ -69,3 +71,52 @@ js_library("automation_util") {
"$externs_path/chrome_extensions.js",
]
}
source_set("browser_tests") {
testonly = true
assert(enable_extensions)
deps = [ ":accessibility_tests" ]
# TODO(jamescook): Figure out which of these are really necessary.
data = [
"$root_out_dir/chrome_100_percent.pak",
"$root_out_dir/chrome_200_percent.pak",
"$root_out_dir/locales/en-US.pak",
"$root_out_dir/locales/fr.pak",
"$root_out_dir/resources.pak",
"$root_out_dir/resources/chromeos/accessibility/chromevox/",
"$root_out_dir/test_data/chrome/browser/resources/chromeos/accessibility/chromevox/",
# The test uses data from the original location.
"//chrome/browser/resources/chromeos/accessibility/chromevox/",
"//chrome/browser/resources/chromeos/accessibility/common/",
"//third_party/chromevox/",
]
data += js2gtest_js_libraries
}
# Note that this suite of tests still uses ChromeVox's background page as a runtime environment. There should not be anything specific to ChromeVox within the tests themselves though.
js2gtest("accessibility_tests") {
test_type = "extension"
sources = [
"automation_util_test.js",
"tree_walker_test.js",
]
gen_include_files = [
"../chromevox/testing/assert_additions.js",
"../chromevox/testing/callback_helper.js",
"../chromevox/testing/chromevox_e2e_test_base.js",
"../chromevox/testing/chromevox_next_e2e_test_base.js",
"../chromevox/testing/mock_feedback.js",
]
# The test base classes generate C++ code with these deps.
deps = [
"//ash",
"//base",
"//chrome/browser/chromeos",
"//chrome/common",
]
defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
}
// Copyright 2014 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.
// Include test fixture.
GEN_INCLUDE([
'../chromevox/testing/chromevox_next_e2e_test_base.js',
'../chromevox/testing/assert_additions.js', '../chromevox/testing/snippets.js'
]);
/**
* Test fixture for automation_util.js.
*/
AccessibilityExtensionAutomationUtilE2ETest =
class extends ChromeVoxNextE2ETest {
/** @override */
setUp() {
window.Dir = constants.Dir;
window.RoleType = chrome.automation.RoleType;
/** Filters nodes not rooted by desktop. */
function filterNonDesktopRoot(node) {
return node.root.role != RoleType.DESKTOP;
}
window.getNonDesktopAncestors = function(node) {
return AutomationUtil.getAncestors(node).filter(filterNonDesktopRoot);
};
window.getNonDesktopUniqueAncestors = function(node1, node2) {
return AutomationUtil.getUniqueAncestors(node1, node2)
.filter(filterNonDesktopRoot);
};
}
basicDoc() { /*!
<p><a href='#'></a>hello</p>
<h1><ul><li>a</ul><div role="group"><button></button></div></h1>
*/
}
secondDoc() { /*!
<html>
<head><title>Second doc</title></head>
<body><div>Second</div></body>
</html>
*/
}
iframeDoc() { /*!
<html>
<head><title>Second doc</title></head>
<body>
<iframe src="data:text/html,<p>Inside</p>"></iframe>
</body>
</html>
*/
}
};
TEST_F(
'AccessibilityExtensionAutomationUtilE2ETest', 'GetAncestors', function() {
this.runWithLoadedTree(this.basicDoc, function(root) {
let expectedLength = 1;
while (root) {
const ancestors = getNonDesktopAncestors(root);
assertEquals(expectedLength++, ancestors.length);
root = root.firstChild;
}
});
});
TEST_F(
'AccessibilityExtensionAutomationUtilE2ETest', 'GetUniqueAncestors',
function() {
this.runWithLoadedTree(this.basicDoc, function(root) {
let leftmost = root, rightmost = root;
while (leftmost.firstChild) {
leftmost = leftmost.firstChild;
}
while (rightmost.lastChild) {
rightmost = rightmost.lastChild;
}
const leftAncestors = getNonDesktopAncestors(leftmost);
const rightAncestors = getNonDesktopAncestors(rightmost);
assertEquals(RoleType.LINK, leftmost.role);
assertEquals(RoleType.BUTTON, rightmost.role);
assertEquals(
1, AutomationUtil.getDivergence(leftAncestors, rightAncestors));
assertEquals(
-1, AutomationUtil.getDivergence(leftAncestors, leftAncestors));
const uniqueAncestorsLeft =
getNonDesktopUniqueAncestors(rightmost, leftmost);
const uniqueAncestorsRight =
getNonDesktopUniqueAncestors(leftmost, rightmost);
assertEquals(2, uniqueAncestorsLeft.length);
assertEquals(RoleType.PARAGRAPH, uniqueAncestorsLeft[0].role);
assertEquals(RoleType.LINK, uniqueAncestorsLeft[1].role);
assertEquals(3, uniqueAncestorsRight.length);
assertEquals(RoleType.HEADING, uniqueAncestorsRight[0].role);
assertEquals(RoleType.GROUP, uniqueAncestorsRight[1].role);
assertEquals(RoleType.BUTTON, uniqueAncestorsRight[2].role);
assertEquals(
1, getNonDesktopUniqueAncestors(leftmost, leftmost).length);
}.bind(this));
});
TEST_F(
'AccessibilityExtensionAutomationUtilE2ETest', 'GetDirection', function() {
this.runWithLoadedTree(this.basicDoc, function(root) {
let left = root, right = root;
// Same node.
assertEquals(Dir.FORWARD, AutomationUtil.getDirection(left, right));
// Ancestry.
left = left.firstChild;
// Upward movement is backward (in dfs).
assertEquals(Dir.BACKWARD, AutomationUtil.getDirection(left, right));
// Downward movement is forward.
assertEquals(Dir.FORWARD, AutomationUtil.getDirection(right, left));
// Ordered.
right = right.lastChild;
assertEquals(Dir.BACKWARD, AutomationUtil.getDirection(right, left));
assertEquals(Dir.FORWARD, AutomationUtil.getDirection(left, right));
});
});
TEST_F(
'AccessibilityExtensionAutomationUtilE2ETest', 'VisitContainer',
function() {
this.runWithLoadedTree(toolbarDoc, function(r) {
const pred = function(n) {
return n.role != 'rootWebArea';
};
const toolbar = AutomationUtil.findNextNode(r, 'forward', pred);
assertEquals('toolbar', toolbar.role);
const back = AutomationUtil.findNextNode(toolbar, 'forward', pred);
assertEquals('Back', back.name);
assertEquals(
toolbar, AutomationUtil.findNextNode(back, 'backward', pred));
const forward = AutomationUtil.findNextNode(back, 'forward', pred);
assertEquals('Forward', forward.name);
assertEquals(
back, AutomationUtil.findNextNode(forward, 'backward', pred));
});
});
TEST_F('AccessibilityExtensionAutomationUtilE2ETest', 'HitTest', function() {
this.runWithLoadedTree(headingDoc, function(r) {
// Gets the center point of a rect.
function getCP(node) {
const loc = node.location;
return {x: loc.left + loc.width / 2, y: loc.top + loc.height / 2};
}
const [h1, h2, a] = r.findAll({role: 'inlineTextBox'});
assertEquals(h1, AutomationUtil.hitTest(r, getCP(h1)));
assertEquals(h1, AutomationUtil.hitTest(r, getCP(h1.parent)));
assertEquals(
h1.parent.parent, AutomationUtil.hitTest(r, getCP(h1.parent.parent)));
assertEquals(a, AutomationUtil.hitTest(r, getCP(a)));
assertEquals(a, AutomationUtil.hitTest(r, getCP(a.parent)));
assertEquals(
a.parent.parent, AutomationUtil.hitTest(r, getCP(a.parent.parent)));
});
});
TEST_F(
'AccessibilityExtensionAutomationUtilE2ETest', 'FindLastNodeSimple',
function() {
this.runWithLoadedTree(
function() { /*!
<p aria-label=" "><div aria-label="x"></div></p>
*/ },
function(r) {
assertEquals(
'x',
AutomationUtil
.findLastNode(
r,
function(n) {
return n.role == RoleType.GENERIC_CONTAINER;
})
.name);
});
});
TEST_F(
'AccessibilityExtensionAutomationUtilE2ETest', 'FindLastNodeNonLeaf',
function() {
this.runWithLoadedTree(
function() { /*!
<div role="button" aria-label="outer">
<div role="button" aria-label="inner">
</div>
</div>
*/ },
function(r) {
assertEquals(
'outer',
AutomationUtil
.findLastNode(
r,
function(n) {
return n.role == RoleType.BUTTON;
})
.name);
});
});
TEST_F(
'AccessibilityExtensionAutomationUtilE2ETest', 'FindLastNodeLeaf',
function() {
this.runWithLoadedTree(
function() { /*!
<p>start</p>
<div aria-label="outer"><div aria-label="inner"></div></div>
<p>end</p>
*/ },
function(r) {
assertEquals(
'inner',
AutomationUtil
.findLastNode(
r,
function(n) {
return n.role == RoleType.GENERIC_CONTAINER;
})
.name);
});
});
// Copyright 2015 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.
// Include test fixture.
GEN_INCLUDE([
'../chromevox/testing/chromevox_next_e2e_test_base.js',
'../chromevox/testing/snippets.js'
]);
/**
* Test fixture for tree_walker.js.
*/
AccessibilityExtensionAutomationTreeWalkerTest =
class extends ChromeVoxNextE2ETest {
/** @override */
testGenCppIncludes() {
super.testGenCppIncludes.call();
// See https://crbug.com/981953 for details.
GEN(`
#if !defined(NDEBUG)
#define MAYBE_Forward DISABLED_Forward
#define MAYBE_Backward DISABLED_Backward
#else
#define MAYBE_Forward Forward
#define MAYBE_Backward Backward
#endif
`);
}
flattenTree(node, outResult) {
outResult.push(node);
node = node.firstChild;
while (node) {
// Ensure proper parent/child links.
assertTrue(node.parent.children.some(function(c) {
return node == c;
}));
this.flattenTree(node, outResult);
node = node.nextSibling;
}
}
isAncestor(ancestor, node) {
while (node = node.parent) {
if (node === ancestor) {
return true;
}
}
return false;
}
isDescendant(descendant, node) {
return this.isAncestor(node, descendant);
}
};
TEST_F(
'AccessibilityExtensionAutomationTreeWalkerTest', 'MAYBE_Forward',
function() {
chrome.automation.getDesktop(this.newCallback(function(d) {
const resultList = [];
this.flattenTree(d, resultList);
let it = new AutomationTreeWalker(d, 'forward');
for (let i = 1; i < resultList.length; i++) {
assertEquals(resultList[i], it.next().node);
}
assertEquals(null, it.next().node);
for (let j = 0; j < resultList.length; j++) {
it = new AutomationTreeWalker(resultList[j], 'forward');
const start = it.node;
let cur = it.next().node;
while (cur) {
const isDescendant = this.isDescendant(cur, start);
if (it.phase == 'descendant') {
assertTrue(isDescendant);
} else if (it.phase == 'other') {
assertFalse(isDescendant);
} else {
assertNotReached();
}
cur = it.next().node;
}
}
}.bind(this)));
});
TEST_F(
'AccessibilityExtensionAutomationTreeWalkerTest', 'MAYBE_Backward',
function() {
chrome.automation.getDesktop(this.newCallback(function(d) {
const resultList = [];
this.flattenTree(d, resultList);
let it = new AutomationTreeWalker(
resultList[resultList.length - 1], 'backward');
for (let i = resultList.length - 2; i >= 0; i--) {
assertEquals(resultList[i], it.next().node);
}
for (let j = resultList.length - 1; j >= 0; j--) {
it = new AutomationTreeWalker(resultList[j], 'backward');
const start = it.node;
let cur = it.next().node;
while (cur) {
const isAncestor = this.isAncestor(cur, start);
if (it.phase == 'ancestor') {
assertTrue(isAncestor);
} else if (it.phase == 'other') {
assertFalse(isAncestor);
} else {
assertNotReached();
}
cur = it.next().node;
}
}
}.bind(this)));
});
TEST_F(
'AccessibilityExtensionAutomationTreeWalkerTest', 'RootLeafRestriction',
function() {
this.runWithLoadedTree(
`
<div role="group" aria-label="1">
<div role="group" aria-label="2">
<div role="group" aria-label="3">
<div role="group" aria-label="4"></div>
</div>
<div role="group" aria-label="5"></div>
</div>
<div role="group" aria-label="6"></div>
</div>
`,
function(r) {
const node2 = r.firstChild.firstChild;
assertEquals('2', node2.name);
// Restrict to 2's subtree and consider 3 and 5 leaves.
const leafP = function(n) {
return n.name == '3' || n.name == '5';
};
const rootP = function(n) {
return n.name == '2';
};
// Track the nodes we've visited.
let visited = '';
const visit = function(n) {
visited += n.name;
};
const restrictions = {leaf: leafP, root: rootP, visit};
let walker =
new AutomationTreeWalker(node2, 'forward', restrictions);
while (walker.next().node) {
}
assertEquals('35', visited);
assertEquals(AutomationTreeWalkerPhase.OTHER, walker.phase);
// And the reverse.
// Note that walking into a root is allowed.
visited = '';
const node6 = r.lastChild.lastChild;
assertEquals('6', node6.name);
walker = new AutomationTreeWalker(node6, 'backward', restrictions);
while (walker.next().node) {
}
assertEquals('532', visited);
// Test not visiting ancestors of initial node.
const node5 = r.firstChild.firstChild.lastChild;
assertEquals('5', node5.name);
restrictions.root = function(n) {
return n.name == '1';
};
restrictions.leaf = function(n) {
return !n.firstChild;
};
visited = '';
restrictions.skipInitialAncestry = false;
walker = new AutomationTreeWalker(node5, 'backward', restrictions);
while (walker.next().node) {
}
assertEquals('4321', visited);
// 2 and 1 are ancestors; check they get skipped.
visited = '';
restrictions.skipInitialAncestry = true;
walker = new AutomationTreeWalker(node5, 'backward', restrictions);
while (walker.next().node) {
}
assertEquals('43', visited);
// We should skip node 2's subtree.
walker = new AutomationTreeWalker(
node2, 'forward', {skipInitialSubtree: true});
assertEquals(node6, walker.next().node);
});
});
TEST_F(
'AccessibilityExtensionAutomationTreeWalkerTest', 'LeafPredicateSymmetry',
function() {
this.runWithLoadedTree(toolbarDoc, function(r) {
const d = r.root.parent.root;
const forwardWalker = new AutomationTreeWalker(d, 'forward');
const forwardNodes = [];
// Get all nodes according to the walker in the forward direction.
do {
forwardNodes.push(forwardWalker.node);
} while (forwardWalker.next().node);
// Now, verify the walker moving backwards matches the forwards list.
const backwardWalker = new AutomationTreeWalker(
forwardNodes[forwardNodes.length - 1], 'backward');
do {
const next = forwardNodes.pop();
assertEquals(next, backwardWalker.node);
} while (backwardWalker.next().node);
});
});
TEST_F(
'AccessibilityExtensionAutomationTreeWalkerTest', 'RootPredicateEnding',
function() {
this.runWithLoadedTree(toolbarDoc, function(r) {
const backwardWalker =
new AutomationTreeWalker(r.firstChild, 'backward', {
root(node) {
return node === r;
}
});
assertEquals(r, backwardWalker.next().node);
assertEquals(null, backwardWalker.next().node);
const forwardWalker =
new AutomationTreeWalker(r.firstChild.lastChild, 'forward', {
root(node) {
return node === r;
}
});
// Advance to the static text box of button contains text "Forward".
assertEquals('Forward', forwardWalker.next().node.name);
// Advance to the inline text box of button contains text "Forward".
assertEquals('Forward', forwardWalker.next().node.name);
assertEquals(null, forwardWalker.next().node);
});
});
......@@ -1497,10 +1497,7 @@ if (!is_android) {
"//chrome/browser/chromeos:arc_test_support",
"//chrome/browser/chromeos:test_support",
"//chrome/browser/media/router:test_support",
"//chrome/browser/resources/chromeos/accessibility/autoclick:browser_tests",
"//chrome/browser/resources/chromeos/accessibility/chromevox:browser_tests",
"//chrome/browser/resources/chromeos/accessibility/select_to_speak:browser_tests",
"//chrome/browser/resources/chromeos/accessibility/switch_access:browser_tests",
"//chrome/browser/resources/chromeos/accessibility:browser_tests",
"//chrome/browser/resources/gaia_auth_host:browser_tests",
"//chrome/services/file_util/public/cpp:browser_tests",
"//chromeos:test_support",
......
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