From fbe8a116c7c470d61ba87e1c11b70df838df8191 Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Fri, 21 Apr 2017 15:25:48 +0200 Subject: [PATCH] Backed out changeset 125045e56532 (bug 1356957) for frequent failures in browser_net_security-error.js --- .../components/request-list-column-file.js | 1 + devtools/client/netmonitor/src/constants.js | 12 ++ .../netmonitor/src/netmonitor-controller.js | 199 ++++++++---------- .../test/browser_net_icon-preview.js | 26 ++- .../test/browser_net_image-tooltip.js | 12 +- .../test/browser_net_simple-request-data.js | 20 +- 6 files changed, 144 insertions(+), 126 deletions(-) diff --git a/devtools/client/netmonitor/src/components/request-list-column-file.js b/devtools/client/netmonitor/src/components/request-list-column-file.js index c52c238fc2bc..c97ebf897419 100644 --- a/devtools/client/netmonitor/src/components/request-list-column-file.js +++ b/devtools/client/netmonitor/src/components/request-list-column-file.js @@ -38,6 +38,7 @@ const RequestListColumnFile = createClass({ className: "requests-list-icon", src: responseContentDataUri, hidden: !responseContentDataUri, + "data-type": responseContentDataUri ? "thumbnail" : undefined, }), div({ className: "subitem-label requests-list-file", diff --git a/devtools/client/netmonitor/src/constants.js b/devtools/client/netmonitor/src/constants.js index febc505ba2b4..d071aa5275f3 100644 --- a/devtools/client/netmonitor/src/constants.js +++ b/devtools/client/netmonitor/src/constants.js @@ -93,6 +93,18 @@ const EVENTS = { UPDATING_RESPONSE_CONTENT: "NetMonitor:NetworkEventUpdating:ResponseContent", RECEIVED_RESPONSE_CONTENT: "NetMonitor:NetworkEventUpdated:ResponseContent", + // When the request post params are displayed in the UI. + REQUEST_POST_PARAMS_DISPLAYED: "NetMonitor:RequestPostParamsAvailable", + + // When the image response thumbnail is displayed in the UI. + RESPONSE_IMAGE_THUMBNAIL_DISPLAYED: + "NetMonitor:ResponseImageThumbnailAvailable", + + // Fired when charts have been displayed in the PerformanceStatisticsView. + PLACEHOLDER_CHARTS_DISPLAYED: "NetMonitor:PlaceholderChartsDisplayed", + PRIMED_CACHE_CHART_DISPLAYED: "NetMonitor:PrimedChartsDisplayed", + EMPTY_CACHE_CHART_DISPLAYED: "NetMonitor:EmptyChartsDisplayed", + // Fired once the NetMonitorController establishes a connection to the debug // target. CONNECTED: "connected", diff --git a/devtools/client/netmonitor/src/netmonitor-controller.js b/devtools/client/netmonitor/src/netmonitor-controller.js index 727981be55a1..1cb3f522d03b 100644 --- a/devtools/client/netmonitor/src/netmonitor-controller.js +++ b/devtools/client/netmonitor/src/netmonitor-controller.js @@ -7,7 +7,10 @@ const { TimelineFront } = require("devtools/shared/fronts/timeline"); const { CurlUtils } = require("devtools/client/shared/curl"); const { ACTIVITY_TYPE, EVENTS } = require("./constants"); -const { getDisplayedRequestById } = require("./selectors/index"); +const { + getRequestById, + getDisplayedRequestById, +} = require("./selectors/index"); const { fetchHeaders, formDataURI, @@ -304,6 +307,7 @@ function NetworkEventsHandler() { this._onRequestPostData = this._onRequestPostData.bind(this); this._onResponseHeaders = this._onResponseHeaders.bind(this); this._onResponseCookies = this._onResponseCookies.bind(this); + this._onResponseContent = this._onResponseContent.bind(this); this._onSecurityInfo = this._onSecurityInfo.bind(this); this._onEventTimings = this._onEventTimings.bind(this); } @@ -424,11 +428,45 @@ NetworkEventsHandler.prototype = { .then(() => window.emit(EVENTS.REQUEST_ADDED, id)); }, - async fetchImage(mimeType, responseContent) { - let payload = {}; - if (mimeType && responseContent && responseContent.content) { - let { encoding, text } = responseContent.content; + async updateRequest(id, data) { + await this.actions.updateRequest(id, data, true); + let { + responseContent, + responseCookies, + responseHeaders, + requestCookies, + requestHeaders, + requestPostData, + } = data; + let request = getRequestById(window.gStore.getState(), id); + + if (requestHeaders && requestHeaders.headers && requestHeaders.headers.length) { + let headers = await fetchHeaders(requestHeaders, getLongString); + if (headers) { + await this.actions.updateRequest( + id, + { requestHeaders: headers }, + true, + ); + } + } + + if (responseHeaders && responseHeaders.headers && responseHeaders.headers.length) { + let headers = await fetchHeaders(responseHeaders, getLongString); + if (headers) { + await this.actions.updateRequest( + id, + { responseHeaders: headers }, + true, + ); + } + } + + if (request && responseContent && responseContent.content) { + let { mimeType } = request; + let { text, encoding } = responseContent.content; let response = await getLongString(text); + let payload = {}; if (mimeType.includes("image/")) { payload.responseContentDataUri = formDataURI(mimeType, encoding, response); @@ -436,36 +474,16 @@ NetworkEventsHandler.prototype = { responseContent.content.text = response; payload.responseContent = responseContent; - } - return payload; - }, - async fetchRequestHeaders(requestHeaders) { - let payload = {}; - if (requestHeaders && requestHeaders.headers && requestHeaders.headers.length) { - let headers = await fetchHeaders(requestHeaders, getLongString); - if (headers) { - payload.requestHeaders = headers; + await this.actions.updateRequest(id, payload, true); + + if (mimeType.includes("image/")) { + window.emit(EVENTS.RESPONSE_IMAGE_THUMBNAIL_DISPLAYED); } } - return payload; - }, - async fetchResponseHeaders(responseHeaders) { - let payload = {}; - if (responseHeaders && responseHeaders.headers && responseHeaders.headers.length) { - let headers = await fetchHeaders(responseHeaders, getLongString); - if (headers) { - payload.responseHeaders = headers; - } - } - return payload; - }, - - // Search the POST data upload stream for request headers and add - // them as a separate property, different from the classic headers. - async fetchPostData(requestPostData) { - let payload = {}; + // Search the POST data upload stream for request headers and add + // them as a separate property, different from the classic headers. if (requestPostData && requestPostData.postData) { let { text } = requestPostData.postData; let postData = await getLongString(text); @@ -473,40 +491,17 @@ NetworkEventsHandler.prototype = { const headersSize = headers.reduce((acc, { name, value }) => { return acc + name.length + value.length + 2; }, 0); + let payload = {}; requestPostData.postData.text = postData; payload.requestPostData = Object.assign({}, requestPostData); payload.requestHeadersFromUploadStream = { headers, headersSize }; - } - return payload; - }, - async fetchResponseCookies(responseCookies) { - let payload = {}; - if (responseCookies) { - let resCookies = []; - // response store cookies in responseCookies or responseCookies.cookies - let cookies = responseCookies.cookies ? - responseCookies.cookies : responseCookies; - // make sure cookies is iterable - if (typeof cookies[Symbol.iterator] === "function") { - for (let cookie of cookies) { - resCookies.push(Object.assign({}, cookie, { - value: await getLongString(cookie.value), - })); - } - if (resCookies.length) { - payload.responseCookies = resCookies; - } - } + await this.actions.updateRequest(id, payload, true); } - return payload; - }, - // Fetch request and response cookies long value. - // Actor does not provide full sized cookie value when the value is too long - // To display values correctly, we need fetch them in each request. - async fetchRequestCookies(requestCookies) { - let payload = {}; + // Fetch request and response cookies long value. + // Actor does not provide full sized cookie value when the value is too long + // To display values correctly, we need fetch them in each request. if (requestCookies) { let reqCookies = []; // request store cookies in requestCookies or requestCookies.cookies @@ -520,45 +515,28 @@ NetworkEventsHandler.prototype = { })); } if (reqCookies.length) { - payload.requestCookies = reqCookies; + await this.actions.updateRequest(id, { requestCookies: reqCookies }, true); } } } - return payload; - }, - async updateRequest(id, data) { - let { - mimeType, - responseContent, - responseCookies, - responseHeaders, - requestCookies, - requestHeaders, - requestPostData, - } = data; - - // fetch request detail contents in parallel - let [ - imageObj, - requestHeadersObj, - responseHeadersObj, - postDataObj, - requestCookiesObj, - responseCookiesObj, - ] = await Promise.all([ - this.fetchImage(mimeType, responseContent), - this.fetchRequestHeaders(requestHeaders), - this.fetchResponseHeaders(responseHeaders), - this.fetchPostData(requestPostData), - this.fetchRequestCookies(requestCookies), - this.fetchResponseCookies(responseCookies), - ]); - - let payload = Object.assign({}, data, - imageObj, requestHeadersObj, responseHeadersObj, - postDataObj, requestCookiesObj, responseCookiesObj); - await this.actions.updateRequest(id, payload, true); + if (responseCookies) { + let resCookies = []; + // response store cookies in responseCookies or responseCookies.cookies + let cookies = responseCookies.cookies ? + responseCookies.cookies : responseCookies; + // make sure cookies is iterable + if (typeof cookies[Symbol.iterator] === "function") { + for (let cookie of cookies) { + resCookies.push(Object.assign({}, cookie, { + value: await getLongString(cookie.value), + })); + } + if (resCookies.length) { + await this.actions.updateRequest(id, { responseCookies: resCookies }, true); + } + } + } }, /** @@ -590,10 +568,9 @@ NetworkEventsHandler.prototype = { case "securityInfo": this.updateRequest(actor, { securityState: networkInfo.securityInfo, - }).then(() => { - this.webConsoleClient.getSecurityInfo(actor, this._onSecurityInfo); - window.emit(EVENTS.UPDATING_SECURITY_INFO, actor); }); + this.webConsoleClient.getSecurityInfo(actor, this._onSecurityInfo); + window.emit(EVENTS.UPDATING_SECURITY_INFO, actor); break; case "responseHeaders": this.webConsoleClient.getResponseHeaders(actor, @@ -613,26 +590,25 @@ NetworkEventsHandler.prototype = { status: networkInfo.response.status, statusText: networkInfo.response.statusText, headersSize: networkInfo.response.headersSize - }).then(() => { - window.emit(EVENTS.STARTED_RECEIVING_RESPONSE, actor); }); + window.emit(EVENTS.STARTED_RECEIVING_RESPONSE, actor); break; case "responseContent": + this.updateRequest(actor, { + contentSize: networkInfo.response.bodySize, + transferredSize: networkInfo.response.transferredSize, + mimeType: networkInfo.response.content.mimeType + }); this.webConsoleClient.getResponseContent(actor, - this._onResponseContent.bind(this, { - contentSize: networkInfo.response.bodySize, - transferredSize: networkInfo.response.transferredSize, - mimeType: networkInfo.response.content.mimeType - })); + this._onResponseContent); window.emit(EVENTS.UPDATING_RESPONSE_CONTENT, actor); break; case "eventTimings": this.updateRequest(actor, { totalTime: networkInfo.totalTime - }).then(() => { - this.webConsoleClient.getEventTimings(actor, this._onEventTimings); - window.emit(EVENTS.UPDATING_EVENT_TIMINGS, actor); }); + this.webConsoleClient.getEventTimings(actor, this._onEventTimings); + window.emit(EVENTS.UPDATING_EVENT_TIMINGS, actor); break; } }, @@ -724,14 +700,13 @@ NetworkEventsHandler.prototype = { /** * Handles additional information received for a "responseContent" packet. * - * @param object data - * The message received from the server event. * @param object response * The message received from the server. */ - _onResponseContent: function (data, response) { - let payload = Object.assign({ responseContent: response }, data); - this.updateRequest(response.from, payload).then(() => { + _onResponseContent: function (response) { + this.updateRequest(response.from, { + responseContent: response + }).then(() => { window.emit(EVENTS.RECEIVED_RESPONSE_CONTENT, response.from); }); }, diff --git a/devtools/client/netmonitor/test/browser_net_icon-preview.js b/devtools/client/netmonitor/test/browser_net_icon-preview.js index 3de8d6a7c139..a1d14d7e155a 100644 --- a/devtools/client/netmonitor/test/browser_net_icon-preview.js +++ b/devtools/client/netmonitor/test/browser_net_icon-preview.js @@ -9,21 +9,22 @@ add_task(function* () { let { tab, monitor } = yield initNetMonitor(CONTENT_TYPE_WITHOUT_CACHE_URL); - const SELECTOR = ".requests-list-icon[src]"; info("Starting test... "); let { document, gStore, windowRequire } = monitor.panelWin; let Actions = windowRequire("devtools/client/netmonitor/src/actions/index"); let { NetMonitorController } = windowRequire("devtools/client/netmonitor/src/netmonitor-controller"); - let { ACTIVITY_TYPE } = windowRequire("devtools/client/netmonitor/src/constants"); + let { + ACTIVITY_TYPE, + EVENTS, + } = windowRequire("devtools/client/netmonitor/src/constants"); gStore.dispatch(Actions.batchEnable(false)); - let wait = waitForNetworkEvents(monitor, CONTENT_TYPE_WITHOUT_CACHE_REQUESTS); + let wait = waitForEvents(); yield performRequests(); yield wait; - yield waitUntil(() => !!document.querySelector(SELECTOR)); info("Checking the image thumbnail when all items are shown."); checkImageThumbnail(); @@ -37,16 +38,22 @@ add_task(function* () { checkImageThumbnail(); info("Reloading the debuggee and performing all requests again..."); - wait = waitForNetworkEvents(monitor, CONTENT_TYPE_WITHOUT_CACHE_REQUESTS); + wait = waitForEvents(); yield reloadAndPerformRequests(); yield wait; - yield waitUntil(() => !!document.querySelector(SELECTOR)); info("Checking the image thumbnail after a reload."); checkImageThumbnail(); yield teardown(monitor); + function waitForEvents() { + return promise.all([ + waitForNetworkEvents(monitor, CONTENT_TYPE_WITHOUT_CACHE_REQUESTS), + monitor.panelWin.once(EVENTS.RESPONSE_IMAGE_THUMBNAIL_DISPLAYED) + ]); + } + function performRequests() { return ContentTask.spawn(tab.linkedBrowser, {}, function* () { content.wrappedJSObject.performRequests(); @@ -59,11 +66,12 @@ add_task(function* () { } function checkImageThumbnail() { - is(document.querySelectorAll(SELECTOR).length, 1, + is(document.querySelectorAll(".requests-list-icon[data-type=thumbnail]").length, 1, "There should be only one image request with a thumbnail displayed."); - is(document.querySelector(SELECTOR).src, TEST_IMAGE_DATA_URI, + is(document.querySelector(".requests-list-icon[data-type=thumbnail]").src, + TEST_IMAGE_DATA_URI, "The image requests-list-icon thumbnail is displayed correctly."); - is(document.querySelector(SELECTOR).hidden, false, + is(document.querySelector(".requests-list-icon[data-type=thumbnail]").hidden, false, "The image requests-list-icon thumbnail should not be hidden."); } }); diff --git a/devtools/client/netmonitor/test/browser_net_image-tooltip.js b/devtools/client/netmonitor/test/browser_net_image-tooltip.js index 99ea61349b17..0cd45a85f6cc 100644 --- a/devtools/client/netmonitor/test/browser_net_image-tooltip.js +++ b/devtools/client/netmonitor/test/browser_net_image-tooltip.js @@ -11,22 +11,25 @@ const IMAGE_TOOLTIP_REQUESTS = 1; */ add_task(function* test() { let { tab, monitor } = yield initNetMonitor(IMAGE_TOOLTIP_URL); - const SELECTOR = ".requests-list-icon[src]"; info("Starting test... "); let { document, gStore, windowRequire } = monitor.panelWin; let Actions = windowRequire("devtools/client/netmonitor/src/actions/index"); let { NetMonitorController } = windowRequire("devtools/client/netmonitor/src/netmonitor-controller"); - let { ACTIVITY_TYPE } = windowRequire("devtools/client/netmonitor/src/constants"); + let { + ACTIVITY_TYPE, + EVENTS, + } = windowRequire("devtools/client/netmonitor/src/constants"); let toolboxDoc = monitor.panelWin.parent.document; gStore.dispatch(Actions.batchEnable(false)); let onEvents = waitForNetworkEvents(monitor, IMAGE_TOOLTIP_REQUESTS); + let onThumbnail = monitor.panelWin.once(EVENTS.RESPONSE_IMAGE_THUMBNAIL_DISPLAYED); yield performRequests(); yield onEvents; - yield waitUntil(() => !!document.querySelector(SELECTOR)); + yield onThumbnail; info("Checking the image thumbnail after a few requests were made..."); yield showTooltipAndVerify(document.querySelectorAll(".request-list-item")[0]); @@ -38,12 +41,13 @@ add_task(function* test() { // +1 extra document reload onEvents = waitForNetworkEvents(monitor, IMAGE_TOOLTIP_REQUESTS + 1); + onThumbnail = monitor.panelWin.once(EVENTS.RESPONSE_IMAGE_THUMBNAIL_DISPLAYED); info("Reloading the debuggee and performing all requests again..."); yield NetMonitorController.triggerActivity(ACTIVITY_TYPE.RELOAD.WITH_CACHE_ENABLED); yield performRequests(); yield onEvents; - yield waitUntil(() => !!document.querySelector(SELECTOR)); + yield onThumbnail; info("Checking the image thumbnail after a reload."); yield showTooltipAndVerify(document.querySelectorAll(".request-list-item")[1]); diff --git a/devtools/client/netmonitor/test/browser_net_simple-request-data.js b/devtools/client/netmonitor/test/browser_net_simple-request-data.js index cbd5908f283f..2f71b45458e1 100644 --- a/devtools/client/netmonitor/test/browser_net_simple-request-data.js +++ b/devtools/client/netmonitor/test/browser_net_simple-request-data.js @@ -193,7 +193,7 @@ function test() { ); }); - monitor.panelWin.once(EVENTS.RECEIVED_RESPONSE_CONTENT, () => { + monitor.panelWin.once(EVENTS.UPDATING_RESPONSE_CONTENT, () => { let requestItem = getSortedRequests(gStore.getState()).get(0); is(requestItem.transferredSize, "12", @@ -203,6 +203,24 @@ function test() { is(requestItem.mimeType, "text/plain; charset=utf-8", "The mimeType data has an incorrect value."); + verifyRequestItemTarget( + document, + getDisplayedRequests(gStore.getState()), + requestItem, + "GET", + SIMPLE_SJS, + { + type: "plain", + fullMimeType: "text/plain; charset=utf-8", + transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 12), + size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 12), + } + ); + }); + + monitor.panelWin.once(EVENTS.RECEIVED_RESPONSE_CONTENT, () => { + let requestItem = getSortedRequests(gStore.getState()).get(0); + ok(requestItem.responseContent, "There should be a responseContent data available."); // eslint-disable-next-line mozilla/no-cpows-in-tests