Bug 1317650 - Fix test failures for Params Panel draft
authorRicky Chien <rchien@mozilla.com>
Sat, 07 Jan 2017 10:47:39 +0800
changeset 457222 ca6ee7f2c8fdc9ebf2474e9c0a8f5be454823347
parent 457221 5f5ea466803754041c51b406bb202dfb363dec13
child 541427 79e3b121b5be9151f5ca05a37b10ad3db7e5c4bf
push id40716
push userbmo:rchien@mozilla.com
push dateSat, 07 Jan 2017 02:48:53 +0000
bugs1317650
milestone53.0a1
Bug 1317650 - Fix test failures for Params Panel MozReview-Commit-ID: 8ENleOLOx9u
devtools/client/netmonitor/test/browser_net_cached-status.js
devtools/client/netmonitor/test/browser_net_complex-params.js
devtools/client/netmonitor/test/browser_net_post-data-01.js
devtools/client/netmonitor/test/browser_net_post-data-02.js
devtools/client/netmonitor/test/browser_net_post-data-03.js
devtools/client/netmonitor/test/browser_net_post-data-04.js
devtools/client/netmonitor/test/browser_net_status-codes.js
--- a/devtools/client/netmonitor/test/browser_net_cached-status.js
+++ b/devtools/client/netmonitor/test/browser_net_cached-status.js
@@ -10,17 +10,16 @@
 add_task(function* () {
   let { tab, monitor } = yield initNetMonitor(STATUS_CODES_URL, null, true);
   info("Starting test... ");
 
   let { NetMonitorView } = monitor.panelWin;
   let { RequestsMenu, NetworkDetails } = NetMonitorView;
 
   RequestsMenu.lazyUpdate = false;
-  NetworkDetails._params.lazyEmpty = false;
 
   const REQUEST_DATA = [
     {
       method: "GET",
       uri: STATUS_CODES_SJS + "?sts=ok&cached",
       details: {
         status: 200,
         statusText: "OK",
--- a/devtools/client/netmonitor/test/browser_net_complex-params.js
+++ b/devtools/client/netmonitor/test/browser_net_complex-params.js
@@ -9,187 +9,174 @@
  */
 
 add_task(function* () {
   let { L10N } = require("devtools/client/netmonitor/l10n");
 
   let { tab, monitor } = yield initNetMonitor(PARAMS_URL);
   info("Starting test... ");
 
-  let { document, EVENTS, Editor, NetMonitorView } = monitor.panelWin;
-  let { RequestsMenu, NetworkDetails } = NetMonitorView;
+  let { document, NetMonitorView } = monitor.panelWin;
+  let { RequestsMenu } = NetMonitorView;
 
   RequestsMenu.lazyUpdate = false;
-  NetworkDetails._params.lazyEmpty = false;
 
   let wait = waitForNetworkEvents(monitor, 1, 6);
   yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
     content.wrappedJSObject.performRequests();
   });
   yield wait;
 
-  let onEvent = monitor.panelWin.once(EVENTS.REQUEST_POST_PARAMS_DISPLAYED);
+  wait = waitForDOM(document, "#params-tabpanel .tree-section", 2);
   EventUtils.sendMouseEvent({ type: "mousedown" },
     document.getElementById("details-pane-toggle"));
   EventUtils.sendMouseEvent({ type: "mousedown" },
     document.querySelectorAll("#details-pane tab")[2]);
-  yield onEvent;
-  yield testParamsTab1("a", '""', '{ "foo": "bar" }', '""');
+  yield wait;
+  testParamsTab1("a", '""', '{ "foo": "bar" }', '""');
 
-  onEvent = monitor.panelWin.once(EVENTS.REQUEST_POST_PARAMS_DISPLAYED);
+  wait = waitForDOM(document, "#params-tabpanel .tree-section", 2);
   RequestsMenu.selectedIndex = 1;
-  yield onEvent;
-  yield testParamsTab1("a", '"b"', '{ "foo": "bar" }', '""');
+  yield wait;
+  testParamsTab1("a", '"b"', '{ "foo": "bar" }', '""');
 
-  onEvent = monitor.panelWin.once(EVENTS.REQUEST_POST_PARAMS_DISPLAYED);
+  wait = waitForDOM(document, "#params-tabpanel .tree-section", 2);
   RequestsMenu.selectedIndex = 2;
-  yield onEvent;
-  yield testParamsTab1("a", '"b"', "foo", '"bar"');
+  yield wait;
+  testParamsTab1("a", '"b"', "foo", '"bar"');
 
-  onEvent = monitor.panelWin.once(EVENTS.REQUEST_POST_PARAMS_DISPLAYED);
+  wait = waitForDOM(document, "#params-tabpanel tr:not(.tree-section).treeRow", 2);
   RequestsMenu.selectedIndex = 3;
-  yield onEvent;
-  yield testParamsTab2("a", '""', '{ "foo": "bar" }', "js");
+  yield wait;
+  testParamsTab2("a", '""', '{ "foo": "bar" }', "js");
 
-  onEvent = monitor.panelWin.once(EVENTS.REQUEST_POST_PARAMS_DISPLAYED);
+  wait = waitForDOM(document, "#params-tabpanel tr:not(.tree-section).treeRow", 2);
   RequestsMenu.selectedIndex = 4;
-  yield onEvent;
-  yield testParamsTab2("a", '"b"', '{ "foo": "bar" }', "js");
+  yield wait;
+  testParamsTab2("a", '"b"', '{ "foo": "bar" }', "js");
 
-  onEvent = monitor.panelWin.once(EVENTS.REQUEST_POST_PARAMS_DISPLAYED);
+  // Wait for all tree sections and editor updated by react
+  let waitSections = waitForDOM(document, "#params-tabpanel .tree-section", 2);
+  let waitEditor = waitForDOM(document, "#params-tabpanel .editor-mount iframe");
   RequestsMenu.selectedIndex = 5;
-  yield onEvent;
-  yield testParamsTab2("a", '"b"', "?foo=bar", "text");
+  let [, editorFrames] = yield Promise.all([waitSections, waitEditor]);
+  yield once(editorFrames[0], "DOMContentLoaded");
+  yield waitForDOM(editorFrames[0].contentDocument, ".CodeMirror-code");
+  testParamsTab2("a", '"b"', "?foo=bar", "text");
 
-  onEvent = monitor.panelWin.once(EVENTS.SIDEBAR_POPULATED);
+  wait = waitForDOM(document, "#params-tabpanel .empty-notice");
   RequestsMenu.selectedIndex = 6;
-  yield onEvent;
-  yield testParamsTab3("a", '"b"');
+  yield wait;
+  testParamsTab3();
 
   yield teardown(monitor);
 
   function testParamsTab1(queryStringParamName, queryStringParamValue,
                           formDataParamName, formDataParamValue) {
     let tabpanel = document.querySelectorAll("#details-pane tabpanel")[2];
 
-    is(tabpanel.querySelectorAll(".variables-view-scope").length, 2,
-      "The number of param scopes displayed in this tabpanel is incorrect.");
-    is(tabpanel.querySelectorAll(".variable-or-property").length, 2,
-      "The number of param values displayed in this tabpanel is incorrect.");
-    is(tabpanel.querySelectorAll(".variables-view-empty-notice").length, 0,
+    is(tabpanel.querySelectorAll(".tree-section").length, 2,
+      "The number of param tree sections displayed in this tabpanel is incorrect.");
+    is(tabpanel.querySelectorAll("tr:not(.tree-section).treeRow").length, 2,
+      "The number of param rows displayed in this tabpanel is incorrect.");
+    is(tabpanel.querySelectorAll(".empty-notice").length, 0,
       "The empty notice should not be displayed in this tabpanel.");
 
-    is(tabpanel.querySelector("#request-params-box")
-      .hasAttribute("hidden"), false,
-      "The request params box should not be hidden.");
-    is(tabpanel.querySelector("#request-post-data-textarea-box")
-      .hasAttribute("hidden"), true,
-      "The request post data textarea box should be hidden.");
+    ok(tabpanel.querySelector(".treeTable"),
+      "The request params box should be displayed.");
+    ok(tabpanel.querySelector(".editor-mount") === null,
+      "The request post data editor should not be displayed.");
 
-    let paramsScope = tabpanel.querySelectorAll(".variables-view-scope")[0];
-    let formDataScope = tabpanel.querySelectorAll(".variables-view-scope")[1];
+    let treeSections = tabpanel.querySelectorAll(".tree-section");
+    let labels = tabpanel
+      .querySelectorAll("tr:not(.tree-section) .treeLabelCell .treeLabel");
+    let values = tabpanel
+      .querySelectorAll("tr:not(.tree-section) .treeValueCell .objectBox");
 
-    is(paramsScope.querySelector(".name").getAttribute("value"),
+    is(treeSections[0].querySelector(".treeLabel").textContent,
       L10N.getStr("paramsQueryString"),
-      "The params scope doesn't have the correct title.");
-    is(formDataScope.querySelector(".name").getAttribute("value"),
+      "The params section doesn't have the correct title.");
+    is(treeSections[1].querySelector(".treeLabel").textContent,
       L10N.getStr("paramsFormData"),
-      "The form data scope doesn't have the correct title.");
+      "The form data section doesn't have the correct title.");
 
-    is(paramsScope.querySelectorAll(".variables-view-variable .name")[0]
-      .getAttribute("value"),
-      queryStringParamName,
+    is(labels[0].textContent, queryStringParamName,
       "The first query string param name was incorrect.");
-    is(paramsScope.querySelectorAll(".variables-view-variable .value")[0]
-      .getAttribute("value"),
-      queryStringParamValue,
+    is(values[0].textContent, queryStringParamValue,
       "The first query string param value was incorrect.");
 
-    is(formDataScope.querySelectorAll(".variables-view-variable .name")[0]
-      .getAttribute("value"),
-      formDataParamName,
+    is(labels[1].textContent, formDataParamName,
       "The first form data param name was incorrect.");
-    is(formDataScope.querySelectorAll(".variables-view-variable .value")[0]
-      .getAttribute("value"),
-      formDataParamValue,
+    is(values[1].textContent, formDataParamValue,
       "The first form data param value was incorrect.");
   }
 
-  function* testParamsTab2(queryStringParamName, queryStringParamValue,
+  function testParamsTab2(queryStringParamName, queryStringParamValue,
                           requestPayload, editorMode) {
-    let isJSON = editorMode == "js";
+    let isJSON = editorMode === "js";
     let tabpanel = document.querySelectorAll("#details-pane tabpanel")[2];
 
-    is(tabpanel.querySelectorAll(".variables-view-scope").length, 2,
-      "The number of param scopes displayed in this tabpanel is incorrect.");
-    is(tabpanel.querySelectorAll(".variable-or-property").length, isJSON ? 4 : 1,
-      "The number of param values displayed in this tabpanel is incorrect.");
-    is(tabpanel.querySelectorAll(".variables-view-empty-notice").length, 0,
+    is(tabpanel.querySelectorAll(".tree-section").length, 2,
+      "The number of param tree sections displayed in this tabpanel is incorrect.");
+    is(tabpanel.querySelectorAll("tr:not(.tree-section).treeRow").length, isJSON ? 2 : 1,
+      "The number of param rows displayed in this tabpanel is incorrect.");
+    is(tabpanel.querySelectorAll(".empty-notice").length, 0,
       "The empty notice should not be displayed in this tabpanel.");
 
-    is(tabpanel.querySelector("#request-params-box")
-      .hasAttribute("hidden"), false,
-      "The request params box should not be hidden.");
-    is(tabpanel.querySelector("#request-post-data-textarea-box")
-      .hasAttribute("hidden"), isJSON,
-      "The request post data textarea box should be hidden.");
+    ok(tabpanel.querySelector(".treeTable"),
+      "The request params box should be displayed.");
+    is(tabpanel.querySelector(".editor-mount") === null,
+      isJSON,
+      "The request post data editor should be not displayed.");
 
-    let paramsScope = tabpanel.querySelectorAll(".variables-view-scope")[0];
-    let payloadScope = tabpanel.querySelectorAll(".variables-view-scope")[1];
+    let treeSections = tabpanel.querySelectorAll(".tree-section");
 
-    is(paramsScope.querySelector(".name").getAttribute("value"),
+    is(treeSections[0].querySelector(".treeLabel").textContent,
       L10N.getStr("paramsQueryString"),
-      "The params scope doesn't have the correct title.");
-    is(payloadScope.querySelector(".name").getAttribute("value"),
+      "The query section doesn't have the correct title.");
+    is(treeSections[1].querySelector(".treeLabel").textContent,
       isJSON ? L10N.getStr("jsonScopeName") : L10N.getStr("paramsPostPayload"),
-      "The request payload scope doesn't have the correct title.");
+      "The post section doesn't have the correct title.");
 
-    is(paramsScope.querySelectorAll(".variables-view-variable .name")[0]
-      .getAttribute("value"),
-      queryStringParamName,
+    let labels = tabpanel
+      .querySelectorAll("tr:not(.tree-section) .treeLabelCell .treeLabel");
+    let values = tabpanel
+      .querySelectorAll("tr:not(.treeS-section) .treeValueCell .objectBox");
+
+    is(labels[0].textContent, queryStringParamName,
       "The first query string param name was incorrect.");
-    is(paramsScope.querySelectorAll(".variables-view-variable .value")[0]
-      .getAttribute("value"),
-      queryStringParamValue,
+    is(values[0].textContent, queryStringParamValue,
       "The first query string param value was incorrect.");
 
     if (isJSON) {
       let requestPayloadObject = JSON.parse(requestPayload);
       let requestPairs = Object.keys(requestPayloadObject)
         .map(k => [k, requestPayloadObject[k]]);
-      let displayedNames = payloadScope.querySelectorAll(
-        ".variables-view-property.variable-or-property .name");
-      let displayedValues = payloadScope.querySelectorAll(
-        ".variables-view-property.variable-or-property .value");
-      for (let i = 0; i < requestPairs.length; i++) {
+      for (let i = 1; i < requestPairs.length; i++) {
         let [requestPayloadName, requestPayloadValue] = requestPairs[i];
-        is(requestPayloadName, displayedNames[i].getAttribute("value"),
+        is(requestPayloadName, labels[i].textContent,
           "JSON property name " + i + " should be displayed correctly");
-        is('"' + requestPayloadValue + '"', displayedValues[i].getAttribute("value"),
+        is('"' + requestPayloadValue + '"', values[i].textContent,
           "JSON property value " + i + " should be displayed correctly");
       }
     } else {
-      let editor = yield NetMonitorView.editor("#request-post-data-textarea");
-      is(editor.getText(), requestPayload,
+      let editor = editorFrames[0].contentDocument.querySelector(".CodeMirror-code");
+      ok(editor.textContent.includes(requestPayload),
         "The text shown in the source editor is incorrect.");
-      is(editor.getMode(), Editor.modes[editorMode],
-        "The mode active in the source editor is incorrect.");
     }
   }
 
-  function testParamsTab3(queryStringParamName, queryStringParamValue) {
+  function testParamsTab3() {
     let tabpanel = document.querySelectorAll("#details-pane tabpanel")[2];
 
-    is(tabpanel.querySelectorAll(".variables-view-scope").length, 0,
-      "The number of param scopes displayed in this tabpanel is incorrect.");
-    is(tabpanel.querySelectorAll(".variable-or-property").length, 0,
-      "The number of param values displayed in this tabpanel is incorrect.");
-    is(tabpanel.querySelectorAll(".variables-view-empty-notice").length, 1,
+    is(tabpanel.querySelectorAll(".tree-section").length, 0,
+      "The number of param tree sections displayed in this tabpanel is incorrect.");
+    is(tabpanel.querySelectorAll("tr:not(.tree-section).treeRow").length, 0,
+      "The number of param rows displayed in this tabpanel is incorrect.");
+    is(tabpanel.querySelectorAll(".empty-notice").length, 1,
       "The empty notice should be displayed in this tabpanel.");
 
-    is(tabpanel.querySelector("#request-params-box")
-      .hasAttribute("hidden"), false,
-      "The request params box should not be hidden.");
-    is(tabpanel.querySelector("#request-post-data-textarea-box")
-      .hasAttribute("hidden"), true,
-      "The request post data textarea box should be hidden.");
+    ok(!tabpanel.querySelector(".treeTable"),
+      "The request params box should be hidden.");
+    ok(!tabpanel.querySelector(".editor-mount iframe"),
+      "The request post data editor should be hidden.");
   }
 });
--- a/devtools/client/netmonitor/test/browser_net_post-data-01.js
+++ b/devtools/client/netmonitor/test/browser_net_post-data-01.js
@@ -8,21 +8,20 @@
  */
 
 add_task(function* () {
   let { L10N } = require("devtools/client/netmonitor/l10n");
 
   let { tab, monitor } = yield initNetMonitor(POST_DATA_URL);
   info("Starting test... ");
 
-  let { document, EVENTS, Editor, NetMonitorView } = monitor.panelWin;
-  let { RequestsMenu, NetworkDetails } = NetMonitorView;
+  let { document, NetMonitorView } = monitor.panelWin;
+  let { RequestsMenu } = NetMonitorView;
 
   RequestsMenu.lazyUpdate = false;
-  NetworkDetails._params.lazyEmpty = false;
 
   let wait = waitForNetworkEvents(monitor, 0, 2);
   yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
     content.wrappedJSObject.performRequests();
   });
   yield wait;
 
   verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(0),
@@ -39,128 +38,99 @@ add_task(function* () {
       status: 200,
       statusText: "Och Aye",
       type: "plain",
       fullMimeType: "text/plain; charset=utf-8",
       size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 12),
       time: true
     });
 
-  let onEvent = monitor.panelWin.once(EVENTS.TAB_UPDATED);
+  // Wait for all tree sections updated by react
+  wait = waitForDOM(document, "#params-tabpanel .tree-section", 2);
   EventUtils.sendMouseEvent({ type: "mousedown" },
     document.getElementById("details-pane-toggle"));
   EventUtils.sendMouseEvent({ type: "mousedown" },
     document.querySelectorAll("#details-pane tab")[2]);
-  yield onEvent;
+  yield wait;
   yield testParamsTab("urlencoded");
 
-  onEvent = monitor.panelWin.once(EVENTS.TAB_UPDATED);
+  // Wait for all tree sections and editor updated by react
+  let waitForSections = waitForDOM(document, "#params-tabpanel .tree-section", 2);
+  let waitForEditor = waitForDOM(document, "#params-tabpanel .editor-mount iframe");
   RequestsMenu.selectedIndex = 1;
-  yield onEvent;
+  let [, editorFrames] = yield Promise.all([waitForSections, waitForEditor]);
+  yield once(editorFrames[0], "DOMContentLoaded");
+  yield waitForDOM(editorFrames[0].contentDocument, ".CodeMirror-code");
   yield testParamsTab("multipart");
 
   return teardown(monitor);
 
   function* testParamsTab(type) {
     let tabEl = document.querySelectorAll("#details-pane tab")[2];
     let tabpanel = document.querySelectorAll("#details-pane tabpanel")[2];
 
     is(tabEl.getAttribute("selected"), "true",
       "The params tab in the network details pane should be selected.");
 
     function checkVisibility(box) {
-      is(tabpanel.querySelector("#request-params-box")
-        .hasAttribute("hidden"), !box.includes("params"),
-        "The request params box doesn't have the indended visibility.");
-      is(tabpanel.querySelector("#request-post-data-textarea-box")
-        .hasAttribute("hidden"), !box.includes("textarea"),
-        "The request post data textarea box doesn't have the indended visibility.");
+      is(!tabpanel.querySelector(".treeTable"), !box.includes("params"),
+        "The request params doesn't have the indended visibility.");
+      is(tabpanel.querySelector(".editor-mount") === null,
+        !box.includes("editor"),
+        "The request post data doesn't have the indended visibility.");
     }
 
-    is(tabpanel.querySelectorAll(".variables-view-scope").length, 2,
-      "There should be 2 param scopes displayed in this tabpanel.");
-    is(tabpanel.querySelectorAll(".variables-view-empty-notice").length, 0,
+    is(tabpanel.querySelectorAll(".tree-section").length, 2,
+      "There should be 2 tree sections displayed in this tabpanel.");
+    is(tabpanel.querySelectorAll(".empty-notice").length, 0,
       "The empty notice should not be displayed in this tabpanel.");
 
-    let queryScope = tabpanel.querySelectorAll(".variables-view-scope")[0];
-    let postScope = tabpanel.querySelectorAll(".variables-view-scope")[1];
+    let treeSections = tabpanel.querySelectorAll(".tree-section");
 
-    is(queryScope.querySelector(".name").getAttribute("value"),
+    is(treeSections[0].querySelector(".treeLabel").textContent,
       L10N.getStr("paramsQueryString"),
-      "The query scope doesn't have the correct title.");
+      "The query section doesn't have the correct title.");
 
-    is(postScope.querySelector(".name").getAttribute("value"),
+    is(treeSections[1].querySelector(".treeLabel").textContent,
       L10N.getStr(type == "urlencoded" ? "paramsFormData" : "paramsPostPayload"),
-      "The post scope doesn't have the correct title.");
+      "The post section doesn't have the correct title.");
 
-    is(queryScope.querySelectorAll(".variables-view-variable .name")[0]
-      .getAttribute("value"),
-      "foo", "The first query param name was incorrect.");
-    is(queryScope.querySelectorAll(".variables-view-variable .value")[0]
-      .getAttribute("value"),
-      "\"bar\"", "The first query param value was incorrect.");
-    is(queryScope.querySelectorAll(".variables-view-variable .name")[1]
-      .getAttribute("value"),
-      "baz", "The second query param name was incorrect.");
-    is(queryScope.querySelectorAll(".variables-view-variable .value")[1]
-      .getAttribute("value"),
-      "\"42\"", "The second query param value was incorrect.");
-    is(queryScope.querySelectorAll(".variables-view-variable .name")[2]
-      .getAttribute("value"),
-      "type", "The third query param name was incorrect.");
-    is(queryScope.querySelectorAll(".variables-view-variable .value")[2]
-      .getAttribute("value"),
-      "\"" + type + "\"", "The third query param value was incorrect.");
+    let labels = tabpanel.querySelectorAll("tr:not(.tree-section) .treeLabelCell .treeLabel");
+    let values = tabpanel.querySelectorAll("tr:not(.tree-section) .treeValueCell .objectBox");
+
+    is(labels[0].textContent, "foo", "The first query param name was incorrect.");
+    is(values[0].textContent, "\"bar\"", "The first query param value was incorrect.");
+    is(labels[1].textContent, "baz", "The second query param name was incorrect.");
+    is(values[1].textContent, "\"42\"", "The second query param value was incorrect.");
+    is(labels[2].textContent, "type", "The third query param name was incorrect.");
+    is(values[2].textContent, "\"" + type + "\"", "The third query param value was incorrect.");
 
     if (type == "urlencoded") {
       checkVisibility("params");
-
-      is(tabpanel.querySelectorAll(".variables-view-variable").length, 5,
-        "There should be 5 param values displayed in this tabpanel.");
-      is(queryScope.querySelectorAll(".variables-view-variable").length, 3,
-        "There should be 3 param values displayed in the query scope.");
-      is(postScope.querySelectorAll(".variables-view-variable").length, 2,
-        "There should be 2 param values displayed in the post scope.");
+      is(labels.length, 5, "There should be 5 param values displayed in this tabpanel.");
+      is(labels[3].textContent, "foo", "The first post param name was incorrect.");
+      is(values[3].textContent, "\"bar\"", "The first post param value was incorrect.");
+      is(labels[4].textContent, "baz", "The second post param name was incorrect.");
+      is(values[4].textContent, "\"123\"", "The second post param value was incorrect.");
+    } else {
+      checkVisibility("params editor");
 
-      is(postScope.querySelectorAll(".variables-view-variable .name")[0]
-        .getAttribute("value"),
-        "foo", "The first post param name was incorrect.");
-      is(postScope.querySelectorAll(".variables-view-variable .value")[0]
-        .getAttribute("value"),
-        "\"bar\"", "The first post param value was incorrect.");
-      is(postScope.querySelectorAll(".variables-view-variable .name")[1]
-        .getAttribute("value"),
-        "baz", "The second post param name was incorrect.");
-      is(postScope.querySelectorAll(".variables-view-variable .value")[1]
-        .getAttribute("value"),
-        "\"123\"", "The second post param value was incorrect.");
-    } else {
-      checkVisibility("params textarea");
+      is(labels.length, 3, "There should be 3 param values displayed in this tabpanel.");
 
-      is(tabpanel.querySelectorAll(".variables-view-variable").length, 3,
-        "There should be 3 param values displayed in this tabpanel.");
-      is(queryScope.querySelectorAll(".variables-view-variable").length, 3,
-        "There should be 3 param values displayed in the query scope.");
-      is(postScope.querySelectorAll(".variables-view-variable").length, 0,
-        "There should be 0 param values displayed in the post scope.");
-
-      let editor = yield NetMonitorView.editor("#request-post-data-textarea");
-      let text = editor.getText();
+      let text = editorFrames[0].contentDocument.querySelector(".CodeMirror-code").textContent;
 
       ok(text.includes("Content-Disposition: form-data; name=\"text\""),
         "The text shown in the source editor is incorrect (1.1).");
       ok(text.includes("Content-Disposition: form-data; name=\"email\""),
         "The text shown in the source editor is incorrect (2.1).");
       ok(text.includes("Content-Disposition: form-data; name=\"range\""),
         "The text shown in the source editor is incorrect (3.1).");
       ok(text.includes("Content-Disposition: form-data; name=\"Custom field\""),
         "The text shown in the source editor is incorrect (4.1).");
       ok(text.includes("Some text..."),
         "The text shown in the source editor is incorrect (2.2).");
       ok(text.includes("42"),
         "The text shown in the source editor is incorrect (3.2).");
       ok(text.includes("Extra data"),
         "The text shown in the source editor is incorrect (4.2).");
-      is(editor.getMode(), Editor.modes.text,
-        "The mode active in the source editor is incorrect.");
     }
   }
 });
--- a/devtools/client/netmonitor/test/browser_net_post-data-02.js
+++ b/devtools/client/netmonitor/test/browser_net_post-data-02.js
@@ -9,65 +9,55 @@
  */
 
 add_task(function* () {
   let { L10N } = require("devtools/client/netmonitor/l10n");
 
   let { tab, monitor } = yield initNetMonitor(POST_RAW_URL);
   info("Starting test... ");
 
-  let { document, EVENTS, NetMonitorView } = monitor.panelWin;
-  let { RequestsMenu, NetworkDetails } = NetMonitorView;
+  let { document, NetMonitorView } = monitor.panelWin;
+  let { RequestsMenu } = NetMonitorView;
 
   RequestsMenu.lazyUpdate = false;
-  NetworkDetails._params.lazyEmpty = false;
 
   let wait = waitForNetworkEvents(monitor, 0, 1);
   yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
     content.wrappedJSObject.performRequests();
   });
   yield wait;
 
-  let onEvent = monitor.panelWin.once(EVENTS.TAB_UPDATED);
-  NetMonitorView.toggleDetailsPane({ visible: true }, 2);
-  RequestsMenu.selectedIndex = 0;
-  yield onEvent;
-
-  let tabEl = document.querySelectorAll("#event-details-pane tab")[2];
-  let tabpanel = document.querySelectorAll("#event-details-pane tabpanel")[2];
-
-  is(tabEl.getAttribute("selected"), "true",
-    "The params tab in the network details pane should be selected.");
+  // Wait for all tree view updated by react
+  wait = waitForDOM(document, "#params-tabpanel .tree-section");
+  EventUtils.sendMouseEvent({ type: "mousedown" },
+    document.getElementById("details-pane-toggle"));
+  EventUtils.sendMouseEvent({ type: "mousedown" },
+    document.querySelectorAll("#details-pane tab")[2]);
+  yield wait;
 
-  is(tabpanel.querySelector("#request-params-box")
-    .hasAttribute("hidden"), false,
-    "The request params box doesn't have the indended visibility.");
-  is(tabpanel.querySelector("#request-post-data-textarea-box")
-    .hasAttribute("hidden"), true,
-    "The request post data textarea box doesn't have the indended visibility.");
+  let tabpanel = document.querySelectorAll("#details-pane tabpanel")[2];
 
-  is(tabpanel.querySelectorAll(".variables-view-scope").length, 1,
-    "There should be 1 param scopes displayed in this tabpanel.");
-  is(tabpanel.querySelectorAll(".variables-view-empty-notice").length, 0,
+  ok(tabpanel.querySelector(".treeTable"),
+    "The request params doesn't have the indended visibility.");
+  ok(tabpanel.querySelector(".editor-mount") === null,
+    "The request post data doesn't have the indended visibility.");
+
+  is(tabpanel.querySelectorAll(".tree-section").length, 1,
+    "There should be 1 tree sections displayed in this tabpanel.");
+  is(tabpanel.querySelectorAll(".empty-notice").length, 0,
     "The empty notice should not be displayed in this tabpanel.");
 
-  let postScope = tabpanel.querySelectorAll(".variables-view-scope")[0];
-  is(postScope.querySelector(".name").getAttribute("value"),
+  is(tabpanel.querySelector(".tree-section .treeLabel").textContent,
     L10N.getStr("paramsFormData"),
-    "The post scope doesn't have the correct title.");
+    "The post section doesn't have the correct title.");
 
-  is(postScope.querySelectorAll(".variables-view-variable").length, 2,
-    "There should be 2 param values displayed in the post scope.");
-  is(postScope.querySelectorAll(".variables-view-variable .name")[0]
-    .getAttribute("value"),
-    "foo", "The first query param name was incorrect.");
-  is(postScope.querySelectorAll(".variables-view-variable .value")[0]
-    .getAttribute("value"),
-    "\"bar\"", "The first query param value was incorrect.");
-  is(postScope.querySelectorAll(".variables-view-variable .name")[1]
-    .getAttribute("value"),
-    "baz", "The second query param name was incorrect.");
-  is(postScope.querySelectorAll(".variables-view-variable .value")[1]
-    .getAttribute("value"),
-    "\"123\"", "The second query param value was incorrect.");
+  let labels = tabpanel
+    .querySelectorAll("tr:not(.tree-section) .treeLabelCell .treeLabel");
+  let values = tabpanel
+    .querySelectorAll("tr:not(.tree-section) .treeValueCell .objectBox");
+
+  is(labels[0].textContent, "foo", "The first query param name was incorrect.");
+  is(values[0].textContent, "\"bar\"", "The first query param value was incorrect.");
+  is(labels[1].textContent, "baz", "The second query param name was incorrect.");
+  is(values[1].textContent, "\"123\"", "The second query param value was incorrect.");
 
   return teardown(monitor);
 });
--- a/devtools/client/netmonitor/test/browser_net_post-data-03.js
+++ b/devtools/client/netmonitor/test/browser_net_post-data-03.js
@@ -9,31 +9,34 @@
  */
 
 add_task(function* () {
   let { L10N } = require("devtools/client/netmonitor/l10n");
 
   let { tab, monitor } = yield initNetMonitor(POST_RAW_WITH_HEADERS_URL);
   info("Starting test... ");
 
-  let { document, EVENTS, NetMonitorView } = monitor.panelWin;
+  let { document, NetMonitorView } = monitor.panelWin;
   let { RequestsMenu } = NetMonitorView;
 
   RequestsMenu.lazyUpdate = false;
 
   let wait = waitForNetworkEvents(monitor, 0, 1);
   yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
     content.wrappedJSObject.performRequests();
   });
   yield wait;
 
-  let onEvent = monitor.panelWin.once(EVENTS.TAB_UPDATED);
-  NetMonitorView.toggleDetailsPane({ visible: true });
-  RequestsMenu.selectedIndex = 0;
-  yield onEvent;
+  // Wait for all tree view updated by react
+  wait = waitForDOM(document, "#headers-tabpanel .variables-view-scope", 3);
+  EventUtils.sendMouseEvent({ type: "mousedown" },
+    document.getElementById("details-pane-toggle"));
+  EventUtils.sendMouseEvent({ type: "mousedown" },
+    document.querySelectorAll("#details-pane tab")[0]);
+  yield wait;
 
   let tabEl = document.querySelectorAll("#details-pane tab")[0];
   let tabpanel = document.querySelectorAll("#details-pane tabpanel")[0];
   let requestFromUploadScope = tabpanel.querySelectorAll(".variables-view-scope")[2];
 
   is(tabEl.getAttribute("selected"), "true",
     "The headers tab in the network details pane should be selected.");
   is(tabpanel.querySelectorAll(".variables-view-scope").length, 3,
@@ -55,44 +58,37 @@ add_task(function* () {
     "The first request header value was incorrect.");
   is(requestFromUploadScope.querySelectorAll(".variables-view-variable .name")[1]
     .getAttribute("value"),
     "custom-header", "The second request header name was incorrect.");
   is(requestFromUploadScope.querySelectorAll(".variables-view-variable .value")[1]
     .getAttribute("value"),
     "\"hello world!\"", "The second request header value was incorrect.");
 
-  onEvent = monitor.panelWin.once(EVENTS.TAB_UPDATED);
+  // Wait for all tree sections updated by react
+  wait = waitForDOM(document, "#params-tabpanel .tree-section");
   EventUtils.sendMouseEvent({ type: "mousedown" },
     document.querySelectorAll("#details-pane tab")[2]);
-  yield onEvent;
+  yield wait;
 
-  tabEl = document.querySelectorAll("#details-pane tab")[2];
   tabpanel = document.querySelectorAll("#details-pane tabpanel")[2];
-  let formDataScope = tabpanel.querySelectorAll(".variables-view-scope")[0];
 
-  is(tab.getAttribute("selected"), "true",
-    "The response tab in the network details pane should be selected.");
-  is(tabpanel.querySelectorAll(".variables-view-scope").length, 1,
-    "There should be 1 header scope displayed in this tabpanel.");
-
-  is(formDataScope.querySelector(".name").getAttribute("value"),
-    L10N.getStr("paramsFormData"),
-    "The form data scope doesn't have the correct title.");
+  ok(tabpanel.querySelector(".treeTable"),
+    "The params tree view should be displayed.");
+  ok(tabpanel.querySelector(".editor-mount") === null,
+    "The post data shouldn't be displayed.");
 
-  is(formDataScope.querySelectorAll(".variables-view-variable").length, 2,
-    "There should be 2 payload values displayed in the form data scope.");
+  is(tabpanel.querySelector(".tree-section .treeLabel").textContent,
+    L10N.getStr("paramsFormData"),
+    "The form data section doesn't have the correct title.");
 
-  is(formDataScope.querySelectorAll(".variables-view-variable .name")[0]
-    .getAttribute("value"),
-    "foo", "The first payload param name was incorrect.");
-  is(formDataScope.querySelectorAll(".variables-view-variable .value")[0]
-    .getAttribute("value"),
-    "\"bar\"", "The first payload param value was incorrect.");
-  is(formDataScope.querySelectorAll(".variables-view-variable .name")[1]
-    .getAttribute("value"),
-    "baz", "The second payload param name was incorrect.");
-  is(formDataScope.querySelectorAll(".variables-view-variable .value")[1]
-    .getAttribute("value"),
-    "\"123\"", "The second payload param value was incorrect.");
+  let labels = tabpanel
+    .querySelectorAll("tr:not(.tree-section) .treeLabelCell .treeLabel");
+  let values = tabpanel
+    .querySelectorAll("tr:not(.tree-section) .treeValueCell .objectBox");
+
+  is(labels[0].textContent, "foo", "The first payload param name was incorrect.");
+  is(values[0].textContent, "\"bar\"", "The first payload param value was incorrect.");
+  is(labels[1].textContent, "baz", "The second payload param name was incorrect.");
+  is(values[1].textContent, "\"123\"", "The second payload param value was incorrect.");
 
   return teardown(monitor);
 });
--- a/devtools/client/netmonitor/test/browser_net_post-data-04.js
+++ b/devtools/client/netmonitor/test/browser_net_post-data-04.js
@@ -9,66 +9,53 @@
  */
 
 add_task(function* () {
   let { L10N } = require("devtools/client/netmonitor/l10n");
 
   let { tab, monitor } = yield initNetMonitor(POST_JSON_URL);
   info("Starting test... ");
 
-  let { document, EVENTS, NetMonitorView } = monitor.panelWin;
-  let { RequestsMenu, NetworkDetails } = NetMonitorView;
+  let { document, NetMonitorView } = monitor.panelWin;
+  let { RequestsMenu } = NetMonitorView;
 
   RequestsMenu.lazyUpdate = false;
-  NetworkDetails._params.lazyEmpty = false;
 
   let wait = waitForNetworkEvents(monitor, 0, 1);
   yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
     content.wrappedJSObject.performRequests();
   });
   yield wait;
 
-  let onEvent = monitor.panelWin.once(EVENTS.TAB_UPDATED);
-  NetMonitorView.toggleDetailsPane({ visible: true }, 2);
-  RequestsMenu.selectedIndex = 0;
-  yield onEvent;
+  // Wait for all tree view updated by react
+  wait = waitForDOM(document, "#params-tabpanel .tree-section");
+  EventUtils.sendMouseEvent({ type: "mousedown" },
+    document.getElementById("details-pane-toggle"));
+  EventUtils.sendMouseEvent({ type: "mousedown" },
+    document.querySelectorAll("#details-pane tab")[2]);
+  yield wait;
 
-  let tabEl = document.querySelectorAll("#event-details-pane tab")[2];
   let tabpanel = document.querySelectorAll("#event-details-pane tabpanel")[2];
 
-  is(tabEl.getAttribute("selected"), "true",
-    "The params tab in the network details pane should be selected.");
+  ok(tabpanel.querySelector(".treeTable"),
+    "The request params doesn't have the indended visibility.");
+  ok(tabpanel.querySelector(".editor-mount") === null,
+    "The request post data doesn't have the indended visibility.");
 
-  is(tabpanel.querySelector("#request-params-box")
-    .hasAttribute("hidden"), false,
-    "The request params box doesn't have the intended visibility.");
-  is(tabpanel.querySelector("#request-post-data-textarea-box")
-    .hasAttribute("hidden"), true,
-    "The request post data textarea box doesn't have the intended visibility.");
-
-  is(tabpanel.querySelectorAll(".variables-view-scope").length, 1,
-    "There should be 1 param scopes displayed in this tabpanel.");
-  is(tabpanel.querySelectorAll(".variables-view-empty-notice").length, 0,
+  is(tabpanel.querySelectorAll(".tree-section").length, 1,
+    "There should be 1 tree sections displayed in this tabpanel.");
+  is(tabpanel.querySelectorAll(".empty-notice").length, 0,
     "The empty notice should not be displayed in this tabpanel.");
 
-  let jsonScope = tabpanel.querySelectorAll(".variables-view-scope")[0];
-  is(jsonScope.querySelector(".name").getAttribute("value"),
+  is(tabpanel.querySelector(".tree-section .treeLabel").textContent,
     L10N.getStr("jsonScopeName"),
-    "The JSON scope doesn't have the correct title.");
-
-  let valueScope = tabpanel.querySelector(
-    ".variables-view-scope > .variables-view-element-details");
+    "The JSON section doesn't have the correct title.");
 
-  is(valueScope.querySelectorAll(".variables-view-variable").length, 1,
-    "There should be 1 value displayed in the JSON scope.");
-  is(valueScope.querySelector(".variables-view-property .name")
-    .getAttribute("value"),
-    "a", "The JSON var name was incorrect.");
-  is(valueScope.querySelector(".variables-view-property .value")
-    .getAttribute("value"),
-    "1", "The JSON var value was incorrect.");
+  let labels = tabpanel
+    .querySelectorAll("tr:not(.tree-section) .treeLabelCell .treeLabel");
+  let values = tabpanel
+    .querySelectorAll("tr:not(.tree-section) .treeValueCell .objectBox");
 
-  let detailsParent = valueScope.querySelector(".variables-view-property .name")
-    .closest(".variables-view-element-details");
-  is(detailsParent.hasAttribute("open"), true, "The JSON value must be visible");
+  is(labels[0].textContent, "a", "The JSON var name was incorrect.");
+  is(values[0].textContent, "1", "The JSON var value was incorrect.");
 
   return teardown(monitor);
 });
--- a/devtools/client/netmonitor/test/browser_net_status-codes.js
+++ b/devtools/client/netmonitor/test/browser_net_status-codes.js
@@ -14,17 +14,16 @@ add_task(function* () {
 
   info("Starting test... ");
 
   let { document, EVENTS, NetMonitorView } = monitor.panelWin;
   let { RequestsMenu, NetworkDetails } = NetMonitorView;
   let requestItems = [];
 
   RequestsMenu.lazyUpdate = false;
-  NetworkDetails._params.lazyEmpty = false;
 
   const REQUEST_DATA = [
     {
       // request #0
       method: "GET",
       uri: STATUS_CODES_SJS + "?sts=100",
       details: {
         status: 101,
@@ -168,43 +167,42 @@ add_task(function* () {
 
   /**
    * A function that tests "Params" tab contains correct information.
    */
   function* testParams(data) {
     let tabpanel = document.querySelectorAll("#details-pane tabpanel")[2];
     let statusParamValue = data.uri.split("=").pop();
     let statusParamShownValue = "\"" + statusParamValue + "\"";
+    let treeSections = tabpanel.querySelectorAll(".tree-section");
 
-    is(tabpanel.querySelectorAll(".variables-view-scope").length, 1,
-      "There should be 1 param scope displayed in this tabpanel.");
-    is(tabpanel.querySelectorAll(".variable-or-property").length, 1,
-      "There should be 1 param value displayed in this tabpanel.");
-    is(tabpanel.querySelectorAll(".variables-view-empty-notice").length, 0,
+    is(treeSections.length, 1,
+      "There should be 1 param section displayed in this tabpanel.");
+    is(tabpanel.querySelectorAll("tr:not(.tree-section).treeRow").length, 1,
+      "There should be 1 param row displayed in this tabpanel.");
+    is(tabpanel.querySelectorAll(".empty-notice").length, 0,
       "The empty notice should not be displayed in this tabpanel.");
 
-    let paramsScope = tabpanel.querySelectorAll(".variables-view-scope")[0];
+    let labels = tabpanel
+      .querySelectorAll("tr:not(.tree-section) .treeLabelCell .treeLabel");
+    let values = tabpanel
+      .querySelectorAll("tr:not(.tree-section) .treeValueCell .objectBox");
 
-    is(paramsScope.querySelector(".name").getAttribute("value"),
+    is(treeSections[0].querySelector(".treeLabel").textContent,
       L10N.getStr("paramsQueryString"),
       "The params scope doesn't have the correct title.");
 
-    is(paramsScope.querySelectorAll(".variables-view-variable .name")[0]
-      .getAttribute("value"),
-      "sts", "The param name was incorrect.");
-    is(paramsScope.querySelectorAll(".variables-view-variable .value")[0]
-      .getAttribute("value"),
-      statusParamShownValue, "The param value was incorrect.");
+    is(labels[0].textContent, "sts", "The param name was incorrect.");
+    is(values[0].textContent, statusParamShownValue, "The param value was incorrect.");
 
-    is(tabpanel.querySelector("#request-params-box")
-      .hasAttribute("hidden"), false,
-      "The request params box should not be hidden.");
-    is(tabpanel.querySelector("#request-post-data-textarea-box")
-      .hasAttribute("hidden"), true,
-      "The request post data textarea box should be hidden.");
+    ok(tabpanel.querySelector(".treeTable"),
+      "The request params tree view should be displayed.");
+    is(tabpanel.querySelector(".editor-mount") === null,
+      true,
+      "The request post data editor should be hidden.");
   }
 
   /**
    * A helper that clicks on a specified request and returns a promise resolved
    * when NetworkDetails has been populated with the data of the given request.
    */
   function chooseRequest(index) {
     let onTabUpdated = monitor.panelWin.once(EVENTS.TAB_UPDATED);