Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

/* Any copyright is dedicated to the Public Domain.
// Sanity test for dominator trees, their focused nodes, and keyboard navigating
// through nodes across incrementally fetching subtrees.
"use strict";
const {
dominatorTreeState,
viewState,
const {
expandDominatorTreeNode,
const {
changeView,
const TEST_URL =
this.test = makeMemoryTest(TEST_URL, async function ({ panel }) {
// Taking snapshots and computing dominator trees is slow :-/
requestLongerTimeout(4);
const store = panel.panelWin.gStore;
const { getState, dispatch } = store;
const doc = panel.panelWin.document;
dispatch(changeView(viewState.DOMINATOR_TREE));
// Take a snapshot.
const takeSnapshotButton = doc.getElementById("take-snapshot");
EventUtils.synthesizeMouseAtCenter(takeSnapshotButton, {}, panel.panelWin);
// Wait for the dominator tree to be computed and fetched.
await waitUntilDominatorTreeState(store, [dominatorTreeState.LOADED]);
ok(true, "Computed and fetched the dominator tree.");
// Expand all the dominator tree nodes that are eagerly fetched, except for
// the leaves which will trigger fetching their lazily loaded subtrees.
const id = getState().snapshots[0].id;
const root = getState().snapshots[0].dominatorTree.root;
(function expandAllEagerlyFetched(node = root) {
if (!node.moreChildrenAvailable || node.children) {
dispatch(expandDominatorTreeNode(id, node));
}
if (node.children) {
for (const child of node.children) {
expandAllEagerlyFetched(child);
}
}
})();
// Find the deepest eagerly loaded node: one which has more children but none
// of them are loaded.
const deepest = (function findDeepest(node = root) {
if (node.moreChildrenAvailable && !node.children) {
return node;
}
if (node.children) {
for (const child of node.children) {
const found = findDeepest(child);
if (found) {
return found;
}
}
}
return null;
})();
ok(deepest, "Found the deepest node");
ok(
!getState().snapshots[0].dominatorTree.expanded.has(deepest.nodeId),
"The deepest node should not be expanded"
);
// Select the deepest node.
EventUtils.synthesizeMouseAtCenter(
doc.querySelector(`.node-${deepest.nodeId}`),
{},
panel.panelWin
);
await waitUntilState(
store,
state => state.snapshots[0].dominatorTree.focused.nodeId === deepest.nodeId
);
ok(
doc.querySelector(`.node-${deepest.nodeId}`).classList.contains("focused"),
"The deepest node should be focused now"
);
// Expand the deepest node, which triggers an incremental fetch of its lazily
// loaded subtree.
EventUtils.synthesizeKey("VK_RIGHT", {}, panel.panelWin);
await waitUntilState(store, state =>
state.snapshots[0].dominatorTree.expanded.has(deepest.nodeId)
);
is(
getState().snapshots[0].dominatorTree.state,
dominatorTreeState.INCREMENTAL_FETCHING,
"Expanding the deepest node should start an incremental fetch of its subtree"
);
ok(
doc.querySelector(`.node-${deepest.nodeId}`).classList.contains("focused"),
"The deepest node should still be focused after expansion"
);
// Wait for the incremental fetch to complete.
await waitUntilState(
store,
state =>
state.snapshots[0].dominatorTree.state === dominatorTreeState.LOADED
);
ok(true, "And the incremental fetch completes.");
ok(
doc.querySelector(`.node-${deepest.nodeId}`).classList.contains("focused"),
"The deepest node should still be focused after we have loaded its children"
);
// Find the most up-to-date version of the node whose children we just
// incrementally fetched.
const newDeepest = (function findNewDeepest(
node = getState().snapshots[0].dominatorTree.root
) {
if (node.nodeId === deepest.nodeId) {
return node;
}
if (node.children) {
for (const child of node.children) {
const found = findNewDeepest(child);
if (found) {
return found;
}
}
}
return null;
})();
ok(newDeepest, "We found the up-to-date version of deepest");
ok(newDeepest.children, "And its children are loaded");
ok(newDeepest.children.length, "And there are more than 0 children");
const firstChild = newDeepest.children[0];
ok(firstChild, "deepest should have a first child");
ok(
doc.querySelector(`.node-${firstChild.nodeId}`),
"and the first child should exist in the dom"
);
// Select the newly loaded first child by pressing the right arrow once more.
EventUtils.synthesizeKey("VK_RIGHT", {}, panel.panelWin);
await waitUntilState(
store,
state => state.snapshots[0].dominatorTree.focused === firstChild
);
ok(
doc
.querySelector(`.node-${firstChild.nodeId}`)
.classList.contains("focused"),
"The first child should now be focused"
);
});