Bug 1415532 - Add element asynchronously. r=jdescottes draft
authorAlexandre Poirot <poirot.alex@gmail.com>
Tue, 21 Nov 2017 14:37:33 -0800
changeset 701945 3cd3589ea191c4d97a10dd4cef7f18a3c67e10a3
parent 701944 0b9d905aafec6bd181f260e93a967c8febcb0af4
child 701994 c2e444030f451cacb3e89942867e6fd4c2cc9067
push id90313
push userbmo:poirot.alex@gmail.com
push dateWed, 22 Nov 2017 13:26:35 +0000
reviewersjdescottes
bugs1415532
milestone59.0a1
Bug 1415532 - Add element asynchronously. r=jdescottes MozReview-Commit-ID: LK0zloFrUEN
testing/talos/talos/tests/devtools/addon/content/damp.js
testing/talos/talos/tests/devtools/addon/content/pages/custom/generate-inspector-html.js
testing/talos/talos/tests/devtools/addon/content/pages/custom/inspector.html
--- a/testing/talos/talos/tests/devtools/addon/content/damp.js
+++ b/testing/talos/talos/tests/devtools/addon/content/damp.js
@@ -451,32 +451,62 @@ async _consoleOpenWithCachedMessagesTest
 
   async _coldInspectorOpen() {
     await this.testSetup(SIMPLE_URL);
     await this.openToolboxAndLog("cold.inspector", "inspector");
     await this.closeToolbox();
     await this.testTeardown();
   },
 
