Bug 1346854 - Adjust network monitor test expectations. r=Honza
After the previous commit, we're now starting network listening at a different
point in toolbox startup. We need to rework some test expectations to account
for the new timing.
MozReview-Commit-ID: 1lNDE51uVPS
--- a/devtools/client/netmonitor/src/netmonitor-controller.js
+++ b/devtools/client/netmonitor/src/netmonitor-controller.js
@@ -374,18 +374,18 @@ NetworkEventsHandler.prototype = {
}
},
/**
* The "DOMContentLoaded" and "Load" events sent by the timeline actor.
* @param object marker
*/
_onDocLoadingMarker: function (marker) {
+ this.actions.addTimingMarker(marker);
window.emit(EVENTS.TIMELINE_EVENT, marker);
- this.actions.addTimingMarker(marker);
},
/**
* The "networkEvent" message type handler.
*
* @param string type
* Message type.
* @param object networkInfo
--- a/devtools/client/netmonitor/test/browser_net_autoscroll.js
+++ b/devtools/client/netmonitor/test/browser_net_autoscroll.js
@@ -2,19 +2,19 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Bug 863102 - Automatically scroll down upon new network requests.
*/
add_task(function* () {
- requestLongerTimeout(2);
+ requestLongerTimeout(4);
- let { monitor } = yield initNetMonitor(INFINITE_GET_URL);
+ let { monitor } = yield initNetMonitor(INFINITE_GET_URL, true);
let { document, gStore, windowRequire } = monitor.panelWin;
let Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
// Wait until the first request makes the empty notice disappear
yield waitForRequestListToAppear();
let requestsContainer = document.querySelector(".requests-list-contents");
ok(requestsContainer, "Container element exists as expected.");
--- a/devtools/client/netmonitor/test/browser_net_cached-status.js
+++ b/devtools/client/netmonitor/test/browser_net_cached-status.js
@@ -3,17 +3,17 @@
"use strict";
/**
* Tests if cached requests have the correct status code
*/
add_task(function* () {
- let { tab, monitor } = yield initNetMonitor(STATUS_CODES_URL, null, true);
+ let { tab, monitor } = yield initNetMonitor(STATUS_CODES_URL, true);
info("Starting test... ");
let { document, gStore, windowRequire } = monitor.panelWin;
let Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
let {
getDisplayedRequests,
getSortedRequests,
} = windowRequire("devtools/client/netmonitor/src/selectors/index");
--- a/devtools/client/netmonitor/test/browser_net_leak_on_tab_close.js
+++ b/devtools/client/netmonitor/test/browser_net_leak_on_tab_close.js
@@ -6,12 +6,12 @@
/**
* Tests that netmonitor doesn't leak windows on parent-side pages (bug 1285638)
*/
add_task(function* () {
// Tell initNetMonitor to enable cache. Otherwise it will assert that there were more
// than zero network requests during the page load. But when loading about:config,
// there are none.
- let { monitor } = yield initNetMonitor("about:config", null, true);
+ let { monitor } = yield initNetMonitor("about:config", true);
ok(monitor, "The network monitor was opened");
yield teardown(monitor);
});
--- a/devtools/client/netmonitor/test/browser_net_reload-markers.js
+++ b/devtools/client/netmonitor/test/browser_net_reload-markers.js
@@ -7,27 +7,24 @@
* Tests if the empty-requests reload button works.
*/
add_task(function* () {
let { monitor } = yield initNetMonitor(SIMPLE_URL);
info("Starting test... ");
let { document } = monitor.panelWin;
+
+ let markersDone = waitForTimelineMarkers(monitor);
+
let button = document.querySelector(".requests-list-reload-notice-button");
button.click();
- let markers = [];
-
- monitor.panelWin.on(EVENTS.TIMELINE_EVENT, (_, marker) => {
- markers.push(marker);
- });
-
yield waitForNetworkEvents(monitor, 1);
- yield waitUntil(() => markers.length == 2);
+ let markers = yield markersDone;
ok(true, "Reloading finished");
is(markers[0].name, "document::DOMContentLoaded",
"The first received marker is correct.");
is(markers[1].name, "document::Load",
"The second received marker is correct.");
--- a/devtools/client/netmonitor/test/browser_net_security-error.js
+++ b/devtools/client/netmonitor/test/browser_net_security-error.js
@@ -12,28 +12,28 @@ add_task(function* () {
let { document, gStore, windowRequire } = monitor.panelWin;
let Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
let { EVENTS } = windowRequire("devtools/client/netmonitor/src/constants");
gStore.dispatch(Actions.batchEnable(false));
info("Requesting a resource that has a certificate problem.");
- let wait = waitForSecurityBrokenNetworkEvent();
+ let requestsDone = waitForSecurityBrokenNetworkEvent();
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests(1, "https://nocert.example.com");
});
- yield wait;
+ yield requestsDone;
- wait = waitForDOM(document, "#security-panel");
+ let securityInfoLoaded = waitForDOM(document, ".security-info-value");
EventUtils.sendMouseEvent({ type: "click" },
document.querySelector(".network-details-panel-toggle"));
EventUtils.sendMouseEvent({ type: "click" },
document.querySelector("#security-tab"));
- yield wait;
+ yield securityInfoLoaded;
let errormsg = document.querySelector(".security-info-value");
isnot(errormsg.textContent, "", "Error message is not empty.");
return teardown(monitor);
/**
* Returns a promise that's resolved once a request with security issues is
--- a/devtools/client/netmonitor/test/browser_net_service-worker-status.js
+++ b/devtools/client/netmonitor/test/browser_net_service-worker-status.js
@@ -8,17 +8,17 @@
*/
// Service workers only work on https
const URL = EXAMPLE_URL.replace("http:", "https:");
const TEST_URL = URL + "service-workers/status-codes.html";
add_task(function* () {
- let { tab, monitor } = yield initNetMonitor(TEST_URL, null, true);
+ let { tab, monitor } = yield initNetMonitor(TEST_URL, true);
info("Starting test... ");
let { document, gStore, windowRequire } = monitor.panelWin;
let Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
let {
getDisplayedRequests,
getSortedRequests,
} = windowRequire("devtools/client/netmonitor/src/selectors/index");
--- a/devtools/client/netmonitor/test/head.js
+++ b/devtools/client/netmonitor/test/head.js
@@ -115,43 +115,133 @@ function toggleCache(target, disabled) {
let navigationFinished = waitForNavigation(target);
// Disable the cache for any toolbox that it is opened from this point on.
Services.prefs.setBoolPref("devtools.cache.disabled", disabled);
return reconfigureTab(target, options).then(() => navigationFinished);
}
-function initNetMonitor(url, window, enableCache) {
+/**
+ * Wait for 2 markers during document load.
+ */
+function waitForTimelineMarkers(monitor) {
+ return new Promise(resolve => {
+ let markers = [];
+
+ function handleTimelineEvent(_, marker) {
+ info(`Got marker: ${marker.name}`);
+ markers.push(marker);
+ if (markers.length == 2) {
+ monitor.panelWin.off(EVENTS.TIMELINE_EVENT, handleTimelineEvent);
+ info("Got two timeline markers, done waiting");
+ resolve(markers);
+ }
+ }
+
+ monitor.panelWin.on(EVENTS.TIMELINE_EVENT, handleTimelineEvent);
+ });
+}
+
+/**
+ * Start monitoring all incoming update events about network requests and wait until
+ * a complete info about all requests is received. (We wait for the timings info
+ * explicitly, because that's always the last piece of information that is received.)
+ *
+ * This method is designed to wait for network requests that are issued during a page
+ * load, when retrieving page resources (scripts, styles, images). It has certain
+ * assumptions that can make it unsuitable for other types of network communication:
+ * - it waits for at least one network request to start and finish before returning
+ * - it waits only for request that were issued after it was called. Requests that are
+ * already in mid-flight will be ignored.
+ * - the request start and end times are overlapping. If a new request starts a moment
+ * after the previous one was finished, the wait will be ended in the "interim"
+ * period.
+ * @returns a promise that resolves when the wait is done.
+ */
+function waitForAllRequestsFinished(monitor) {
+ let window = monitor.panelWin;
+ let { windowRequire } = window;
+ let { NetMonitorController } =
+ windowRequire("devtools/client/netmonitor/src/netmonitor-controller");
+
+ return new Promise(resolve => {
+ // Key is the request id, value is a boolean - is request finished or not?
+ let requests = new Map();
+
+ function onRequest(_, id) {
+ let networkInfo = NetMonitorController.webConsoleClient.getNetworkRequest(id);
+ let { url } = networkInfo.request;
+ info(`Request ${id} for ${url} not yet done, keep waiting...`);
+ requests.set(id, false);
+ }
+
+ function onTimings(_, id) {
+ let networkInfo = NetMonitorController.webConsoleClient.getNetworkRequest(id);
+ let { url } = networkInfo.request;
+ info(`Request ${id} for ${url} done`);
+ requests.set(id, true);
+ maybeResolve();
+ }
+
+ function maybeResolve() {
+ // Have all the requests in the map finished yet?
+ if (![...requests.values()].every(finished => finished)) {
+ return;
+ }
+
+ // All requests are done - unsubscribe from events and resolve!
+ window.off(EVENTS.NETWORK_EVENT, onRequest);
+ window.off(EVENTS.RECEIVED_EVENT_TIMINGS, onTimings);
+ info("All requests finished");
+ resolve();
+ }
+
+ window.on(EVENTS.NETWORK_EVENT, onRequest);
+ window.on(EVENTS.RECEIVED_EVENT_TIMINGS, onTimings);
+ });
+}
+
+function initNetMonitor(url, enableCache) {
info("Initializing a network monitor pane.");
return Task.spawn(function* () {
let tab = yield addTab(url);
info("Net tab added successfully: " + url);
let target = TargetFactory.forTab(tab);
yield target.makeRemote();
info("Target remoted.");
+ let toolbox = yield gDevTools.showToolbox(target, "netmonitor");
+ info("Network monitor pane shown successfully.");
+
+ let monitor = toolbox.getCurrentPanel();
+
if (!enableCache) {
+ let panel = monitor.panelWin;
+ let { gStore, windowRequire } = panel;
info("Disabling cache and reloading page.");
+ let requestsDone = waitForAllRequestsFinished(monitor);
+ let markersDone = waitForTimelineMarkers(monitor);
yield toggleCache(target, true);
+ yield Promise.all([requestsDone, markersDone]);
info("Cache disabled when the current and all future toolboxes are open.");
// Remove any requests generated by the reload while toggling the cache to
// avoid interfering with the test.
isnot([...target.activeConsole.getNetworkEvents()].length, 0,
"Request to reconfigure the tab was recorded.");
+ info("Clearing requests in the console client.");
target.activeConsole.clearNetworkRequests();
+ info("Clearing requests in the UI.");
+ let Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
+ gStore.dispatch(Actions.clearRequests());
}
- let toolbox = yield gDevTools.showToolbox(target, "netmonitor");
- info("Network monitor pane shown successfully.");
-
- let monitor = toolbox.getCurrentPanel();
return {tab, monitor};
});
}
function restartNetMonitor(monitor, newUrl) {
info("Restarting the specified network monitor.");
return Task.spawn(function* () {
@@ -216,43 +306,54 @@ function waitForNetworkEvents(monitor, g
}
function updateProgressForURL(url, event) {
initProgressForURL(url);
progress[url][Object.keys(EVENTS).find(e => EVENTS[e] == event)] = 1;
}
function onGenericEvent(event, actor) {
+ let networkInfo = NetMonitorController.webConsoleClient.getNetworkRequest(actor);
+ if (!networkInfo) {
+ // Must have been related to reloading document to disable cache.
+ // Ignore the event.
+ return;
+ }
genericEvents++;
- maybeResolve(event, actor);
+ maybeResolve(event, actor, networkInfo);
}
function onPostEvent(event, actor) {
+ let networkInfo = NetMonitorController.webConsoleClient.getNetworkRequest(actor);
+ if (!networkInfo) {
+ // Must have been related to reloading document to disable cache.
+ // Ignore the event.
+ return;
+ }
postEvents++;
- maybeResolve(event, actor);
+ maybeResolve(event, actor, networkInfo);
}
- function maybeResolve(event, actor) {
+ function maybeResolve(event, actor, networkInfo) {
info("> Network events progress: " +
genericEvents + "/" + ((getRequests + postRequests) * 13) + ", " +
postEvents + "/" + (postRequests * 2) + ", " +
"got " + event + " for " + actor);
- let networkInfo = NetMonitorController.webConsoleClient.getNetworkRequest(actor);
let url = networkInfo.request.url;
updateProgressForURL(url, event);
// Uncomment this to get a detailed progress logging (when debugging a test)
// info("> Current state: " + JSON.stringify(progress, null, 2));
// There are 15 updates which need to be fired for a request to be
// considered finished. The "requestPostData" packet isn't fired for
// non-POST requests.
if (genericEvents >= (getRequests + postRequests) * 13 &&
- postEvents >= postRequests * 2) {
+ postEvents >= postRequests * 2) {
awaitedEventsToListeners.forEach(([e, l]) => panel.off(EVENTS[e], l));
executeSoon(resolve);
}
}
awaitedEventsToListeners.forEach(([e, l]) => panel.on(EVENTS[e], l));
});
}