Bug 1333383 - add test for netmonitor rendering JSON response with null;r=honza
authorJulian Descottes <jdescottes@mozilla.com>
Fri, 27 Jan 2017 19:59:38 +0100
changeset 332430 713e1811a14ff710f6cf0e5ad2643fb5786ad7e3
parent 332429 7305ca850fb34af24a4cc0585e1613ef81bb1390
child 332431 8f8290156d0b5b14a44bbc99060ea0b4b0ac2b7c
push id86529
push userjdescottes@mozilla.com
push dateFri, 03 Feb 2017 15:03:34 +0000
treeherdermozilla-inbound@713e1811a14f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershonza
bugs1333383
milestone54.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1333383 - add test for netmonitor rendering JSON response with null;r=honza MozReview-Commit-ID: GZvQnADkYoL
devtools/client/netmonitor/test/browser.ini
devtools/client/netmonitor/test/browser_net_json-null.js
devtools/client/netmonitor/test/head.js
devtools/client/netmonitor/test/html_json-basic.html
devtools/client/netmonitor/test/sjs_json-test-server.sjs
--- a/devtools/client/netmonitor/test/browser.ini
+++ b/devtools/client/netmonitor/test/browser.ini
@@ -12,16 +12,17 @@ support-files =
   html_cors-test-page.html
   html_custom-get-page.html
   html_cyrillic-test-page.html
   html_frame-test-page.html
   html_frame-subdocument.html
   html_filter-test-page.html
   html_infinite-get-page.html
   html_json-b64.html
+  html_json-basic.html
   html_json-custom-mime-test-page.html
   html_json-long-test-page.html
   html_json-malformed-test-page.html
   html_json-text-mime-test-page.html
   html_jsonp-test-page.html
   html_navigate-test-page.html
   html_params-test-page.html
   html_post-data-test-page.html
@@ -36,16 +37,17 @@ support-files =
   html_status-codes-test-page.html
   html_api-calls-test-page.html
   html_copy-as-curl.html
   html_curl-utils.html
   sjs_content-type-test-server.sjs
   sjs_cors-test-server.sjs
   sjs_https-redirect-test-server.sjs
   sjs_hsts-test-server.sjs
+  sjs_json-test-server.sjs
   sjs_simple-test-server.sjs
   sjs_sorting-test-server.sjs
   sjs_status-codes-test-server.sjs
   sjs_truncate-test-server.sjs
   test-image.png
   service-workers/status-codes.html
   service-workers/status-codes-service-worker.js
   !/devtools/client/framework/test/shared-head.js
@@ -102,16 +104,17 @@ skip-if = (os == 'linux' && debug && bit
 [browser_net_filter-02.js]
 [browser_net_filter-03.js]
 [browser_net_filter-04.js]
 [browser_net_footer-summary.js]
 [browser_net_html-preview.js]
 [browser_net_icon-preview.js]
 [browser_net_image-tooltip.js]
 [browser_net_json-b64.js]
+[browser_net_json-null.js]
 [browser_net_json-long.js]
 [browser_net_json-malformed.js]
 [browser_net_json_custom_mime.js]
 [browser_net_json_text_mime.js]
 [browser_net_jsonp.js]
 [browser_net_large-response.js]
 [browser_net_leak_on_tab_close.js]
 [browser_net_open_request_in_tab.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/netmonitor/test/browser_net_json-null.js
@@ -0,0 +1,78 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const { L10N } = require("devtools/client/netmonitor/l10n");
+
+/**
+ * Tests if JSON responses containing null values are properly displayed.
+ */
+
+add_task(function* () {
+  let { tab, monitor } = yield initNetMonitor(JSON_BASIC_URL + "?name=null");
+  info("Starting test... ");
+
+  let { document, NetMonitorView } = monitor.panelWin;
+  let { RequestsMenu } = NetMonitorView;
+
+  RequestsMenu.lazyUpdate = false;
+
+  let wait = waitForNetworkEvents(monitor, 1);
+  yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
+    content.wrappedJSObject.performRequests();
+  });
+  yield wait;
+
+  yield openResponsePanel(document);
+  checkResponsePanelDisplaysJSON(document);
+
+  let tabpanel = document.querySelector("#response-panel");
+  is(tabpanel.querySelectorAll(".tree-section").length, 1,
+    "There should be 1 tree sections displayed in this tabpanel.");
+  is(tabpanel.querySelectorAll(".treeRow:not(.tree-section)").length, 1,
+    "There should be 1 json properties displayed in this tabpanel.");
+  is(tabpanel.querySelectorAll(".empty-notice").length, 0,
+    "The empty notice should not be displayed in this tabpanel.");
+
+  let labels = tabpanel
+    .querySelectorAll("tr:not(.tree-section) .treeLabelCell .treeLabel");
+  let values = tabpanel
+    .querySelectorAll("tr:not(.tree-section) .treeValueCell .objectBox");
+
+  is(labels[0].textContent, "greeting", "The first json property name was incorrect.");
+  is(values[0].textContent, "null", "The first json property value was incorrect.");
+
+  yield teardown(monitor);
+});
+
+/**
+ * Helper to assert that the response panel found in the provided document is currently
+ * showing a preview of a JSON object.
+ */
+function checkResponsePanelDisplaysJSON(doc) {
+  let tabpanel = doc.querySelector("#response-panel");
+  is(tabpanel.querySelector(".response-error-header") === null, true,
+    "The response error header doesn't have the intended visibility.");
+  let jsonView = tabpanel.querySelector(".tree-section .treeLabel") || {};
+  is(jsonView.textContent === L10N.getStr("jsonScopeName"), true,
+    "The response json view has the intended visibility.");
+  is(tabpanel.querySelector(".editor-mount iframe") === null, true,
+    "The response editor doesn't have the intended visibility.");
+  is(tabpanel.querySelector(".response-image-box") === null, true,
+    "The response image box doesn't have the intended visibility.");
+}
+
+/**
+ * Open the netmonitor details panel and switch to the response tab.
+ * Returns a promise that will resolve when the response panel DOM element is available.
+ */
+function openResponsePanel(doc) {
+  let onReponsePanelReady = waitForDOM(doc, "#response-panel");
+  EventUtils.sendMouseEvent(
+    { type: "mousedown" },
+    doc.getElementById("details-pane-toggle")
+  );
+  doc.querySelector("#response-tab").click();
+  return onReponsePanelReady;
+}
--- a/devtools/client/netmonitor/test/head.js
+++ b/devtools/client/netmonitor/test/head.js
@@ -35,16 +35,17 @@ const POST_RAW_URL = EXAMPLE_URL + "html
 const POST_RAW_WITH_HEADERS_URL = EXAMPLE_URL + "html_post-raw-with-headers-test-page.html";
 const PARAMS_URL = EXAMPLE_URL + "html_params-test-page.html";
 const JSONP_URL = EXAMPLE_URL + "html_jsonp-test-page.html";
 const JSON_LONG_URL = EXAMPLE_URL + "html_json-long-test-page.html";
 const JSON_MALFORMED_URL = EXAMPLE_URL + "html_json-malformed-test-page.html";
 const JSON_CUSTOM_MIME_URL = EXAMPLE_URL + "html_json-custom-mime-test-page.html";
 const JSON_TEXT_MIME_URL = EXAMPLE_URL + "html_json-text-mime-test-page.html";
 const JSON_B64_URL = EXAMPLE_URL + "html_json-b64.html";