-  async reloadInspectorAndLog(label, toolbox) {
+  async reloadInspectorAndLog(label, toolbox, waitForElement) {
     let onReload = async function() {
       let inspector = toolbox.getPanel("inspector");
       // First wait for markup view to be loaded against the new root node
       await inspector.once("new-root");
       // Then wait for inspector to be updated
       await inspector.once("inspector-updated");
+
+      if (!waitForElement) {
+        return;
+      }
+      let { walker, markup } = inspector;
+      let nodeFront;
+      while (true) {
+        if (!nodeFront) {
+          nodeFront = await walker.querySelector(walker.rootNode, waitForElement);
+        }
+        let container = markup.getContainer(nodeFront);
+        if (container) {
+          break;
+        }
+        await inspector.once("markupmutation");
+      }
     };
     await this.reloadPageAndLog(label + ".inspector", onReload);
   },
 
   async customInspector() {
     let url = CUSTOM_URL.replace(/\$TOOL/, "inspector");
     await this.testSetup(url);
-    let toolbox = await this.openToolboxAndLog("custom.inspector", "inspector");
-    await this.reloadInspectorAndLog("custom", toolbox);
+    let onLoad = async function (toolbox, inspector) {
+      let { walker, markup } = inspector;
+      let nodeFront;
+      while (true) {
+        if (!nodeFront) {
+          nodeFront = await walker.querySelector(walker.rootNode, "#last");
+        }
+        let container = markup.getContainer(nodeFront);
+        if (container) {
+          break;
+        }
+        await inspector.once("markupmutation");
+      }
+    };
+    let toolbox = await this.openToolboxAndLog("custom.inspector", "inspector", onLoad);
+    await this.reloadInspectorAndLog("custom", toolbox, "#last");
     await this.closeToolboxAndLog("custom.inspector");
     await this.testTeardown();
   },
 
   _getToolLoadingTests(url, label, { expectedMessages, expectedSources }) {
     let tests = {
       async inspector() {
         await this.testSetup(url);
new file mode 100644
--- /dev/null
+++ b/testing/talos/talos/tests/devtools/addon/content/pages/custom/generate-inspector-html.js
@@ -0,0 +1,87 @@
+// nodejs script to generate: testing/talos/talos/tests/devtools/addon/content/pages/custom/inspector.html
+// Execute it like this:
+// $ nodejs generate-inspector-html.js > testing/talos/talos/tests/devtools/addon/content/pages/custom/inspector.html
+
+// We first create a deep tree with ${deep} nested children
+let deep = 50;
+// Then we create ${n} element after the deep tree
+let n = 50;
+// Number of attributes set on the repeated elements
+let attributes = 50;
+// We also add elements asynchronously after the ${n}-th.
+let async = 10;
+
+// Build the <div> with $attributes data attributes
+let div = "<div";
+for(var i = 1; i <= attributes; i++) {
+  div += " data-a" + i + "=\"" + i + "\"";
+}
+div += ">";
+
+// Build the tree of $deep elements
+let tree = "";
+for(var i = 1; i <= deep; i++) {
+  for(var j = 0; j < i; j++) {
+    tree += "&nbsp;";
+  }
+  if (i == deep) {
+    tree += div.replace("div", "div id=\"deep\"");
+  } else {
+    tree += div;
+  }
+  tree += " " + i + "\n";
+}
+for(var i = deep; i >= 0; i--) {
+  for(var j = 0; j < i; j++) {
+    tree += " ";
+  }
+  tree += "</div>\n";
+}
+
+// Build the list of $n elements
+let repeat = "";
+for(var i = 1; i <= n; i++) {
+  repeat += div + " " + i + " </div>\n";
+}
+
+console.log(`
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Custom page for the Inspector</title>
+  <style>
+  div {
+    margin-left: 0.5em;
+  }
+  </style>
+</head>
+<body>
+<script>
+  // Add element asynchronously
+  let x = 0;
+  let count = ${async};
+  let interval = window.setInterval(() => {
+    let div = document.createElement("div");
+    document.body.appendChild(div);
+    document.body.setAttribute("increment", x++);
+    if (x == count) {
+      // Flag the last one to help listening for test completion
+      div.id = "last";
+      // Stop adding elements
+      window.clearInterval(interval);
+    }
+  }, 50);
+</script>
+<!-- <div> elements with ${deep} nested childs, all with ${attributes} attributes -->
+<!-- The deepest <div> has id="deep"> -->
+`);
+console.log(tree);
+console.log(`
+<!-- ${n} <div> elements without any children -->
+`);
+console.log(repeat);
+console.log(`
+</body>
+</html>`);
+
--- a/testing/talos/talos/tests/devtools/addon/content/pages/custom/inspector.html
+++ b/testing/talos/talos/tests/devtools/addon/content/pages/custom/inspector.html
@@ -6,16 +6,32 @@
   <title>Custom page for the Inspector</title>
   <style>
   div {
     margin-left: 0.5em;
   }
   </style>
 </head>
 <body>
+<script>
+  // Add element asynchronously
+  let x = 0;
+  let count = 10;
+  let interval = window.setInterval(() => {
+    let div = document.createElement("div");
+    document.body.appendChild(div);
+    document.body.setAttribute("increment", x++);
+    if (x == count) {
+      // Flag the last one to help listening for test completion
+      div.id = "last";
+      // Stop adding elements
+      window.clearInterval(interval);
+    }
+  }, 50);
+</script>
 <!-- <div> elements with 50 nested childs, all with 50 attributes -->
 <!-- The deepest <div> has id="deep"> -->
 
 &nbsp;<div data-a1="1" data-a2="2" data-a3="3" data-a4="4" data-a5="5" data-a6="6" data-a7="7" data-a8="8" data-a9="9" data-a10="10" data-a11="11" data-a12="12" data-a13="13" data-a14="14" data-a15="15" data-a16="16" data-a17="17" data-a18="18" data-a19="19" data-a20="20" data-a21="21" data-a22="22" data-a23="23" data-a24="24" data-a25="25" data-a26="26" data-a27="27" data-a28="28" data-a29="29" data-a30="30" data-a31="31" data-a32="32" data-a33="33" data-a34="34" data-a35="35" data-a36="36" data-a37="37" data-a38="38" data-a39="39" data-a40="40" data-a41="41" data-a42="42" data-a43="43" data-a44="44" data-a45="45" data-a46="46" data-a47="47" data-a48="48" data-a49="49" data-a50="50"> 1
 &nbsp;&nbsp;<div data-a1="1" data-a2="2" data-a3="3" data-a4="4" data-a5="5" data-a6="6" data-a7="7" data-a8="8" data-a9="9" data-a10="10" data-a11="11" data-a12="12" data-a13="13" data-a14="14" data-a15="15" data-a16="16" data-a17="17" data-a18="18" data-a19="19" data-a20="20" data-a21="21" data-a22="22" data-a23="23" data-a24="24" data-a25="25" data-a26="26" data-a27="27" data-a28="28" data-a29="29" data-a30="30" data-a31="31" data-a32="32" data-a33="33" data-a34="34" data-a35="35" data-a36="36" data-a37="37" data-a38="38" data-a39="39" data-a40="40" data-a41="41" data-a42="42" data-a43="43" data-a44="44" data-a45="45" data-a46="46" data-a47="47" data-a48="48" data-a49="49" data-a50="50"> 2
 &nbsp;&nbsp;&nbsp;<div data-a1="1" data-a2="2" data-a3="3" data-a4="4" data-a5="5" data-a6="6" data-a7="7" data-a8="8" data-a9="9" data-a10="10" data-a11="11" data-a12="12" data-a13="13" data-a14="14" data-a15="15" data-a16="16" data-a17="17" data-a18="18" data-a19="19" data-a20="20" data-a21="21" data-a22="22" data-a23="23" data-a24="24" data-a25="25" data-a26="26" data-a27="27" data-a28="28" data-a29="29" data-a30="30" data-a31="31" data-a32="32" data-a33="33" data-a34="34" data-a35="35" data-a36="36" data-a37="37" data-a38="38" data-a39="39" data-a40="40" data-a41="41" data-a42="42" data-a43="43" data-a44="44" data-a45="45" data-a46="46" data-a47="47" data-a48="48" data-a49="49" data-a50="50"> 3
 &nbsp;&nbsp;&nbsp;&nbsp;<div data-a1="1" data-a2="2" data-a3="3" data-a4="4" data-a5="5" data-a6="6" data-a7="7" data-a8="8" data-a9="9" data-a10="10" data-a11="11" data-a12="12" data-a13="13" data-a14="14" data-a15="15" data-a16="16" data-a17="17" data-a18="18" data-a19="19" data-a20="20" data-a21="21" data-a22="22" data-a23="23" data-a24="24" data-a25="25" data-a26="26" data-a27="27" data-a28="28" data-a29="29" data-a30="30" data-a31="31" data-a32="32" data-a33="33" data-a34="34" data-a35="35" data-a36="36" data-a37="37" data-a38="38" data-a39="39" data-a40="40" data-a41="41" data-a42="42" data-a43="43" data-a44="44" data-a45="45" data-a46="46" data-a47="47" data-a48="48" data-a49="49" data-a50="50"> 4
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<div data-a1="1" data-a2="2" data-a3="3" data-a4="4" data-a5="5" data-a6="6" data-a7="7" data-a8="8" data-a9="9" data-a10="10" data-a11="11" data-a12="12" data-a13="13" data-a14="14" data-a15="15" data-a16="16" data-a17="17" data-a18="18" data-a19="19" data-a20="20" data-a21="21" data-a22="22" data-a23="23" data-a24="24" data-a25="25" data-a26="26" data-a27="27" data-a28="28" data-a29="29" data-a30="30" data-a31="31" data-a32="32" data-a33="33" data-a34="34" data-a35="35" data-a36="36" data-a37="37" data-a38="38" data-a39="39" data-a40="40" data-a41="41" data-a42="42" data-a43="43" data-a44="44" data-a45="45" data-a46="46" data-a47="47" data-a48="48" data-a49="49" data-a50="50"> 5