Bug 1380512 - Fix intermittent on browser_webconsole_check_stubs_console_api. r=Honza, a=test-only
authorNicolas Chevobbe <nchevobbe@mozilla.com>
Mon, 14 Aug 2017 10:30:59 +0200
changeset 423583 1dd09478ec89230c01f0acbe33871ac5d48ca757
parent 423582 b6b61f8221fb1636fee4445b7a94b0df23ffeda6
child 423584 36c4a1d0b3bea5f7b55c54c7c2741e1dcc3a0c02
push id1517
push userjlorenzo@mozilla.com
push dateThu, 14 Sep 2017 16:50:54 +0000
treeherdermozilla-release@3b41fd564418 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersHonza, test-only
bugs1380512
milestone56.0
Bug 1380512 - Fix intermittent on browser_webconsole_check_stubs_console_api. r=Honza, a=test-only There was an error because of the console.dir call, which is calling the server to fetch the properties of the inspected object. But, since the console.dir call was the last command to be called, the actor were cleared before the properties fetch call was done, resulting in an error on the server (no such actor for ID). To fix this, we wait for the properties fetch call to be done before closing the tab. MozReview-Commit-ID: 9bsh3vHVPVa
devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/head.js
--- a/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/head.js
+++ b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/head.js
@@ -284,28 +284,44 @@ function* generateConsoleApiStubs() {
   const TEST_URI = "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html";
 
   let stubs = {
     preparedMessages: [],
     packets: [],
   };
 
   let toolbox = yield openNewTabAndToolbox(TEST_URI, "webconsole");
-  let {ui} = toolbox.getCurrentPanel().hud;
+  const hud = toolbox.getCurrentPanel().hud;
+  let {ui} = hud;
   ok(ui.jsterm, "jsterm exists");
   ok(ui.newConsoleOutput, "newConsoleOutput exists");
 
   for (let [key, {keys, code}] of consoleApi) {
     let received = new Promise(resolve => {
       let i = 0;
-      let listener = (type, res) => {
-        stubs.packets.push(formatPacket(keys[i], res));
-        stubs.preparedMessages.push(formatStub(keys[i], res));
+      let listener = async (type, res) => {
+        const callKey = keys[i];
+        stubs.packets.push(formatPacket(callKey, res));
+        stubs.preparedMessages.push(formatStub(callKey, res));
         if (++i === keys.length) {
           toolbox.target.client.removeListener("consoleAPICall", listener);
+
+          // If this is a console.dir call, we need to wait for the properties
+          // to be fetched so we don't have any server errors.
+          if (callKey === "console.dir({C, M, Y, K})") {
+            const dirMsg = await waitForMessage(hud, `cyan: "C"`);
+            const oi = dirMsg.querySelector(".tree");
+            // If there's only one node, it means that the object inspector
+            // is not expanded.
+            if (oi.querySelectorAll(".node").length === 1) {
+              await waitForNodeMutation(oi, {
+                childList: true
+              });
+            }
+          }
           resolve();
         }
       };
       toolbox.target.client.addListener("consoleAPICall", listener);
     });
 
     yield ContentTask.spawn(
       gBrowser.selectedBrowser,
@@ -501,8 +517,49 @@ function* generatePageErrorStubs() {
     );
 
     yield received;
   }
 
   yield closeTabAndToolbox();
   return formatFile(stubs, "ConsoleMessage");
 }
+
+/**
+ * Wait for messages in the web console output, resolving once they are receieved.
+ *
+ * @param hud: the webconsole
+ * @param message: string. text match in .message-body
+ */
+function waitForMessage(hud, messageText) {
+  return new Promise(resolve => {
+    hud.ui.on("new-messages",
+      function messagesReceived(e, newMessages) {
+        for (let newMessage of newMessages) {
+          let messageBody = newMessage.node.querySelector(".message-body");
+          if (messageBody.textContent.includes(messageText)) {
+            info("Matched a message with text: " + messageText);
+            hud.ui.off("new-messages", messagesReceived);
+            resolve(newMessage.node);
+            break;
+          }
+        }
+      });
+  });
+}
+
+/**
+* Returns a promise that resolves when the node passed as an argument mutate
+* according to the passed configuration.
+*
+* @param {Node} node - The node to observe mutations on.
+* @param {Object} observeConfig - A configuration object for MutationObserver.observe.
+* @returns {Promise}
+*/
+function waitForNodeMutation(node, observeConfig = {}) {
+  return new Promise(resolve => {
+    const observer = new MutationObserver(mutations => {
+      resolve(mutations);
+      observer.disconnect();
+    });
+    observer.observe(node, observeConfig);
+  });
+}