summaryrefslogtreecommitdiffstats
path: root/devtools/client/memory/test/browser/browser_memory_dominator_trees_01.js
diff options
context:
space:
mode:
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.js147
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");
+});