diff options
Diffstat (limited to 'devtools/client/memory/test/browser/browser_memory_dominator_trees_01.js')
-rw-r--r-- | devtools/client/memory/test/browser/browser_memory_dominator_trees_01.js | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/devtools/client/memory/test/browser/browser_memory_dominator_trees_01.js b/devtools/client/memory/test/browser/browser_memory_dominator_trees_01.js new file mode 100644 index 000000000..3380d6e21 --- /dev/null +++ b/devtools/client/memory/test/browser/browser_memory_dominator_trees_01.js @@ -0,0 +1,147 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +// Sanity test for dominator trees, their focused nodes, and keyboard navigating +// through nodes across incrementally fetching subtrees. + +"use strict"; + +const { + dominatorTreeState, + viewState, +} = require("devtools/client/memory/constants"); +const { + expandDominatorTreeNode, +} = require("devtools/client/memory/actions/snapshot"); +const { changeView } = require("devtools/client/memory/actions/view"); + +const TEST_URL = "http://example.com/browser/devtools/client/memory/test/browser/doc_big_tree.html"; + +this.test = makeMemoryTest(TEST_URL, function* ({ tab, 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. + + yield 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 (let 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 (let 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); + yield 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); + yield 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. + + yield 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 (let 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); + yield 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"); +}); |