+const JSON_BASIC_URL = EXAMPLE_URL + "html_json-basic.html";
 const SORTING_URL = EXAMPLE_URL + "html_sorting-test-page.html";
 const FILTERING_URL = EXAMPLE_URL + "html_filter-test-page.html";
 const INFINITE_GET_URL = EXAMPLE_URL + "html_infinite-get-page.html";
 const CUSTOM_GET_URL = EXAMPLE_URL + "html_custom-get-page.html";
 const SINGLE_GET_URL = EXAMPLE_URL + "html_single-get-page.html";
 const STATISTICS_URL = EXAMPLE_URL + "html_statistics-test-page.html";
 const CURL_URL = EXAMPLE_URL + "html_copy-as-curl.html";
 const CURL_UTILS_URL = EXAMPLE_URL + "html_curl-utils.html";
new file mode 100644
--- /dev/null
+++ b/devtools/client/netmonitor/test/html_json-basic.html
@@ -0,0 +1,40 @@
+<!-- Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/ -->
+<!doctype html>
+
+<html>
+  <head>
+    <meta charset="utf-8"/>
+    <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
+    <meta http-equiv="Pragma" content="no-cache" />
+    <meta http-equiv="Expires" content="0" />
+    <title>Network Monitor test page</title>
+  </head>
+
+  <body>
+    <p>JSON request test page</p>
+    <p>Pass the JSON name (as supported by sjs_json-test-server.sjs) as a query parameter</p>
+
+    <script type="text/javascript">
+      function get(aAddress, aCallback) {
+        var xhr = new XMLHttpRequest();
+        xhr.open("GET", aAddress, true);
+
+        xhr.onreadystatechange = function() {
+          if (this.readyState == this.DONE) {
+            aCallback();
+          }
+        };
+        xhr.send(null);
+      }
+
+      function performRequests() {
+        // Forward the query parameter for this page to sjs_json-test-server
+        get("sjs_json-test-server.sjs" + window.location.search, function() {
+          // Done.
+        });
+      }
+    </script>
+  </body>
+
+</html>
new file mode 100644
--- /dev/null
+++ b/devtools/client/netmonitor/test/sjs_json-test-server.sjs
@@ -0,0 +1,22 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function handleRequest(request, response) {
+
+  response.setStatusLine(request.httpVersion, 200, "OK");
+  response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
+  response.setHeader("Pragma", "no-cache");
+  response.setHeader("Expires", "0");
+
+  response.setHeader("Content-Type", "application/json; charset=utf-8", false);
+
+  // This server checks the name parameter from the request to decide which JSON object to
+  // return.
+  let params = request.queryString.split("&");
+  let name = (params.filter((s) => s.includes("name="))[0] || "").split("=")[1];
+  switch (name) {
+    case "null":
+      response.write("{ \"greeting\": null }");
+      break;
+  }
+}