Commit bbbb1727 authored by Anastasia Helfinstein's avatar Anastasia Helfinstein Committed by Commit Bot

[Switch Access] Update existing Javascript tests

This change adds error messages to all of the asserts in each existing
JavaScript test and updating the testing infrastructure in small ways.

Bug: 897365
Change-Id: Id83c9975d734d785524beb1370c5415ab4d0c900
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1865479
Commit-Queue: Anastasia Helfinstein <anastasi@google.com>
Reviewed-by: default avatarAkihiro Ota <akihiroota@chromium.org>
Cr-Commit-Position: refs/heads/master@{#709172}
parent 04bf7eaa
......@@ -54,109 +54,120 @@ SwitchAccessAutoScanManagerTest.prototype = {
};
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);
this.runWithLoadedTree('', (desktop) => {
assertFalse(this.autoScanManager.isRunning(),
'Auto scan manager is running prematurely');
assertEquals(0, switchAccess.moveForwardCount,
'Incorrect initialization of moveForwardCount');
assertEquals(0, intervalCount, 'Incorrect initialization of intervalCount');
switchAccess.onMoveForwardForTesting_ =
this.newCallback(function() {
assertTrue(this.autoScanManager.isRunning());
assertGT(switchAccess.moveForwardCount, 0);
assertEquals(1, intervalCount);
this.newCallback(() => {
assertTrue(this.autoScanManager.isRunning(),
'Auto scan manager has stopped running');
assertGT(switchAccess.moveForwardCount, 0,
'Switch Access has not moved forward');
assertEquals(1, intervalCount,
'The number of intervals is no longer exactly 1');
});
this.autoScanManager.setEnabled(true);
assertTrue(this.autoScanManager.isRunning());
assertEquals(1, intervalCount);
}
);
assertTrue(this.autoScanManager.isRunning(),
'Auto scan manager is not running');
assertEquals(1, intervalCount, 'There is not exactly 1 interval');
});
});
TEST_F('SwitchAccessAutoScanManagerTest', 'SetEnabledMultiple', function() {
this.runWithLoadedTree('data:text/html;charset=utf-8,',
function(desktop) {
assertFalse(this.autoScanManager.isRunning());
assertEquals(0, intervalCount);
this.runWithLoadedTree('', (desktop) => {
assertFalse(this.autoScanManager.isRunning(),
'Auto scan manager is running prematurely');
assertEquals(0, intervalCount, 'Incorrect initialization of intervalCount');
this.autoScanManager.setEnabled(true);
this.autoScanManager.setEnabled(true);
this.autoScanManager.setEnabled(true);
assertTrue(this.autoScanManager.isRunning());
assertEquals(1, intervalCount);
}
);
assertTrue(this.autoScanManager.isRunning(),
'Auto scan manager is not running');
assertEquals(1, intervalCount, 'There is not exactly 1 interval');
});
});
TEST_F('SwitchAccessAutoScanManagerTest', 'EnableAndDisable', function() {
this.runWithLoadedTree('data:text/html;charset=utf-8,',
function(desktop) {
assertFalse(this.autoScanManager.isRunning());
assertEquals(0, intervalCount);
this.runWithLoadedTree('', (desktop) => {
assertFalse(this.autoScanManager.isRunning(),
'Auto scan manager is running prematurely');
assertEquals(0, intervalCount, 'Incorrect initialization of intervalCount');
this.autoScanManager.setEnabled(true);
assertTrue(this.autoScanManager.isRunning());
assertEquals(1, intervalCount);
assertTrue(this.autoScanManager.isRunning(),
'Auto scan manager is not running');
assertEquals(1, intervalCount, 'There is not exactly 1 interval');
this.autoScanManager.setEnabled(false);
assertFalse(this.autoScanManager.isRunning());
assertEquals(0, intervalCount);
}
);
assertFalse(this.autoScanManager.isRunning(),
'Auto scan manager did not stop running');
assertEquals(0, intervalCount, 'Interval was not removed');
});
});
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.runWithLoadedTree('', (desktop) => {
assertFalse(this.autoScanManager.isRunning(),
'Auto scan manager is running prematurely');
assertEquals(0, switchAccess.moveForwardCount,
'Incorrect initialization of moveForwardCount');
assertEquals(0, intervalCount, 'Incorrect initialization of intervalCount');
this.autoScanManager.setEnabled(true);
this.autoScanManager.restartIfRunning();
this.autoScanManager.restartIfRunning();
this.autoScanManager.restartIfRunning();
assertTrue(this.autoScanManager.isRunning());
assertEquals(1, intervalCount);
}
);
assertTrue(this.autoScanManager.isRunning(),
'Auto scan manager is not running');
assertEquals(1, intervalCount, 'There is not exactly 1 interval');
});
});
TEST_F('SwitchAccessAutoScanManagerTest', 'RestartIfRunningWhenOff', function() {
this.runWithLoadedTree('data:text/html;charset=utf-8,',
function(desktop) {
assertFalse(this.autoScanManager.isRunning());
TEST_F('SwitchAccessAutoScanManagerTest', 'RestartIfRunningWhenOff', function()
{
this.runWithLoadedTree('', (desktop) => {
assertFalse(this.autoScanManager.isRunning(),
'Auto scan manager is running at start.');
this.autoScanManager.restartIfRunning();
assertFalse(this.autoScanManager.isRunning());
}
);
assertFalse(this.autoScanManager.isRunning(),
'Auto scan manager enabled by restartIfRunning');
});
});
TEST_F('SwitchAccessAutoScanManagerTest', 'SetDefaultScanTime', function() {
this.runWithLoadedTree('data:text/html;charset=utf-8,',
function(desktop) {
assertFalse(this.autoScanManager.isRunning());
assertEquals(UNDEFINED_INTERVAL_DELAY, intervalDelay);
this.runWithLoadedTree('', (desktop) => {
assertFalse(this.autoScanManager.isRunning(),
'Auto scan manager is running prematurely');
assertEquals(UNDEFINED_INTERVAL_DELAY, intervalDelay,
'Interval delay improperly initialized');
this.autoScanManager.setDefaultScanTime(2);
assertFalse(this.autoScanManager.isRunning());
assertEquals(2, this.autoScanManager.defaultScanTime_);
assertEquals(UNDEFINED_INTERVAL_DELAY, intervalDelay);
assertFalse(this.autoScanManager.isRunning(),
'Setting default scan time started auto-scanning');
assertEquals(2, this.autoScanManager.defaultScanTime_,
'Default scan time set improperly');
assertEquals(UNDEFINED_INTERVAL_DELAY, intervalDelay,
'Interval delay set prematurely');
this.autoScanManager.setEnabled(true);
assertTrue(this.autoScanManager.isRunning());
assertEquals(2, this.autoScanManager.defaultScanTime_);
assertEquals(2, intervalDelay);
assertTrue(this.autoScanManager.isRunning(), 'Auto scan did not start');
assertEquals(2, this.autoScanManager.defaultScanTime_,
'Default scan time has changed');
assertEquals(2, intervalDelay, 'Interval delay not set');
this.autoScanManager.setDefaultScanTime(5);
assertTrue(this.autoScanManager.isRunning());
assertEquals(5, this.autoScanManager.defaultScanTime_);
assertEquals(5, intervalDelay);
}
);
assertTrue(this.autoScanManager.isRunning(), 'Auto scan stopped');
assertEquals(5, this.autoScanManager.defaultScanTime_,
'Default scan time did not change when set a second time');
assertEquals(5, intervalDelay, 'Interval delay did not update');
});
});
......@@ -38,12 +38,10 @@ function currentNode() {
TEST_F('SwitchAccessNavigationManagerTest', 'SelectButton', function() {
const website =
`data:text/html;charset=utf-8,
<button id="test" aria-pressed="false">First Button</button>
<button>Second Button</button>
`<button id="test" aria-pressed=false>First Button</button>
<script>
var state = false;
var button = document.getElementById("test");
let state = false;
let button = document.getElementById("test");
button.onclick = () => {
state = !state;
button.setAttribute("aria-pressed", state);
......@@ -54,13 +52,18 @@ TEST_F('SwitchAccessNavigationManagerTest', 'SelectButton', function() {
moveToPageContents();
let node = currentNode().automationNode;
assertTrue(!!node);
assertEquals(node.name, "First Button");
assertTrue(!!node, 'Node is invalid');
assertEquals(node.name, 'First Button', 'Did not find the right node');
node.addEventListener(
chrome.automation.EventType.CHECKED_STATE_CHANGED,
this.newCallback((event) => assertEquals(node.name, event.target.name)));
this.newCallback((event) => {
assertEquals(node.name, event.target.name,
'Checked state changed on unexpected node');
}));
switchAccess.selectCurrentNode();
// The event listener is not set instantaneously. Set a timeout of 0 to
// yield to pending processes.
setTimeout(this.newCallback(switchAccess.selectCurrentNode), 0);
});
});
......@@ -28,17 +28,27 @@ TEST_F('SwitchAccessRectHelperUnitTest', 'Equals', function() {
const rect5 = {left: 0, top: 0, width: 11, height: 10};
const rect6 = {left: 0, top: 0, width: 10, height: 11};
assertTrue(RectHelper.areEqual(rect1, rect1));
assertTrue(RectHelper.areEqual(rect1, rect2));
assertTrue(RectHelper.areEqual(rect2, rect1));
assertFalse(RectHelper.areEqual(rect1, rect3));
assertFalse(RectHelper.areEqual(rect3, rect1));
assertFalse(RectHelper.areEqual(rect1, rect4));
assertFalse(RectHelper.areEqual(rect4, rect1));
assertFalse(RectHelper.areEqual(rect1, rect5));
assertFalse(RectHelper.areEqual(rect5, rect1));
assertFalse(RectHelper.areEqual(rect1, rect6));
assertFalse(RectHelper.areEqual(rect6, rect1));
assertTrue(RectHelper.areEqual(rect1, rect1), 'areEqual should be reflexive');
assertTrue(RectHelper.areEqual(rect1, rect2),
'Rect1 and Rect2 should be equal');
assertTrue(RectHelper.areEqual(rect2, rect1),
'areEqual should be symmetric (1)');
assertFalse(RectHelper.areEqual(rect1, rect3),
'rect1 and rect3 should not be equal');
assertFalse(RectHelper.areEqual(rect3, rect1),
'areEqual should be symmetric (2)');
assertFalse(RectHelper.areEqual(rect1, rect4),
'rect1 and rect4 should not be equal');
assertFalse(RectHelper.areEqual(rect4, rect1),
'areEqual should be symmetric (3)');
assertFalse(RectHelper.areEqual(rect1, rect5),
'rect1 and rect5 should not be equal');
assertFalse(RectHelper.areEqual(rect5, rect1),
'areEqual should be symmetric (4)');
assertFalse(RectHelper.areEqual(rect1, rect6),
'rect1 and rect6 should not be equal');
assertFalse(RectHelper.areEqual(rect6, rect1),
'areEqual should be symmetric (5)');
});
TEST_F('SwitchAccessRectHelperUnitTest', 'Center', function() {
......@@ -46,12 +56,12 @@ TEST_F('SwitchAccessRectHelperUnitTest', 'Center', function() {
const rect2 = {left: 10, top: 20, width: 10, height: 40};
const center1 = RectHelper.center(rect1);
assertEquals(5, center1.x);
assertEquals(5, center1.y);
assertEquals(5, center1.x, 'Center1 x should be 5');
assertEquals(5, center1.y, 'Center1 y should be 5');
const center2 = RectHelper.center(rect2);
assertEquals(15, center2.x);
assertEquals(40, center2.y);
assertEquals(15, center2.x, 'Center2 x should be 15');
assertEquals(40, center2.y, 'Center2 y should be 40');
});
TEST_F('SwitchAccessRectHelperUnitTest', 'Union', function() {
......@@ -63,19 +73,23 @@ TEST_F('SwitchAccessRectHelperUnitTest', 'Union', function() {
// When one rect entirely contains the other, that rect is returned.
const union_1_2 = RectHelper.union(rect1, rect2);
assertTrue(RectHelper.areEqual(rect1, union_1_2));
assertTrue(RectHelper.areEqual(rect1, union_1_2),
'Union of rect1 and rect2 should be rect1');
const union_1_3 = RectHelper.union(rect1, rect3);
let expected = {left: 0, top: 0, width: 20, height: 60};
assertTrue(RectHelper.areEqual(expected, union_1_3));
assertTrue(RectHelper.areEqual(expected, union_1_3),
'Union of rect1 and rect3 does not match expected value');
const union_1_4 = RectHelper.union(rect1, rect4);
expected = {left: 0, top: 0, width: 10, height: 20};
assertTrue(RectHelper.areEqual(expected, union_1_4));
assertTrue(RectHelper.areEqual(expected, union_1_4),
'Union of rect1 and rect4 does not match expected value');
const union_1_5 = RectHelper.union(rect1, rect5);
expected = {left: 0, top: 0, width: 15, height: 15};
assertTrue(RectHelper.areEqual(expected, union_1_5));
assertTrue(RectHelper.areEqual(expected, union_1_5),
'Union of rect1 and rect5 does not match expected value');
});
TEST_F('SwitchAccessRectHelperUnitTest', 'UnionAll', function() {
......@@ -87,64 +101,52 @@ TEST_F('SwitchAccessRectHelperUnitTest', 'UnionAll', function() {
const union1 = RectHelper.unionAll([rect1, rect2, rect3, rect4]);
let expected = {left: 0, top: 0, width: 20, height: 20};
assertTrue(RectHelper.areEqual(expected, union1));
assertTrue(RectHelper.areEqual(expected, union1),
'Union of rects 1-4 does not match expected value');
const union2 = RectHelper.unionAll([rect1, rect2, rect3, rect4, rect5]);
expected = {left: 0, top: 0, width: 100, height: 20};
assertTrue(RectHelper.areEqual(expected, union2));
assertTrue(RectHelper.areEqual(expected, union2),
'Union of rects 1-5 does not match expected value');
});
TEST_F('SwitchAccessRectHelperUnitTest',
'ExpandToFitWithPadding_OuterContainedInInner', function() {
TEST_F('SwitchAccessRectHelperUnitTest', 'ExpandToFitWithPadding', function() {
const padding = 5;
const inner = {left: 100, top: 100, width: 100, height: 100};
const outer = {left: 120, top: 120, width: 20, height: 20};
let inner = {left: 100, top: 100, width: 100, height: 100};
let outer = {left: 120, top: 120, width: 20, height: 20};
let expected = {left: 95, top: 95, width: 110, height: 110};
assertTrue(RectHelper.areEqual(expected,
RectHelper.expandToFitWithPadding(padding, outer, inner)));
});
TEST_F('SwitchAccessRectHelperUnitTest',
'ExpandToFitWithPadding_OuterContainsInner', function() {
const padding = 5;
const inner = {left: 100, top: 100, width: 100, height: 100};
const outer = {left: 50, top: 50, width: 200, height: 200};
RectHelper.expandToFitWithPadding(padding, outer, inner)),
'When outer is contained in inner, expandToFitWithPadding does not ' +
'match expected value');
inner = {left: 100, top: 100, width: 100, height: 100};
outer = {left: 50, top: 50, width: 200, height: 200};
assertTrue(RectHelper.areEqual(outer,
RectHelper.expandToFitWithPadding(padding, outer, inner)));
});
RectHelper.expandToFitWithPadding(padding, outer, inner)),
'When outer contains inner, expandToFitWithPadding should equal outer');
TEST_F('SwitchAccessRectHelperUnitTest', 'ExpandToFitWithPadding_NoOverlap',
function() {
const padding = 5;
const inner = {left: 100, top: 100, width: 100, height: 100};
const outer = {left: 10, top: 10, width: 10, height: 10};
inner = {left: 100, top: 100, width: 100, height: 100};
outer = {left: 10, top: 10, width: 10, height: 10};
expected = {left: 10, top: 10, width: 195, height: 195};
assertTrue(RectHelper.areEqual(expected,
RectHelper.expandToFitWithPadding(padding, outer, inner)));
});
RectHelper.expandToFitWithPadding(padding, outer, inner)),
'When there is no overlap, expandToFitWithPadding does not match ' +
'expected value');
TEST_F('SwitchAccessRectHelperUnitTest', 'ExpandToFitWithPadding_Overlap',
function() {
const padding = 5;
const inner = {left: 100, top: 100, width: 100, height: 100};
const outer = {left: 120, top: 50, width: 200, height: 200};
inner = {left: 100, top: 100, width: 100, height: 100};
outer = {left: 120, top: 50, width: 200, height: 200};
expected = {left: 95, top: 50, width: 225, height: 200};
assertTrue(RectHelper.areEqual(expected,
RectHelper.expandToFitWithPadding(padding, outer, inner)));
});
RectHelper.expandToFitWithPadding(padding, outer, inner)),
'When there is some overlap, expandToFitWithPadding does not match ' +
'expected value');
TEST_F('SwitchAccessRectHelperUnitTest', 'ExpandToFitWithPadding_WithinPadding',
function() {
const padding = 5;
const inner = {left: 100, top: 100, width: 100, height: 100};
const outer = {left: 97, top: 95, width: 108, height: 110};
inner = {left: 100, top: 100, width: 100, height: 100};
outer = {left: 97, top: 95, width: 108, height: 110};
expected = {left: 95, top: 95, width: 110, height: 110};
assertTrue(RectHelper.areEqual(expected,
RectHelper.expandToFitWithPadding(padding, outer, inner)));
RectHelper.expandToFitWithPadding(padding, outer, inner)),
'When outer contains inner but without sufficient padding, ' +
'expandToFitWithPadding does not match expected value');
});
......@@ -83,6 +83,11 @@ SwitchAccessE2ETest.prototype = {
* the desktop node once the document is ready.
*/
runWithLoadedTree: function(url, callback) {
const prefix = url.substring(0, 4);
if (prefix !== 'http' && prefix !== 'data') {
url = 'data:text/html;charset=utf-8,' + url;
}
callback = this.newCallback(callback);
chrome.automation.getDesktop(function(desktopRootNode) {
var createParams = {active: true, url: url};
......
......@@ -20,19 +20,13 @@ SwitchAccessPredicateTest.prototype = {
},
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);
assertTrue(this.desktop != undefined, 'Desktop is undefined');
const node = new AutomationTreeWalker(
this.desktop, constants.Dir.FORWARD, { visit: (n) => n.name === name }
).next().node;
assertTrue(node != null, 'Node is null');
return node;
},
getNodesForRole: function(role) {
return new AutomationTreeWalker(this.desktop, constants.Dir.FORWARD,
{ visit: (node) => node.role === role });
}
};
......@@ -42,329 +36,353 @@ function fakeLoc(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>';
return `<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"
node.firstChild && node.firstChild.name === 'upper1'
}
).next().node;
assertTrue(root != null);
assertTrue(root != null, 'Root is null');
const upper1 = root.firstChild;
assertTrue(upper1 && upper1.name === "upper1");
assertTrue(upper1 && upper1.name === 'upper1', 'Upper1 not found');
const upper2 = upper1.nextSibling;
assertTrue(upper2 && upper2.name === "upper2");
assertTrue(upper2 && upper2.name === 'upper2', 'Upper2 not found');
const lower1 = upper1.firstChild;
assertTrue(lower1 && lower1.name === "lower1");
assertTrue(lower1 && lower1.name === 'lower1', 'Lower1 not found');
const lower2 = lower1.nextSibling;
assertTrue(lower2 && lower2.name === "lower2");
assertTrue(lower2 && lower2.name === 'lower2', 'Lower2 not found');
const lower3 = upper2.firstChild;
assertTrue(lower3 && lower3.name === "lower3");
assertTrue(lower3 && lower3.name === 'lower3', 'Lower3 not found');
const leaf1 = lower1.firstChild;
assertTrue(leaf1 && leaf1.name === "leaf1");
assertTrue(leaf1 && leaf1.name === 'leaf1', 'Leaf1 not found');
const leaf2 = leaf1.nextSibling;
assertTrue(leaf2 && leaf2.name === "leaf2");
assertTrue(leaf2 && leaf2.name === 'leaf2', 'Leaf2 not found');
const leaf3 = leaf2.nextSibling;
assertTrue(leaf3 && leaf3.name === "leaf3");
assertTrue(leaf3 && leaf3.name === 'leaf3', 'Leaf3 not found');
const leaf4 = lower2.firstChild;
assertTrue(leaf4 && leaf4.name === "leaf4");
assertTrue(leaf4 && leaf4.name === 'leaf4', 'Leaf4 not found');
const leaf5 = leaf4.nextSibling;
assertTrue(leaf5 && leaf5.name === "leaf5");
assertTrue(leaf5 && leaf5.name === 'leaf5', 'Leaf5 not found');
const leaf6 = lower3.firstChild;
assertTrue(leaf6 && leaf6.name === "leaf6");
assertTrue(leaf6 && leaf6.name === 'leaf6', 'Leaf6 not found');
const leaf7 = leaf6.nextSibling;
assertTrue(leaf7 && leaf7.name === "leaf7");
assertTrue(leaf7 && leaf7.name === 'leaf7', 'Leaf7 not found');
return { root, upper1, upper2, lower1, lower2, lower3, leaf1, leaf2, leaf3,
leaf4, leaf5, leaf6, leaf7 };
}
TEST_F('SwitchAccessPredicateTest', 'IsInteresting', function() {
this.runWithLoadedTree(testWebsite(),
function(desktop) {
this.runWithLoadedTree(testWebsite(), (desktop) => {
const t = getTree(desktop);
// The scope is only used to verify the locations are not the same, and
// since the buildTree function depends on isInteresting, pass in null
// for the scope.
assertTrue(SwitchAccessPredicate.isInteresting(t.root, null));
assertTrue(SwitchAccessPredicate.isInteresting(t.upper1, null));
assertTrue(SwitchAccessPredicate.isInteresting(t.upper2, null));
assertTrue(SwitchAccessPredicate.isInteresting(t.lower1, null));
assertFalse(SwitchAccessPredicate.isInteresting(t.lower2, null));
assertFalse(SwitchAccessPredicate.isInteresting(t.lower3, null));
assertTrue(SwitchAccessPredicate.isInteresting(t.leaf1, null));
assertFalse(SwitchAccessPredicate.isInteresting(t.leaf2, null));
assertTrue(SwitchAccessPredicate.isInteresting(t.leaf3, null));
assertFalse(SwitchAccessPredicate.isInteresting(t.leaf4, null));
assertTrue(SwitchAccessPredicate.isInteresting(t.leaf5, null));
assertFalse(SwitchAccessPredicate.isInteresting(t.leaf6, null));
assertFalse(SwitchAccessPredicate.isInteresting(t.leaf7, null));
}
);
assertTrue(SwitchAccessPredicate.isInteresting(t.root, null),
'Root should be interesting');
assertTrue(SwitchAccessPredicate.isInteresting(t.upper1, null),
'Upper1 should be interesting');
assertTrue(SwitchAccessPredicate.isInteresting(t.upper2, null),
'Upper2 should be interesting');
assertTrue(SwitchAccessPredicate.isInteresting(t.lower1, null),
'Lower1 should be interesting');
assertFalse(SwitchAccessPredicate.isInteresting(t.lower2, null),
'Lower2 should not be interesting');
assertFalse(SwitchAccessPredicate.isInteresting(t.lower3, null),
'Lower3 should not be interesting');
assertTrue(SwitchAccessPredicate.isInteresting(t.leaf1, null),
'Leaf1 should be interesting');
assertFalse(SwitchAccessPredicate.isInteresting(t.leaf2, null),
'Leaf2 should not be interesting');
assertTrue(SwitchAccessPredicate.isInteresting(t.leaf3, null),
'Leaf3 should be interesting');
assertFalse(SwitchAccessPredicate.isInteresting(t.leaf4, null),
'Leaf4 should not be interesting');
assertTrue(SwitchAccessPredicate.isInteresting(t.leaf5, null),
'Leaf5 should be interesting');
assertFalse(SwitchAccessPredicate.isInteresting(t.leaf6, null),
'Leaf6 should not be interesting');
assertFalse(SwitchAccessPredicate.isInteresting(t.leaf7, null),
'Leaf7 should not be interesting');
});
});
TEST_F('SwitchAccessPredicateTest', 'IsGroup', function() {
this.runWithLoadedTree(testWebsite(),
function(desktop) {
this.runWithLoadedTree(testWebsite(), (desktop) => {
const t = getTree(desktop);
// The scope is only used to verify the locations are not the same, and
// since the buildTree function depends on isGroup, pass in null for
// the scope.
assertTrue(SwitchAccessPredicate.isGroup(t.root, null));
assertTrue(SwitchAccessPredicate.isGroup(t.upper1, null));
assertFalse(SwitchAccessPredicate.isGroup(t.upper2, null));
assertTrue(SwitchAccessPredicate.isGroup(t.lower1, null));
assertFalse(SwitchAccessPredicate.isGroup(t.lower2, null));
assertFalse(SwitchAccessPredicate.isGroup(t.lower3, null));
assertFalse(SwitchAccessPredicate.isGroup(t.leaf1, null));
assertFalse(SwitchAccessPredicate.isGroup(t.leaf2, null));
assertFalse(SwitchAccessPredicate.isGroup(t.leaf3, null));
assertFalse(SwitchAccessPredicate.isGroup(t.leaf4, null));
assertFalse(SwitchAccessPredicate.isGroup(t.leaf5, null));
assertFalse(SwitchAccessPredicate.isGroup(t.leaf6, null));
assertFalse(SwitchAccessPredicate.isGroup(t.leaf7, null));
}
);
assertTrue(SwitchAccessPredicate.isGroup(t.root, null),
'Root should be a group');
assertTrue(SwitchAccessPredicate.isGroup(t.upper1, null),
'Upper1 should be a group');
assertFalse(SwitchAccessPredicate.isGroup(t.upper2, null),
'Upper2 should not be a group');
assertTrue(SwitchAccessPredicate.isGroup(t.lower1, null),
'Lower1 should be a group');
assertFalse(SwitchAccessPredicate.isGroup(t.lower2, null),
'Lower2 should not be a group');
assertFalse(SwitchAccessPredicate.isGroup(t.lower3, null),
'Lower3 should not be a group');
assertFalse(SwitchAccessPredicate.isGroup(t.leaf1, null),
'Leaf1 should not be a group');
assertFalse(SwitchAccessPredicate.isGroup(t.leaf2, null),
'Leaf2 should not be a group');
assertFalse(SwitchAccessPredicate.isGroup(t.leaf3, null),
'Leaf3 should not be a group');
assertFalse(SwitchAccessPredicate.isGroup(t.leaf4, null),
'Leaf4 should not be a group');
assertFalse(SwitchAccessPredicate.isGroup(t.leaf5, null),
'Leaf5 should not be a group');
assertFalse(SwitchAccessPredicate.isGroup(t.leaf6, null),
'Leaf6 should not be a group');
assertFalse(SwitchAccessPredicate.isGroup(t.leaf7, null),
'Leaf7 should not be a group');
});
});
TEST_F('SwitchAccessPredicateTest', 'IsInterestingSubtree', function() {
this.runWithLoadedTree(testWebsite(),
function(desktop) {
this.runWithLoadedTree(testWebsite(), (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));
}
);
assertTrue(SwitchAccessPredicate.isInterestingSubtree(t.root),
'Root should be an interesting subtree');
assertTrue(SwitchAccessPredicate.isInterestingSubtree(t.upper1),
'Upper1 should be an interesting subtree');
assertTrue(SwitchAccessPredicate.isInterestingSubtree(t.upper2),
'Upper2 should be an interesting subtree');
assertTrue(SwitchAccessPredicate.isInterestingSubtree(t.lower1),
'Lower1 should be an interesting subtree');
assertTrue(SwitchAccessPredicate.isInterestingSubtree(t.lower2),
'Lower2 should be an interesting subtree');
assertFalse(SwitchAccessPredicate.isInterestingSubtree(t.lower3),
'Lower3 should not be an interesting subtree');
assertTrue(SwitchAccessPredicate.isInterestingSubtree(t.leaf1),
'Leaf1 should be an interesting subtree');
assertFalse(SwitchAccessPredicate.isInterestingSubtree(t.leaf2),
'Leaf2 should not be an interesting subtree');
assertTrue(SwitchAccessPredicate.isInterestingSubtree(t.leaf3),
'Leaf3 should be an interesting subtree');
assertFalse(SwitchAccessPredicate.isInterestingSubtree(t.leaf4),
'Leaf4 should not be an interesting subtree');
assertTrue(SwitchAccessPredicate.isInterestingSubtree(t.leaf5),
'Leaf5 should be an interesting subtree');
assertFalse(SwitchAccessPredicate.isInterestingSubtree(t.leaf6),
'Leaf6 should not be an interesting subtree');
assertFalse(SwitchAccessPredicate.isInterestingSubtree(t.leaf7),
'Leaf7 should not be an interesting subtree');
});
});
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>' +
'<input type="range" aria-label="slider" value="5" min="0" max="10">' +
'<div aria-label="listitem" role="listitem" onclick="2+2"></div>' +
'<div aria-label="div1"><p>p1</p></div>';
this.runWithLoadedTree('data:text/html;charset=utf-8,' + treeString,
function(desktop) {
`<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>
<input type="range" aria-label="slider" value=5 min=0 max=10>
<div aria-label="listitem" role="listitem" onclick="2+2"></div>
<div aria-label="div1"><p>p1</p></div>`;
this.runWithLoadedTree(treeString, (desktop) => {
this.setDesktop(desktop);
// Objects that are offscreen should not be actionable.
const button1 = this.getNodeByName('button1');
assertFalse(SwitchAccessPredicate.isActionable(button1));
assertFalse(SwitchAccessPredicate.isActionable(button1),
'Offscreen objects should not be actionable');
// 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();
assertFalse(SwitchAccessPredicate.isActionable(button2),
'Disabled objects should not be actionable');
const rwas = desktop.findAll(
{role: chrome.automation.RoleType.ROOT_WEB_AREA});
for (const node of rwas) {
assertFalse(SwitchAccessPredicate.isActionable(node),
'Root web area should not be directly actionable');
}
// Links are considered actionable.
const link1 = this.getNodeByName('link1');
assertTrue(SwitchAccessPredicate.isActionable(link1));
assertTrue(SwitchAccessPredicate.isActionable(link1),
'Links should be actionable');
// Inputs are also considered actionable.
const input1 = this.getNodeByName('input1');
assertTrue(SwitchAccessPredicate.isActionable(input1));
assertTrue(SwitchAccessPredicate.isActionable(input1),
'Inputs should be actionable');
// Buttons are generally actionable.
const button3 = this.getNodeByName('button3');
assertTrue(SwitchAccessPredicate.isActionable(button3));
assertTrue(SwitchAccessPredicate.isActionable(button3),
'Buttons should be actionable');
// Sliders are generally actionable.
const slider = this.getNodeByName('slider');
assertTrue(SwitchAccessPredicate.isActionable(slider));
assertTrue(SwitchAccessPredicate.isActionable(slider),
'Sliders should be actionable');
// List items with a default action of click are actionable.
const listitem = this.getNodeByName('listitem');
assertTrue(SwitchAccessPredicate.isActionable(listitem));
assertTrue(SwitchAccessPredicate.isActionable(listitem),
'Clickable list items should be actionable');
// Divs are not generally actionable.
const div1 = this.getNodeByName('div1');
assertFalse(SwitchAccessPredicate.isActionable(div1));
assertFalse(SwitchAccessPredicate.isActionable(div1),
'Divs should not generally be actionable');
// Static text is not actionable.
const p1 = this.getNodeByName('p1');
assertFalse(SwitchAccessPredicate.isActionable(p1));
}
);
assertFalse(SwitchAccessPredicate.isActionable(p1),
'Static text should not generally be actionable');
});
});
TEST_F('SwitchAccessPredicateTest', 'IsActionableFocusableElements', function()
{
const treeString =
'<div aria-label="noChildren" tabindex="0"></div>' +
'<div aria-label="oneInterestingChild" tabindex="1">' +
'<div><div><div><button>button1</button></div></div></div>' +
'</div>' +
'<div aria-label="oneUninterestingChild" tabindex="2">' +
'<p>p1</p>' +
'</div>' +
'<div aria-label="interestingChildren" tabindex="3">' +
'<button>button2</button>' +
'<button>button3</button>' +
'</div>' +
'<div aria-label="uninterestingChildren" tabindex="4">' +
'<p>p2</p>' +
'<p>p3</p>' +
'</div>';
this.runWithLoadedTree('data:text/html;charset=utf-8,' + treeString,
function(desktop) {
`<div aria-label="noChildren" tabindex=0></div>
<div aria-label="oneInterestingChild" tabindex=0>
<div>
<div>
<div>
<button>button1</button>
</div>
</div>
</div>
</div>
<div aria-label="oneUninterestingChild" tabindex=0>
<p>p1</p>
</div>
<div aria-label="interestingChildren" tabindex=0>
<button>button2</button>
<button>button3</button>
</div>
<div aria-label="uninterestingChildren" tabindex=0>
<p>p2</p>
<p>p3</p>
</div>`;
this.runWithLoadedTree(treeString, (desktop) => {
this.setDesktop(desktop);
// Focusable element with no children should be actionable.
const noChildren = this.getNodeByName('noChildren');
assertTrue(SwitchAccessPredicate.isActionable(noChildren));
assertTrue(SwitchAccessPredicate.isActionable(noChildren),
'Focusable element with no children should be actionable');
// Focusable elements with one or more interesting children should not
// be actionable.
const oneInterestingChild = this.getNodeByName('oneInterestingChild');
assertFalse(SwitchAccessPredicate.isActionable(oneInterestingChild));
assertFalse(SwitchAccessPredicate.isActionable(oneInterestingChild),
'Focusable element with an interesting child should not be actionable');
const interestingChildren = this.getNodeByName('interestingChildren');
assertFalse(SwitchAccessPredicate.isActionable(interestingChildren));
assertFalse(SwitchAccessPredicate.isActionable(interestingChildren),
'Focusable element with interesting children should not be actionable');
// Focusable elements with children that are all uninteresting should
// be actionable.
const oneUninterestingChild =
this.getNodeByName('oneUninterestingChild');
assertTrue(SwitchAccessPredicate.isActionable(oneUninterestingChild));
const oneUninterestingChild = this.getNodeByName('oneUninterestingChild');
assertTrue(SwitchAccessPredicate.isActionable(oneUninterestingChild),
'Focusable element with one uninteresting child should be actionable');
const uninterestingChildren =
this.getNodeByName('uninterestingChildren');
assertTrue(SwitchAccessPredicate.isActionable(uninterestingChildren));
}
);
const uninterestingChildren = this.getNodeByName('uninterestingChildren');
assertTrue(SwitchAccessPredicate.isActionable(uninterestingChildren),
'Focusable element with uninteresting children should be actionable');
});
});
TEST_F('SwitchAccessPredicateTest', 'LeafPredicate', function() {
this.runWithLoadedTree(testWebsite(),
function(desktop) {
this.runWithLoadedTree(testWebsite(), (desktop) => {
const t = getTree(desktop);
// Start with root as scope
let leaf =
SwitchAccessPredicate.leaf(RootNodeWrapper.buildTree(t.root));
assertFalse(leaf(t.root));
assertTrue(leaf(t.upper1));
assertTrue(leaf(t.upper2));
let leaf = SwitchAccessPredicate.leaf(RootNodeWrapper.buildTree(t.root));
assertFalse(leaf(t.root), 'Root should not be a leaf node');
assertTrue(leaf(t.upper1), 'Upper1 should be a leaf node for root tree');
assertTrue(leaf(t.upper2), 'Upper2 should be a leaf node for root tree');
// Set upper1 as scope
leaf = SwitchAccessPredicate.leaf(RootNodeWrapper.buildTree(t.upper1));
assertFalse(leaf(t.upper1));
assertTrue(leaf(t.lower1));
assertTrue(leaf(t.leaf4));
assertTrue(leaf(t.leaf5));
assertFalse(leaf(t.upper1), 'Upper1 should not be a leaf for upper1 tree');
assertTrue(leaf(t.lower1), 'Lower1 should be a leaf for upper1 tree');
assertTrue(leaf(t.leaf4), 'leaf4 should be a leaf for upper1 tree');
assertTrue(leaf(t.leaf5), 'leaf5 should be a leaf for upper1 tree');
// Set lower1 as scope
leaf = SwitchAccessPredicate.leaf(RootNodeWrapper.buildTree(t.lower1));
assertFalse(leaf(t.lower1));
assertTrue(leaf(t.leaf1));
assertTrue(leaf(t.leaf2));
assertTrue(leaf(t.leaf3));
}
);
assertFalse(leaf(t.lower1), 'Lower1 should not be a leaf for lower1 tree');
assertTrue(leaf(t.leaf1), 'Leaf1 should be a leaf for lower1 tree');
assertTrue(leaf(t.leaf2), 'Leaf2 should be a leaf for lower1 tree');
assertTrue(leaf(t.leaf3), 'Leaf3 should be a leaf for lower1 tree');
});
});
TEST_F('SwitchAccessPredicateTest', 'RootPredicate', function() {
this.runWithLoadedTree(testWebsite(),
function(desktop) {
this.runWithLoadedTree(testWebsite(), (desktop) => {
const t = getTree(desktop);
// Start with root as scope
let root =
SwitchAccessPredicate.root(RootNodeWrapper.buildTree(t.root));
assertTrue(root(t.root));
assertFalse(root(t.upper1));
assertFalse(root(t.upper2));
let root = SwitchAccessPredicate.root(RootNodeWrapper.buildTree(t.root));
assertTrue(root(t.root), 'Root should be a root of the root tree');
assertFalse(root(t.upper1), 'Upper1 should not be a root of the root tree');
assertFalse(root(t.upper2), 'Upper2 should not be a root of the root tree');
// Set upper1 as scope
root = SwitchAccessPredicate.root(RootNodeWrapper.buildTree(t.upper1));
assertTrue(root(t.upper1));
assertFalse(root(t.lower1));
assertFalse(root(t.lower2));
assertTrue(root(t.upper1), 'Upper1 should be a root of the upper1 tree');
assertFalse(root(t.lower1),
'Lower1 should not be a root of the upper1 tree');
assertFalse(root(t.lower2),
'Lower2 should not be a root of the upper1 tree');
// Set lower1 as scope
root = SwitchAccessPredicate.root(RootNodeWrapper.buildTree(t.lower1));
assertTrue(root(t.lower1));
assertFalse(root(t.leaf1));
assertFalse(root(t.leaf2));
assertFalse(root(t.leaf3));
}
);
assertTrue(root(t.lower1), 'Lower1 should be a root of the lower1 tree');
assertFalse(root(t.leaf1), 'Leaf1 should not be a root of the lower1 tree');
assertFalse(root(t.leaf2), 'Leaf2 should not be a root of the lower1 tree');
assertFalse(root(t.leaf3), 'Leaf3 should not be a root of the lower1 tree');
});
});
TEST_F('SwitchAccessPredicateTest', 'VisitPredicate', function() {
this.runWithLoadedTree(testWebsite(),
function(desktop) {
this.runWithLoadedTree(testWebsite(), (desktop) => {
const t = getTree(desktop);
// Start with root as scope
let visit =
SwitchAccessPredicate.visit(RootNodeWrapper.buildTree(t.root));
assertTrue(visit(t.root));
assertTrue(visit(t.upper1));
assertTrue(visit(t.upper2));
let visit = SwitchAccessPredicate.visit(RootNodeWrapper.buildTree(t.root));
assertTrue(visit(t.root), 'Root should be visited in root tree');
assertTrue(visit(t.upper1), 'Upper1 should be visited in root tree');
assertTrue(visit(t.upper2), 'Upper2 should be visited in root tree');
// Set upper1 as scope
visit =
SwitchAccessPredicate.visit(RootNodeWrapper.buildTree(t.upper1));
assertTrue(visit(t.upper1));
assertTrue(visit(t.lower1));
assertFalse(visit(t.lower2));
assertFalse(visit(t.leaf4));
assertTrue(visit(t.leaf5));
visit = SwitchAccessPredicate.visit(RootNodeWrapper.buildTree(t.upper1));
assertTrue(visit(t.upper1), 'Upper1 should be visited in upper1 tree');
assertTrue(visit(t.lower1), 'Lower1 should be visited in upper1 tree');
assertFalse(visit(t.lower2), 'Lower2 should not be visited in upper1 tree');
assertFalse(visit(t.leaf4), 'Leaf4 should not be visited in upper1 tree');
assertTrue(visit(t.leaf5), 'Leaf5 should be visited in upper1 tree');
// Set lower1 as scope
visit =
SwitchAccessPredicate.visit(RootNodeWrapper.buildTree(t.lower1));
assertTrue(visit(t.lower1));
assertTrue(visit(t.leaf1));
assertFalse(visit(t.leaf2));
assertTrue(visit(t.leaf3));
visit = SwitchAccessPredicate.visit(RootNodeWrapper.buildTree(t.lower1));
assertTrue(visit(t.lower1), 'Lower1 should be visited in lower1 tree');
assertTrue(visit(t.leaf1), 'Leaf1 should be visited in lower1 tree');
assertFalse(visit(t.leaf2), 'Leaf2 should not be visited in lower1 tree');
assertTrue(visit(t.leaf3), 'Leaf3 should be visited in lower1 tree');
// An uninteresting subtree should return false, regardless of scope
assertFalse(visit(t.lower3));
assertFalse(visit(t.leaf6));
assertFalse(visit(t.leaf7));
}
);
assertFalse(visit(t.lower3), 'Lower3 should not be visited in lower1 tree');
assertFalse(visit(t.leaf6), 'Leaf6 should not be visited in lower1 tree');
assertFalse(visit(t.leaf7), 'Leaf7 should not be visited in lower1 tree');
});
});
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