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