browser/devtools/netmonitor/test/head.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* Any copyright is dedicated to the Public Domain.
     2    http://creativecommons.org/publicdomain/zero/1.0/ */
     3 "use strict";
     5 const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
     7 let { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
     8 let { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
     9 let { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
    10 let { gDevTools } = Cu.import("resource:///modules/devtools/gDevTools.jsm", {});
    11 let { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
    12 let { CurlUtils } = Cu.import("resource:///modules/devtools/Curl.jsm", {});
    13 let TargetFactory = devtools.TargetFactory;
    14 let Toolbox = devtools.Toolbox;
    16 const EXAMPLE_URL = "http://example.com/browser/browser/devtools/netmonitor/test/";
    18 const SIMPLE_URL = EXAMPLE_URL + "html_simple-test-page.html";
    19 const NAVIGATE_URL = EXAMPLE_URL + "html_navigate-test-page.html";
    20 const CONTENT_TYPE_URL = EXAMPLE_URL + "html_content-type-test-page.html";
    21 const CONTENT_TYPE_WITHOUT_CACHE_URL = EXAMPLE_URL + "html_content-type-without-cache-test-page.html";
    22 const CYRILLIC_URL = EXAMPLE_URL + "html_cyrillic-test-page.html";
    23 const STATUS_CODES_URL = EXAMPLE_URL + "html_status-codes-test-page.html";
    24 const POST_DATA_URL = EXAMPLE_URL + "html_post-data-test-page.html";
    25 const POST_RAW_URL = EXAMPLE_URL + "html_post-raw-test-page.html";
    26 const POST_RAW_WITH_HEADERS_URL = EXAMPLE_URL + "html_post-raw-with-headers-test-page.html";
    27 const PARAMS_URL = EXAMPLE_URL + "html_params-test-page.html";
    28 const JSONP_URL = EXAMPLE_URL + "html_jsonp-test-page.html";
    29 const JSON_LONG_URL = EXAMPLE_URL + "html_json-long-test-page.html";
    30 const JSON_MALFORMED_URL = EXAMPLE_URL + "html_json-malformed-test-page.html";
    31 const JSON_CUSTOM_MIME_URL = EXAMPLE_URL + "html_json-custom-mime-test-page.html";
    32 const JSON_TEXT_MIME_URL = EXAMPLE_URL + "html_json-text-mime-test-page.html";
    33 const SORTING_URL = EXAMPLE_URL + "html_sorting-test-page.html";
    34 const FILTERING_URL = EXAMPLE_URL + "html_filter-test-page.html";
    35 const INFINITE_GET_URL = EXAMPLE_URL + "html_infinite-get-page.html";
    36 const CUSTOM_GET_URL = EXAMPLE_URL + "html_custom-get-page.html";
    37 const SINGLE_GET_URL = EXAMPLE_URL + "html_single-get-page.html";
    38 const STATISTICS_URL = EXAMPLE_URL + "html_statistics-test-page.html";
    39 const CURL_URL = EXAMPLE_URL + "html_copy-as-curl.html";
    40 const CURL_UTILS_URL = EXAMPLE_URL + "html_curl-utils.html";
    42 const SIMPLE_SJS = EXAMPLE_URL + "sjs_simple-test-server.sjs";
    43 const CONTENT_TYPE_SJS = EXAMPLE_URL + "sjs_content-type-test-server.sjs";
    44 const STATUS_CODES_SJS = EXAMPLE_URL + "sjs_status-codes-test-server.sjs";
    45 const SORTING_SJS = EXAMPLE_URL + "sjs_sorting-test-server.sjs";
    47 const TEST_IMAGE = EXAMPLE_URL + "test-image.png";
    48 const TEST_IMAGE_DATA_URI = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==";
    50 gDevTools.testing = true;
    51 SimpleTest.registerCleanupFunction(() => {
    52   gDevTools.testing = false;
    53 });
    55 // All tests are asynchronous.
    56 waitForExplicitFinish();
    58 const gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log");
    59 // To enable logging for try runs, just set the pref to true.
    60 Services.prefs.setBoolPref("devtools.debugger.log", false);
    62 // Always reset some prefs to their original values after the test finishes.
    63 const gDefaultFilters = Services.prefs.getCharPref("devtools.netmonitor.filters");
    65 registerCleanupFunction(() => {
    66   info("finish() was called, cleaning up...");
    68   Services.prefs.setBoolPref("devtools.debugger.log", gEnableLogging);
    69   Services.prefs.setCharPref("devtools.netmonitor.filters", gDefaultFilters);
    70 });
    72 function addTab(aUrl, aWindow) {
    73   info("Adding tab: " + aUrl);
    75   let deferred = promise.defer();
    76   let targetWindow = aWindow || window;
    77   let targetBrowser = targetWindow.gBrowser;
    79   targetWindow.focus();
    80   let tab = targetBrowser.selectedTab = targetBrowser.addTab(aUrl);
    81   let browser = tab.linkedBrowser;
    83   browser.addEventListener("load", function onLoad() {
    84     browser.removeEventListener("load", onLoad, true);
    85     deferred.resolve(tab);
    86   }, true);
    88   return deferred.promise;
    89 }
    91 function removeTab(aTab, aWindow) {
    92   info("Removing tab.");
    94   let targetWindow = aWindow || window;
    95   let targetBrowser = targetWindow.gBrowser;
    97   targetBrowser.removeTab(aTab);
    98 }
   100 function initNetMonitor(aUrl, aWindow) {
   101   info("Initializing a network monitor pane.");
   103   return addTab(aUrl).then((aTab) => {
   104     info("Net tab added successfully: " + aUrl);
   106     let deferred = promise.defer();
   107     let debuggee = aTab.linkedBrowser.contentWindow.wrappedJSObject;
   108     let target = TargetFactory.forTab(aTab);
   110     gDevTools.showToolbox(target, "netmonitor").then((aToolbox) => {
   111       info("Netork monitor pane shown successfully.");
   113       let monitor = aToolbox.getCurrentPanel();
   114       deferred.resolve([aTab, debuggee, monitor]);
   115     });
   117     return deferred.promise;
   118   });
   119 }
   121 function restartNetMonitor(aMonitor, aNewUrl) {
   122   info("Restarting the specified network monitor.");
   124   let deferred = promise.defer();
   125   let tab = aMonitor.target.tab;
   126   let url = aNewUrl || tab.linkedBrowser.contentWindow.wrappedJSObject.location.href;
   128   aMonitor.once("destroyed", () => initNetMonitor(url).then(deferred.resolve));
   129   removeTab(tab);
   131   return deferred.promise;
   132 }
   134 function teardown(aMonitor) {
   135   info("Destroying the specified network monitor.");
   137   let deferred = promise.defer();
   138   let tab = aMonitor.target.tab;
   140   aMonitor.once("destroyed", () => executeSoon(deferred.resolve));
   141   removeTab(tab);
   143   return deferred.promise;
   144 }
   146 function waitForNetworkEvents(aMonitor, aGetRequests, aPostRequests = 0) {
   147   let deferred = promise.defer();
   149   let panel = aMonitor.panelWin;
   150   let genericEvents = 0;
   151   let postEvents = 0;
   153   function onGenericEvent() {
   154     genericEvents++;
   155     maybeResolve();
   156   }
   158   function onPostEvent() {
   159     postEvents++;
   160     maybeResolve();
   161   }
   163   function maybeResolve() {
   164     info("> Network events progress: " +
   165       genericEvents + "/" + ((aGetRequests + aPostRequests) * 13) + ", " +
   166       postEvents + "/" + (aPostRequests * 2));
   168     // There are 15 updates which need to be fired for a request to be
   169     // considered finished. RequestPostData isn't fired for non-POST requests.
   170     if (genericEvents == (aGetRequests + aPostRequests) * 13 &&
   171         postEvents == aPostRequests * 2) {
   173       panel.off(panel.EVENTS.UPDATING_REQUEST_HEADERS, onGenericEvent);
   174       panel.off(panel.EVENTS.RECEIVED_REQUEST_HEADERS, onGenericEvent);
   175       panel.off(panel.EVENTS.UPDATING_REQUEST_COOKIES, onGenericEvent);
   176       panel.off(panel.EVENTS.RECEIVED_REQUEST_COOKIES, onGenericEvent);
   177       panel.off(panel.EVENTS.UPDATING_REQUEST_POST_DATA, onPostEvent);
   178       panel.off(panel.EVENTS.RECEIVED_REQUEST_POST_DATA, onPostEvent);
   179       panel.off(panel.EVENTS.UPDATING_RESPONSE_HEADERS, onGenericEvent);
   180       panel.off(panel.EVENTS.RECEIVED_RESPONSE_HEADERS, onGenericEvent);
   181       panel.off(panel.EVENTS.UPDATING_RESPONSE_COOKIES, onGenericEvent);
   182       panel.off(panel.EVENTS.RECEIVED_RESPONSE_COOKIES, onGenericEvent);
   183       panel.off(panel.EVENTS.STARTED_RECEIVING_RESPONSE, onGenericEvent);
   184       panel.off(panel.EVENTS.UPDATING_RESPONSE_CONTENT, onGenericEvent);
   185       panel.off(panel.EVENTS.RECEIVED_RESPONSE_CONTENT, onGenericEvent);
   186       panel.off(panel.EVENTS.UPDATING_EVENT_TIMINGS, onGenericEvent);
   187       panel.off(panel.EVENTS.RECEIVED_EVENT_TIMINGS, onGenericEvent);
   189       executeSoon(deferred.resolve);
   190     }
   191   }
   193   panel.on(panel.EVENTS.UPDATING_REQUEST_HEADERS, onGenericEvent);
   194   panel.on(panel.EVENTS.RECEIVED_REQUEST_HEADERS, onGenericEvent);
   195   panel.on(panel.EVENTS.UPDATING_REQUEST_COOKIES, onGenericEvent);
   196   panel.on(panel.EVENTS.RECEIVED_REQUEST_COOKIES, onGenericEvent);
   197   panel.on(panel.EVENTS.UPDATING_REQUEST_POST_DATA, onPostEvent);
   198   panel.on(panel.EVENTS.RECEIVED_REQUEST_POST_DATA, onPostEvent);
   199   panel.on(panel.EVENTS.UPDATING_RESPONSE_HEADERS, onGenericEvent);
   200   panel.on(panel.EVENTS.RECEIVED_RESPONSE_HEADERS, onGenericEvent);
   201   panel.on(panel.EVENTS.UPDATING_RESPONSE_COOKIES, onGenericEvent);
   202   panel.on(panel.EVENTS.RECEIVED_RESPONSE_COOKIES, onGenericEvent);
   203   panel.on(panel.EVENTS.STARTED_RECEIVING_RESPONSE, onGenericEvent);
   204   panel.on(panel.EVENTS.UPDATING_RESPONSE_CONTENT, onGenericEvent);
   205   panel.on(panel.EVENTS.RECEIVED_RESPONSE_CONTENT, onGenericEvent);
   206   panel.on(panel.EVENTS.UPDATING_EVENT_TIMINGS, onGenericEvent);
   207   panel.on(panel.EVENTS.RECEIVED_EVENT_TIMINGS, onGenericEvent);
   209   return deferred.promise;
   210 }
   212 function verifyRequestItemTarget(aRequestItem, aMethod, aUrl, aData = {}) {
   213   info("> Verifying: " + aMethod + " " + aUrl + " " + aData.toSource());
   214   // This bloats log sizes significantly in automation (bug 992485)
   215   //info("> Request: " + aRequestItem.attachment.toSource());
   217   let requestsMenu = aRequestItem.ownerView;
   218   let widgetIndex = requestsMenu.indexOfItem(aRequestItem);
   219   let visibleIndex = requestsMenu.visibleItems.indexOf(aRequestItem);
   221   info("Widget index of item: " + widgetIndex);
   222   info("Visible index of item: " + visibleIndex);
   224   let { fuzzyUrl, status, statusText, type, fullMimeType, size, time } = aData;
   225   let { attachment, target } = aRequestItem
   227   let uri = Services.io.newURI(aUrl, null, null).QueryInterface(Ci.nsIURL);
   228   let name = uri.fileName || "/";
   229   let query = uri.query;
   230   let hostPort = uri.hostPort;
   232   if (fuzzyUrl) {
   233     ok(attachment.method.startsWith(aMethod), "The attached method is incorrect.");
   234     ok(attachment.url.startsWith(aUrl), "The attached url is incorrect.");
   235   } else {
   236     is(attachment.method, aMethod, "The attached method is incorrect.");
   237     is(attachment.url, aUrl, "The attached url is incorrect.");
   238   }
   240   is(target.querySelector(".requests-menu-method").getAttribute("value"),
   241     aMethod, "The displayed method is incorrect.");
   243   if (fuzzyUrl) {
   244     ok(target.querySelector(".requests-menu-file").getAttribute("value").startsWith(
   245       name + (query ? "?" + query : "")), "The displayed file is incorrect.");
   246     ok(target.querySelector(".requests-menu-file").getAttribute("tooltiptext").startsWith(
   247       name + (query ? "?" + query : "")), "The tooltip file is incorrect.");
   248   } else {
   249     is(target.querySelector(".requests-menu-file").getAttribute("value"),
   250       name + (query ? "?" + query : ""), "The displayed file is incorrect.");
   251     is(target.querySelector(".requests-menu-file").getAttribute("tooltiptext"),
   252       name + (query ? "?" + query : ""), "The tooltip file is incorrect.");
   253   }
   255   is(target.querySelector(".requests-menu-domain").getAttribute("value"),
   256     hostPort, "The displayed domain is incorrect.");
   257   is(target.querySelector(".requests-menu-domain").getAttribute("tooltiptext"),
   258     hostPort, "The tooltip domain is incorrect.");
   260   if (status !== undefined) {
   261     let value = target.querySelector(".requests-menu-status").getAttribute("code");
   262     let codeValue = target.querySelector(".requests-menu-status-code").getAttribute("value");
   263     let tooltip = target.querySelector(".requests-menu-status-and-method").getAttribute("tooltiptext");
   264     info("Displayed status: " + value);
   265     info("Displayed code: " + codeValue);
   266     info("Tooltip status: " + tooltip);
   267     is(value, status, "The displayed status is incorrect.");
   268     is(codeValue, status, "The displayed status code is incorrect.");
   269     is(tooltip, status + " " + statusText, "The tooltip status is incorrect.");
   270   }
   271   if (type !== undefined) {
   272     let value = target.querySelector(".requests-menu-type").getAttribute("value");
   273     let tooltip = target.querySelector(".requests-menu-type").getAttribute("tooltiptext");
   274     info("Displayed type: " + value);
   275     info("Tooltip type: " + tooltip);
   276     is(value, type, "The displayed type is incorrect.");
   277     is(tooltip, fullMimeType, "The tooltip type is incorrect.");
   278   }
   279   if (size !== undefined) {
   280     let value = target.querySelector(".requests-menu-size").getAttribute("value");
   281     let tooltip = target.querySelector(".requests-menu-size").getAttribute("tooltiptext");
   282     info("Displayed size: " + value);
   283     info("Tooltip size: " + tooltip);
   284     is(value, size, "The displayed size is incorrect.");
   285     is(tooltip, size, "The tooltip size is incorrect.");
   286   }
   287   if (time !== undefined) {
   288     let value = target.querySelector(".requests-menu-timings-total").getAttribute("value");
   289     let tooltip = target.querySelector(".requests-menu-timings-total").getAttribute("tooltiptext");
   290     info("Displayed time: " + value);
   291     info("Tooltip time: " + tooltip);
   292     ok(~~(value.match(/[0-9]+/)) >= 0, "The displayed time is incorrect.");
   293     ok(~~(tooltip.match(/[0-9]+/)) >= 0, "The tooltip time is incorrect.");
   294   }
   296   if (visibleIndex != -1) {
   297     if (visibleIndex % 2 == 0) {
   298       ok(aRequestItem.target.hasAttribute("even"),
   299         "Unexpected 'even' attribute for " + aRequestItem.value);
   300       ok(!aRequestItem.target.hasAttribute("odd"),
   301         "Unexpected 'odd' attribute for " + aRequestItem.value);
   302     } else {
   303       ok(!aRequestItem.target.hasAttribute("even"),
   304         "Unexpected 'even' attribute for " + aRequestItem.value);
   305       ok(aRequestItem.target.hasAttribute("odd"),
   306         "Unexpected 'odd' attribute for " + aRequestItem.value);
   307     }
   308   }
   309 }
   311 /**
   312  * Helper function for waiting for an event to fire before resolving a promise.
   313  * Example: waitFor(aMonitor.panelWin, aMonitor.panelWin.EVENTS.TAB_UPDATED);
   314  *
   315  * @param object subject
   316  *        The event emitter object that is being listened to.
   317  * @param string eventName
   318  *        The name of the event to listen to.
   319  * @return object
   320  *        Returns a promise that resolves upon firing of the event.
   321  */
   322 function waitFor (subject, eventName) {
   323   let deferred = promise.defer();
   324   subject.once(eventName, deferred.resolve);
   325   return deferred.promise;
   326 }
   328 /**
   329  * Tests if a button for a filter of given type is the only one checked.
   330  *
   331  * @param string aFilterType
   332  *        The type of the filter that should be the only one checked.
   333  */
   334 function testFilterButtons(aMonitor, aFilterType) {
   335   let doc = aMonitor.panelWin.document;
   336   let target = doc.querySelector("#requests-menu-filter-" + aFilterType + "-button");
   337   let buttons = doc.querySelectorAll(".requests-menu-footer-button");
   339   // Only target should be checked.
   340   let checkStatus = [(button == target) ? 1 : 0 for (button of buttons)]
   341   testFilterButtonsCustom(aMonitor, checkStatus);
   342 }
   344 /**
   345  * Tests if filter buttons have 'checked' attributes set correctly.
   346  *
   347  * @param array aIsChecked
   348  *        An array specifying if a button at given index should have a
   349  *        'checked' attribute. For example, if the third item of the array
   350  *        evaluates to true, the third button should be checked.
   351  */
   352 function testFilterButtonsCustom(aMonitor, aIsChecked) {
   353   let doc = aMonitor.panelWin.document;
   354   let buttons = doc.querySelectorAll(".requests-menu-footer-button");
   355   for (let i = 0; i < aIsChecked.length; i++) {
   356     let button = buttons[i];
   357     if (aIsChecked[i]) {
   358       is(button.hasAttribute("checked"), true,
   359         "The " + button.id + " button should have a 'checked' attribute.");
   360     } else {
   361       is(button.hasAttribute("checked"), false,
   362         "The " + button.id + " button should not have a 'checked' attribute.");
   363     }
   364   }
   365 }

mercurial