diff options
Diffstat (limited to 'devtools/client/netmonitor')
32 files changed, 532 insertions, 291 deletions
diff --git a/devtools/client/netmonitor/actions/index.js b/devtools/client/netmonitor/actions/index.js index 3f7b0bd2f..2ce23448e 100644 --- a/devtools/client/netmonitor/actions/index.js +++ b/devtools/client/netmonitor/actions/index.js @@ -4,6 +4,7 @@ "use strict"; const filters = require("./filters"); -const sidebar = require("./sidebar"); +const requests = require("./requests"); +const ui = require("./ui"); -module.exports = Object.assign({}, filters, sidebar); +module.exports = Object.assign({}, filters, requests, ui); diff --git a/devtools/client/netmonitor/actions/moz.build b/devtools/client/netmonitor/actions/moz.build index 477cafb41..d0ac61944 100644 --- a/devtools/client/netmonitor/actions/moz.build +++ b/devtools/client/netmonitor/actions/moz.build @@ -6,5 +6,6 @@ DevToolsModules( 'filters.js', 'index.js', - 'sidebar.js', + 'requests.js', + 'ui.js', ) diff --git a/devtools/client/netmonitor/actions/requests.js b/devtools/client/netmonitor/actions/requests.js new file mode 100644 index 000000000..ae794a437 --- /dev/null +++ b/devtools/client/netmonitor/actions/requests.js @@ -0,0 +1,25 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const { + UPDATE_REQUESTS, +} = require("../constants"); + +/** + * Update request items + * + * @param {array} requests - visible request items + */ +function updateRequests(items) { + return { + type: UPDATE_REQUESTS, + items, + }; +} + +module.exports = { + updateRequests, +}; diff --git a/devtools/client/netmonitor/actions/sidebar.js b/devtools/client/netmonitor/actions/sidebar.js deleted file mode 100644 index 7e8dca5c1..000000000 --- a/devtools/client/netmonitor/actions/sidebar.js +++ /dev/null @@ -1,49 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -const { - DISABLE_TOGGLE_BUTTON, - SHOW_SIDEBAR, - TOGGLE_SIDEBAR, -} = require("../constants"); - -/** - * Change ToggleButton disabled state. - * - * @param {boolean} disabled - expected button disabled state - */ -function disableToggleButton(disabled) { - return { - type: DISABLE_TOGGLE_BUTTON, - disabled: disabled, - }; -} - -/** - * Change sidebar visible state. - * - * @param {boolean} visible - expected sidebar visible state - */ -function showSidebar(visible) { - return { - type: SHOW_SIDEBAR, - visible: visible, - }; -} - -/** - * Toggle to show/hide sidebar. - */ -function toggleSidebar() { - return { - type: TOGGLE_SIDEBAR, - }; -} - -module.exports = { - disableToggleButton, - showSidebar, - toggleSidebar, -}; diff --git a/devtools/client/netmonitor/actions/ui.js b/devtools/client/netmonitor/actions/ui.js new file mode 100644 index 000000000..c6df307ed --- /dev/null +++ b/devtools/client/netmonitor/actions/ui.js @@ -0,0 +1,36 @@ ++/* This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const {
+ OPEN_SIDEBAR,
+ TOGGLE_SIDEBAR,
+} = require("../constants");
+
+/**
+ * Change sidebar open state.
+ *
+ * @param {boolean} open - open state
+ */
+function openSidebar(open) {
+ return {
+ type: OPEN_SIDEBAR,
+ open,
+ };
+}
+
+/**
+ * Toggle sidebar open state.
+ */
+function toggleSidebar() {
+ return {
+ type: TOGGLE_SIDEBAR,
+ };
+}
+
+module.exports = {
+ openSidebar,
+ toggleSidebar,
+};
diff --git a/devtools/client/netmonitor/components/moz.build b/devtools/client/netmonitor/components/moz.build index 47ef7f026..42459584d 100644 --- a/devtools/client/netmonitor/components/moz.build +++ b/devtools/client/netmonitor/components/moz.build @@ -6,5 +6,6 @@ DevToolsModules( 'filter-buttons.js', 'search-box.js', + 'summary-button.js', 'toggle-button.js', ) diff --git a/devtools/client/netmonitor/components/summary-button.js b/devtools/client/netmonitor/components/summary-button.js new file mode 100644 index 000000000..223552fbf --- /dev/null +++ b/devtools/client/netmonitor/components/summary-button.js @@ -0,0 +1,61 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* globals NetMonitorView */ + +"use strict"; + +const { + CONTENT_SIZE_DECIMALS, + REQUEST_TIME_DECIMALS, +} = require("../constants"); +const { DOM, PropTypes } = require("devtools/client/shared/vendor/react"); +const { connect } = require("devtools/client/shared/vendor/react-redux"); +const { PluralForm } = require("devtools/shared/plural-form"); +const { L10N } = require("../l10n"); +const { + getDisplayedRequestsSummary +} = require("../selectors/index"); + +const { button, span } = DOM; + +function SummaryButton({ + summary, + triggerSummary +}) { + let { count, contentSize, transferredSize, millis } = summary; + const text = (count === 0) ? L10N.getStr("networkMenu.empty") : + PluralForm.get(count, L10N.getStr("networkMenu.summary2")) + .replace("#1", count) + .replace("#2", L10N.numberWithDecimals(contentSize / 1024, + CONTENT_SIZE_DECIMALS)) + .replace("#3", L10N.numberWithDecimals(transferredSize / 1024, + CONTENT_SIZE_DECIMALS)) + .replace("#4", L10N.numberWithDecimals(millis / 1000, + REQUEST_TIME_DECIMALS)); + + return button({ + id: "requests-menu-network-summary-button", + className: "devtools-button", + title: count ? text : L10N.getStr("netmonitor.toolbar.perf"), + onClick: triggerSummary, + }, + span({ className: "summary-info-icon" }), + span({ className: "summary-info-text" }, text)); +} + +SummaryButton.propTypes = { + summary: PropTypes.object.isRequired, +}; + +module.exports = connect( + (state) => ({ + summary: getDisplayedRequestsSummary(state), + }), + (dispatch) => ({ + triggerSummary: () => { + NetMonitorView.toggleFrontendMode(); + }, + }) +)(SummaryButton); diff --git a/devtools/client/netmonitor/components/toggle-button.js b/devtools/client/netmonitor/components/toggle-button.js index db546c55d..c9a59a76b 100644 --- a/devtools/client/netmonitor/components/toggle-button.js +++ b/devtools/client/netmonitor/components/toggle-button.js @@ -1,5 +1,3 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -11,47 +9,43 @@ const { connect } = require("devtools/client/shared/vendor/react-redux"); const { L10N } = require("../l10n"); const Actions = require("../actions/index"); -// Shortcuts const { button } = DOM; -/** - * Button used to toggle sidebar - */ function ToggleButton({ disabled, - onToggle, - visible, + open, + triggerSidebar, }) { let className = ["devtools-button"]; - if (!visible) { + if (!open) { className.push("pane-collapsed"); } - let titleMsg = visible ? L10N.getStr("collapseDetailsPane") : - L10N.getStr("expandDetailsPane"); + + const title = open ? L10N.getStr("collapseDetailsPane") : + L10N.getStr("expandDetailsPane"); return button({ id: "details-pane-toggle", className: className.join(" "), - title: titleMsg, - disabled: disabled, + title, + disabled, tabIndex: "0", - onMouseDown: onToggle, + onMouseDown: triggerSidebar, }); } ToggleButton.propTypes = { disabled: PropTypes.bool.isRequired, - onToggle: PropTypes.func.isRequired, - visible: PropTypes.bool.isRequired, + triggerSidebar: PropTypes.func.isRequired, }; module.exports = connect( (state) => ({ - disabled: state.sidebar.toggleButtonDisabled, - visible: state.sidebar.visible, + disabled: state.requests.items.length === 0, + open: state.ui.sidebar.open, }), (dispatch) => ({ - onToggle: () => { + triggerSidebar: () => { dispatch(Actions.toggleSidebar()); let requestsMenu = NetMonitorView.RequestsMenu; diff --git a/devtools/client/netmonitor/constants.js b/devtools/client/netmonitor/constants.js index a540d74b2..33bc71ea7 100644 --- a/devtools/client/netmonitor/constants.js +++ b/devtools/client/netmonitor/constants.js @@ -5,15 +5,17 @@ const general = { FREETEXT_FILTER_SEARCH_DELAY: 200, + CONTENT_SIZE_DECIMALS: 2, + REQUEST_TIME_DECIMALS: 2, }; const actionTypes = { TOGGLE_FILTER_TYPE: "TOGGLE_FILTER_TYPE", ENABLE_FILTER_TYPE_ONLY: "ENABLE_FILTER_TYPE_ONLY", - TOGGLE_SIDEBAR: "TOGGLE_SIDEBAR", - SHOW_SIDEBAR: "SHOW_SIDEBAR", - DISABLE_TOGGLE_BUTTON: "DISABLE_TOGGLE_BUTTON", SET_FILTER_TEXT: "SET_FILTER_TEXT", + OPEN_SIDEBAR: "OPEN_SIDEBAR", + TOGGLE_SIDEBAR: "TOGGLE_SIDEBAR", + UPDATE_REQUESTS: "UPDATE_REQUESTS", }; module.exports = Object.assign({}, general, actionTypes); diff --git a/devtools/client/netmonitor/moz.build b/devtools/client/netmonitor/moz.build index 4b34b093b..2c9b32d3f 100644 --- a/devtools/client/netmonitor/moz.build +++ b/devtools/client/netmonitor/moz.build @@ -17,6 +17,7 @@ DevToolsModules( 'events.js', 'filter-predicates.js', 'l10n.js', + 'open-request-in-tab.js', 'panel.js', 'performance-statistics-view.js', 'prefs.js', diff --git a/devtools/client/netmonitor/netmonitor-view.js b/devtools/client/netmonitor/netmonitor-view.js index 68470f7a9..414b9ab8f 100644 --- a/devtools/client/netmonitor/netmonitor-view.js +++ b/devtools/client/netmonitor/netmonitor-view.js @@ -125,7 +125,6 @@ var NetMonitorView = { if (!Prefs.statistics) { $("#request-menu-context-perf").hidden = true; $("#notice-perf-message").hidden = true; - $("#requests-menu-network-summary-button").hidden = true; } }, @@ -171,10 +170,10 @@ var NetMonitorView = { if (flags.visible) { this._body.classList.remove("pane-collapsed"); - gStore.dispatch(Actions.showSidebar(true)); + gStore.dispatch(Actions.openSidebar(true)); } else { this._body.classList.add("pane-collapsed"); - gStore.dispatch(Actions.showSidebar(false)); + gStore.dispatch(Actions.openSidebar(false)); } if (tabIndex !== undefined) { @@ -234,7 +233,7 @@ var NetMonitorView = { // populating the statistics view. // • The response mime type is used for categorization. yield whenDataAvailable(requestsView, [ - "responseHeaders", "status", "contentSize", "mimeType", "totalTime" + "responseHeaders", "status", "contentSize", "transferredSize", "mimeType", "totalTime" ]); } catch (ex) { // Timed out while waiting for data. Continue with what we have. @@ -964,7 +963,7 @@ NetworkDetailsView.prototype = { if (!response) { return; } - let { blocked, dns, connect, send, wait, receive } = response.timings; + let { blocked, dns, connect, ssl, send, wait, receive } = response.timings; let tabboxWidth = $("#details-pane").getAttribute("width"); @@ -989,6 +988,11 @@ NetworkDetailsView.prototype = { $("#timings-summary-connect .requests-menu-timings-total") .setAttribute("value", L10N.getFormatStr("networkMenu.totalMS", connect)); + $("#timings-summary-ssl .requests-menu-timings-box") + .setAttribute("width", ssl * scale); + $("#timings-summary-ssl .requests-menu-timings-total") + .setAttribute("value", L10N.getFormatStr("networkMenu.totalMS", ssl)); + $("#timings-summary-send .requests-menu-timings-box") .setAttribute("width", send * scale); $("#timings-summary-send .requests-menu-timings-total") @@ -1008,6 +1012,8 @@ NetworkDetailsView.prototype = { .style.transform = "translateX(" + (scale * blocked) + "px)"; $("#timings-summary-connect .requests-menu-timings-box") .style.transform = "translateX(" + (scale * (blocked + dns)) + "px)"; + $("#timings-summary-ssl .requests-menu-timings-box") + .style.transform = "translateX(" + (scale * blocked) + "px)"; $("#timings-summary-send .requests-menu-timings-box") .style.transform = "translateX(" + (scale * (blocked + dns + connect)) + "px)"; @@ -1023,6 +1029,8 @@ NetworkDetailsView.prototype = { .style.transform = "translateX(" + (scale * blocked) + "px)"; $("#timings-summary-connect .requests-menu-timings-total") .style.transform = "translateX(" + (scale * (blocked + dns)) + "px)"; + $("#timings-summary-ssl .requests-menu-timings-total") + .style.transform = "translateX(" + (scale * blocked) + "px)"; $("#timings-summary-send .requests-menu-timings-total") .style.transform = "translateX(" + (scale * (blocked + dns + connect)) + "px)"; @@ -1125,6 +1133,8 @@ NetworkDetailsView.prototype = { setValue("#security-protocol-version-value", securityInfo.protocolVersion); setValue("#security-ciphersuite-value", securityInfo.cipherSuite); + setValue("#security-keagroup-value", securityInfo.keaGroupName); + setValue("#security-signaturescheme-value", securityInfo.signatureSchemeName); // Host header let domain = getUriHostPort(url); diff --git a/devtools/client/netmonitor/netmonitor.xul b/devtools/client/netmonitor/netmonitor.xul index bb580f7ad..aa5c4d848 100644 --- a/devtools/client/netmonitor/netmonitor.xul +++ b/devtools/client/netmonitor/netmonitor.xul @@ -28,9 +28,8 @@ id="react-filter-buttons-hook"/> <spacer id="requests-menu-spacer" flex="1"/> - <toolbarbutton id="requests-menu-network-summary-button" - class="devtools-toolbarbutton icon-and-text" - data-localization="tooltiptext=netmonitor.toolbar.perf"/> + <html:div xmlns="http://www.w3.org/1999/xhtml" + id="react-summary-button-hook"/> <html:div xmlns="http://www.w3.org/1999/xhtml" id="react-search-box-hook"/> <html:div xmlns="http://www.w3.org/1999/xhtml" @@ -479,6 +478,14 @@ <hbox class="requests-menu-timings-box connect"/> <label class="plain requests-menu-timings-total"/> </hbox> + <hbox id="timings-summary-ssl" + class="tabpanel-summary-container" + align="center"> + <label class="plain tabpanel-summary-label" + data-localization="content=netmonitor.timings.ssl"/> + <hbox class="requests-menu-timings-box ssl"/> + <label class="plain requests-menu-timings-total"/> + </hbox> <hbox id="timings-summary-send" class="tabpanel-summary-container" align="center"> @@ -551,6 +558,26 @@ id="security-warning-cipher" data-localization="tooltiptext=netmonitor.security.warning.cipher" /> </hbox> + <hbox id="security-keagroup" + class="tabpanel-summary-container" + align="baseline"> + <label class="plain tabpanel-summary-label" + data-localization="content=netmonitor.security.keaGroup"/> + <textbox id="security-keagroup-value" + class="plain tabpanel-summary-value devtools-monospace cropped-textbox" + flex="1" + readonly="true"/> + </hbox> + <hbox id="security-signaturescheme" + class="tabpanel-summary-container" + align="baseline"> + <label class="plain tabpanel-summary-label" + data-localization="content=netmonitor.security.signatureScheme"/> + <textbox id="security-signaturescheme-value" + class="plain tabpanel-summary-value devtools-monospace cropped-textbox" + flex="1" + readonly="true"/> + </hbox> </vbox> </vbox> <vbox id="security-info-domain" diff --git a/devtools/client/netmonitor/open-request-in-tab.js b/devtools/client/netmonitor/open-request-in-tab.js new file mode 100644 index 000000000..aeb35dad0 --- /dev/null +++ b/devtools/client/netmonitor/open-request-in-tab.js @@ -0,0 +1,40 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/* eslint-disable mozilla/reject-some-requires */
+
+"use strict";
+
+let { Cc, Ci } = require("chrome");
+const Services = require("Services");
+const { gDevTools } = require("devtools/client/framework/devtools");
+
+/**
+ * Opens given request in a new tab.
+ */
+function openRequestInTab(request) {
+ let win = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
+ let rawData = request.requestPostData ? request.requestPostData.postData : null;
+ let postData;
+
+ if (rawData && rawData.text) {
+ let stringStream = getInputStreamFromString(rawData.text);
+ postData = Cc["@mozilla.org/network/mime-input-stream;1"]
+ .createInstance(Ci.nsIMIMEInputStream);
+ postData.addHeader("Content-Type", "application/x-www-form-urlencoded");
+ postData.setData(stringStream);
+ }
+
+ win.gBrowser.selectedTab = win.gBrowser.addTab(request.url, null, null, postData);
+}
+
+function getInputStreamFromString(data) {
+ let stringStream = Cc["@mozilla.org/io/string-input-stream;1"]
+ .createInstance(Ci.nsIStringInputStream);
+ stringStream.data = data;
+ return stringStream;
+}
+
+module.exports = {
+ openRequestInTab,
+};
diff --git a/devtools/client/netmonitor/performance-statistics-view.js b/devtools/client/netmonitor/performance-statistics-view.js index c712c083d..38b98fb68 100644 --- a/devtools/client/netmonitor/performance-statistics-view.js +++ b/devtools/client/netmonitor/performance-statistics-view.js @@ -92,27 +92,35 @@ PerformanceStatisticsView.prototype = { let string = L10N.numberWithDecimals(value / 1024, CONTENT_SIZE_DECIMALS); return L10N.getFormatStr("charts.sizeKB", string); }, + transferredSize: value => { + let string = L10N.numberWithDecimals(value / 1024, CONTENT_SIZE_DECIMALS); + return L10N.getFormatStr("charts.transferredSizeKB", string); + }, time: value => { let string = L10N.numberWithDecimals(value / 1000, REQUEST_TIME_DECIMALS); return L10N.getFormatStr("charts.totalS", string); } }, _commonChartTotals: { + cached: total => { + return L10N.getFormatStr("charts.totalCached", total); + }, + count: total => { + return L10N.getFormatStr("charts.totalCount", total); + }, size: total => { let string = L10N.numberWithDecimals(total / 1024, CONTENT_SIZE_DECIMALS); return L10N.getFormatStr("charts.totalSize", string); }, + transferredSize: total => { + let string = L10N.numberWithDecimals(total / 1024, CONTENT_SIZE_DECIMALS); + return L10N.getFormatStr("charts.totalTransferredSize", string); + }, time: total => { let seconds = total / 1000; let string = L10N.numberWithDecimals(seconds, REQUEST_TIME_DECIMALS); return PluralForm.get(seconds, L10N.getStr("charts.totalSeconds")).replace("#1", string); - }, - cached: total => { - return L10N.getFormatStr("charts.totalCached", total); - }, - count: total => { - return L10N.getFormatStr("charts.totalCount", total); } }, @@ -136,6 +144,14 @@ PerformanceStatisticsView.prototype = { let chart = Chart.PieTable(document, { diameter: NETWORK_ANALYSIS_PIE_CHART_DIAMETER, title: L10N.getStr(title), + header: { + cached: "", + count: "", + label: L10N.getStr("charts.type"), + size: L10N.getStr("charts.size"), + transferredSize: L10N.getStr("charts.transferred"), + time: L10N.getStr("charts.time") + }, data: data, strings: strings, totals: totals, @@ -161,13 +177,14 @@ PerformanceStatisticsView.prototype = { * True if the cache is considered enabled, false for disabled. */ _sanitizeChartDataSource: function (items, emptyCache) { - let data = [ + const data = [ "html", "css", "js", "xhr", "fonts", "images", "media", "flash", "ws", "other" - ].map(e => ({ + ].map((type) => ({ cached: 0, count: 0, - label: e, + label: type, size: 0, + transferredSize: 0, time: 0 })); @@ -211,6 +228,7 @@ PerformanceStatisticsView.prototype = { if (emptyCache || !responseIsFresh(details)) { data[type].time += details.totalTime || 0; data[type].size += details.contentSize || 0; + data[type].transferredSize += details.transferredSize || 0; } else { data[type].cached++; } diff --git a/devtools/client/netmonitor/reducers/index.js b/devtools/client/netmonitor/reducers/index.js index 58638a030..f36b1d91f 100644 --- a/devtools/client/netmonitor/reducers/index.js +++ b/devtools/client/netmonitor/reducers/index.js @@ -5,9 +5,11 @@ const { combineReducers } = require("devtools/client/shared/vendor/redux"); const filters = require("./filters"); -const sidebar = require("./sidebar"); +const requests = require("./requests"); +const ui = require("./ui"); module.exports = combineReducers({ filters, - sidebar, + requests, + ui, }); diff --git a/devtools/client/netmonitor/reducers/moz.build b/devtools/client/netmonitor/reducers/moz.build index 477cafb41..d0ac61944 100644 --- a/devtools/client/netmonitor/reducers/moz.build +++ b/devtools/client/netmonitor/reducers/moz.build @@ -6,5 +6,6 @@ DevToolsModules( 'filters.js', 'index.js', - 'sidebar.js', + 'requests.js', + 'ui.js', ) diff --git a/devtools/client/netmonitor/reducers/requests.js b/devtools/client/netmonitor/reducers/requests.js new file mode 100644 index 000000000..9ba888cad --- /dev/null +++ b/devtools/client/netmonitor/reducers/requests.js @@ -0,0 +1,28 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +"use strict"; + +const I = require("devtools/client/shared/vendor/immutable"); +const { + UPDATE_REQUESTS, +} = require("../constants"); + +const Requests = I.Record({ + items: [], +}); + +function updateRequests(state, action) { + return state.set("items", action.items || state.items); +} + +function requests(state = new Requests(), action) { + switch (action.type) { + case UPDATE_REQUESTS: + return updateRequests(state, action); + default: + return state; + } +} + +module.exports = requests; diff --git a/devtools/client/netmonitor/reducers/sidebar.js b/devtools/client/netmonitor/reducers/sidebar.js deleted file mode 100644 index eaa8b63df..000000000 --- a/devtools/client/netmonitor/reducers/sidebar.js +++ /dev/null @@ -1,43 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -const I = require("devtools/client/shared/vendor/immutable"); -const { - DISABLE_TOGGLE_BUTTON, - SHOW_SIDEBAR, - TOGGLE_SIDEBAR, -} = require("../constants"); - -const SidebarState = I.Record({ - toggleButtonDisabled: true, - visible: false, -}); - -function disableToggleButton(state, action) { - return state.set("toggleButtonDisabled", action.disabled); -} - -function showSidebar(state, action) { - return state.set("visible", action.visible); -} - -function toggleSidebar(state, action) { - return state.set("visible", !state.visible); -} - -function sidebar(state = new SidebarState(), action) { - switch (action.type) { - case DISABLE_TOGGLE_BUTTON: - return disableToggleButton(state, action); - case SHOW_SIDEBAR: - return showSidebar(state, action); - case TOGGLE_SIDEBAR: - return toggleSidebar(state, action); - default: - return state; - } -} - -module.exports = sidebar; diff --git a/devtools/client/netmonitor/reducers/ui.js b/devtools/client/netmonitor/reducers/ui.js new file mode 100644 index 000000000..033b944f3 --- /dev/null +++ b/devtools/client/netmonitor/reducers/ui.js @@ -0,0 +1,40 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const I = require("devtools/client/shared/vendor/immutable"); +const { + OPEN_SIDEBAR, + TOGGLE_SIDEBAR, +} = require("../constants"); + +const Sidebar = I.Record({ + open: false, +}); + +const UI = I.Record({ + sidebar: new Sidebar(), +}); + +function openSidebar(state, action) { + return state.setIn(["sidebar", "open"], action.open); +} + +function toggleSidebar(state, action) { + return state.setIn(["sidebar", "open"], !state.sidebar.open); +} + +function ui(state = new UI(), action) { + switch (action.type) { + case OPEN_SIDEBAR: + return openSidebar(state, action); + case TOGGLE_SIDEBAR: + return toggleSidebar(state, action); + default: + return state; + } +} + +module.exports = ui; diff --git a/devtools/client/netmonitor/request-list-context-menu.js b/devtools/client/netmonitor/request-list-context-menu.js index 215296265..331a7bde3 100644 --- a/devtools/client/netmonitor/request-list-context-menu.js +++ b/devtools/client/netmonitor/request-list-context-menu.js @@ -10,6 +10,7 @@ const Services = require("Services"); const { Task } = require("devtools/shared/task"); const { Curl } = require("devtools/client/shared/curl"); const { gDevTools } = require("devtools/client/framework/devtools"); +const { openRequestInTab } = require("devtools/client/netmonitor/open-request-in-tab"); const Menu = require("devtools/client/framework/menu"); const MenuItem = require("devtools/client/framework/menu-item"); const { L10N } = require("./l10n"); @@ -186,8 +187,7 @@ RequestListContextMenu.prototype = { */ openRequestInTab() { let win = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType); - let { url } = this.selectedItem.attachment; - win.openUILinkIn(url, "tab", { relatedToCurrent: true }); + openRequestInTab(this.selectedItem.attachment); }, /** diff --git a/devtools/client/netmonitor/request-utils.js b/devtools/client/netmonitor/request-utils.js index ba54efb4f..647d71e7c 100644 --- a/devtools/client/netmonitor/request-utils.js +++ b/devtools/client/netmonitor/request-utils.js @@ -92,7 +92,7 @@ exports.getFormDataSections = Task.async(function* (headers, uploadHeaders, post exports.formDataURI = function (mimeType, encoding, text) { if (!encoding) { encoding = "base64"; - text = btoa(text); + text = btoa(unescape(encodeURIComponent(text))); } return "data:" + mimeType + ";" + encoding + "," + text; }; diff --git a/devtools/client/netmonitor/requests-menu-view.js b/devtools/client/netmonitor/requests-menu-view.js index 6ea6381ec..4ee307145 100644 --- a/devtools/client/netmonitor/requests-menu-view.js +++ b/devtools/client/netmonitor/requests-menu-view.js @@ -19,7 +19,6 @@ const {setImageTooltip, getImageDimensions} = const {Heritage, WidgetMethods, setNamedTimeout} = require("devtools/client/shared/widgets/view-helpers"); const {CurlUtils} = require("devtools/client/shared/curl"); -const {PluralForm} = require("devtools/shared/plural-form"); const {Filters, isFreetextMatch} = require("./filter-predicates"); const {Sorters} = require("./sort-predicates"); const {L10N, WEBCONSOLE_L10N} = require("./l10n"); @@ -90,10 +89,11 @@ function storeWatcher(initialValue, reduceValue, onChange) { let currentValue = initialValue; return () => { + const oldValue = currentValue; const newValue = reduceValue(currentValue); - if (newValue !== currentValue) { - onChange(newValue, currentValue); + if (newValue !== oldValue) { currentValue = newValue; + onChange(newValue, oldValue); } }; } @@ -129,8 +129,6 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, { let widgetParentEl = $("#requests-menu-contents"); this.widget = new SideMenuWidget(widgetParentEl); this._splitter = $("#network-inspector-view-splitter"); - this._summary = $("#requests-menu-network-summary-button"); - this._summary.setAttribute("label", L10N.getStr("networkMenu.empty")); // Create a tooltip for the newly appended network request item. this.tooltip = new HTMLTooltip(NetMonitorController._toolbox.doc, { type: "arrow" }); @@ -211,13 +209,10 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, { if (NetMonitorController.supportsPerfStats) { $("#requests-menu-perf-notice-button").addEventListener("command", this._onContextPerfCommand, false); - $("#requests-menu-network-summary-button").addEventListener("command", - this._onContextPerfCommand, false); $("#network-statistics-back-button").addEventListener("command", this._onContextPerfCommand, false); } else { $("#notice-perf-message").hidden = true; - $("#requests-menu-network-summary-button").hidden = true; } if (!NetMonitorController.supportsTransferredResponseSize) { @@ -257,8 +252,6 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, { this._onReloadCommand, false); $("#requests-menu-perf-notice-button").removeEventListener("command", this._onContextPerfCommand, false); - $("#requests-menu-network-summary-button").removeEventListener("command", - this._onContextPerfCommand, false); $("#network-statistics-back-button").removeEventListener("command", this._onContextPerfCommand, false); @@ -406,9 +399,20 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, { if (rawHeadersHidden) { let selected = this.selectedItem.attachment; let selectedRequestHeaders = selected.requestHeaders.headers; - let selectedResponseHeaders = selected.responseHeaders.headers; + // display Status-Line above other response headers + let selectedStatusLine = selected.httpVersion + + " " + selected.status + + " " + selected.statusText + + "\n"; requestTextarea.value = writeHeaderText(selectedRequestHeaders); - responseTextare.value = writeHeaderText(selectedResponseHeaders); + // sometimes it's empty + if (selected.responseHeaders) { + let selectedResponseHeaders = selected.responseHeaders.headers; + responseTextare.value = selectedStatusLine + + writeHeaderText(selectedResponseHeaders); + } else { + responseTextare.value = selectedStatusLine; + } $("#raw-headers").hidden = false; } else { requestTextarea.value = null; @@ -422,7 +426,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, { */ reFilterRequests: function () { this.filterContents(this._filterPredicate); - this.refreshSummary(); + this.updateRequests(); this.refreshZebra(); }, @@ -541,7 +545,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, { break; } - this.refreshSummary(); + this.updateRequests(); this.refreshZebra(); }, @@ -552,41 +556,17 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, { NetMonitorController.NetworkEventsHandler.clearMarkers(); NetMonitorView.Sidebar.toggle(false); - this.store.dispatch(Actions.disableToggleButton(true)); $("#requests-menu-empty-notice").hidden = false; this.empty(); - this.refreshSummary(); + this.updateRequests(); }, /** - * Refreshes the status displayed in this container's footer, providing - * concise information about all requests. + * Update store request itmes and trigger related UI update */ - refreshSummary: function () { - let visibleItems = this.visibleItems; - let visibleRequestsCount = visibleItems.length; - if (!visibleRequestsCount) { - this._summary.setAttribute("label", L10N.getStr("networkMenu.empty")); - return; - } - - let totalBytes = this._getTotalBytesOfRequests(visibleItems); - let totalMillis = - this._getNewestRequest(visibleItems).attachment.endedMillis - - this._getOldestRequest(visibleItems).attachment.startedMillis; - - // https://developer.mozilla.org/en-US/docs/Localization_and_Plurals - let str = PluralForm.get(visibleRequestsCount, - L10N.getStr("networkMenu.summary")); - - this._summary.setAttribute("label", str - .replace("#1", visibleRequestsCount) - .replace("#2", L10N.numberWithDecimals((totalBytes || 0) / 1024, - CONTENT_SIZE_DECIMALS)) - .replace("#3", L10N.numberWithDecimals((totalMillis || 0) / 1000, - REQUEST_TIME_DECIMALS)) - ); + updateRequests: function () { + this.store.dispatch(Actions.updateRequests(this.visibleItems)); }, /** @@ -865,7 +845,6 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, { this._updateQueue = []; this._addQueue = []; - this.store.dispatch(Actions.disableToggleButton(!this.itemCount)); $("#requests-menu-empty-notice").hidden = !!this.itemCount; // Make sure all the requests are sorted and filtered. @@ -875,7 +854,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, { // so this doesn't happen once per network event update). this.sortContents(); this.filterContents(); - this.refreshSummary(); + this.updateRequests(); this.refreshZebra(); // Rescale all the waterfalls so that everything is visible at once. @@ -1131,7 +1110,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, { */ _createWaterfallView: function (item, timings, fromCache) { let { target } = item; - let sections = ["blocked", "dns", "connect", "send", "wait", "receive"]; + let sections = ["blocked", "dns", "connect", "ssl", "send", "wait", "receive"]; // Skipping "blocked" because it doesn't work yet. let timingsNode = $(".requests-menu-timings", target); @@ -1559,59 +1538,6 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, { }, /** - * Gets the total number of bytes representing the cumulated content size of - * a set of requests. Returns 0 for an empty set. - * - * @param array itemsArray - * @return number - */ - _getTotalBytesOfRequests: function (itemsArray) { - if (!itemsArray.length) { - return 0; - } - - let result = 0; - itemsArray.forEach(item => { - let size = item.attachment.contentSize; - result += (typeof size == "number") ? size : 0; - }); - - return result; - }, - - /** - * Gets the oldest (first performed) request in a set. Returns null for an - * empty set. - * - * @param array itemsArray - * @return object - */ - _getOldestRequest: function (itemsArray) { - if (!itemsArray.length) { - return null; - } - return itemsArray.reduce((prev, curr) => - prev.attachment.startedMillis < curr.attachment.startedMillis ? - prev : curr); - }, - - /** - * Gets the newest (latest performed) request in a set. Returns null for an - * empty set. - * - * @param array itemsArray - * @return object - */ - _getNewestRequest: function (itemsArray) { - if (!itemsArray.length) { - return null; - } - return itemsArray.reduce((prev, curr) => - prev.attachment.startedMillis > curr.attachment.startedMillis ? - prev : curr); - }, - - /** * Gets the available waterfall width in this container. * @return number */ diff --git a/devtools/client/netmonitor/selectors/index.js b/devtools/client/netmonitor/selectors/index.js index f473149b5..60d6007cd 100644 --- a/devtools/client/netmonitor/selectors/index.js +++ b/devtools/client/netmonitor/selectors/index.js @@ -1,8 +1,78 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + "use strict"; +const { createSelector } = require("devtools/client/shared/vendor/reselect"); + +/** + * Gets the total number of bytes representing the cumulated content size of + * a set of requests. Returns 0 for an empty set. + * + * @param {array} items - an array of request items + * @return {number} total bytes of requests + */ +function getContentSizeOfRequests(items) { + if (!items.length) { + return 0; + } + + let result = 0; + items.forEach((item) => { + let size = item.attachment.contentSize; + result += (typeof size == "number") ? size : 0; + }); + + return result; +} + +function getTransferredSizeOfRequests(items) { + if (!items.length) { + return 0; + } + + let result = 0; + items.forEach((item) => { + let size = item.attachment.transferredSize; + result += (typeof size == "number") ? size : 0; + }); + + return result; +} + +/** + * Gets the total milliseconds for all requests. Returns null for an + * empty set. + * + * @param {array} items - an array of request items + * @return {object} total milliseconds for all requests + */ +function getMillisOfRequests(items) { + if (!items.length) { + return null; + } + + const oldest = items.reduce((prev, curr) => + prev.attachment.startedMillis < curr.attachment.startedMillis ? + prev : curr); + const newest = items.reduce((prev, curr) => + prev.attachment.startedMillis > curr.attachment.startedMillis ? + prev : curr); + + return newest.attachment.endedMillis - oldest.attachment.startedMillis; +} + +const getDisplayedRequestsSummary = createSelector( + (state) => state.requests.items, + (requests) => ({ + count: requests.length, + contentSize: getContentSizeOfRequests(requests), + transferredSize: getTransferredSizeOfRequests(requests), + millis: getMillisOfRequests(requests), + }) +); + module.exports = { - // selectors... + getDisplayedRequestsSummary, }; diff --git a/devtools/client/netmonitor/test/browser_net_charts-03.js b/devtools/client/netmonitor/test/browser_net_charts-03.js index c7d9b0c1a..4a655a8ca 100644 --- a/devtools/client/netmonitor/test/browser_net_charts-03.js +++ b/devtools/client/netmonitor/test/browser_net_charts-03.js @@ -33,6 +33,10 @@ add_task(function* () { totals: { label1: value => "Hello " + L10N.numberWithDecimals(value, 2), label2: value => "World " + L10N.numberWithDecimals(value, 2) + }, + header: { + label1: "label1header", + label2: "label2header", } }); @@ -51,39 +55,48 @@ add_task(function* () { is(title.getAttribute("value"), "Table title", "The title node displays the correct text."); - is(rows.length, 3, "There should be 3 table chart rows created."); + is(rows.length, 4, "There should be 3 table chart rows and a header created."); - ok(rows[0].querySelector(".table-chart-row-box.chart-colored-blob"), - "A colored blob exists for the firt row."); is(rows[0].querySelectorAll("label")[0].getAttribute("name"), "label1", - "The first column of the first row exists."); + "The first column of the header exists."); is(rows[0].querySelectorAll("label")[1].getAttribute("name"), "label2", + "The second column of the header exists."); + is(rows[0].querySelectorAll("span")[0].textContent, "label1header", + "The first column of the header displays the correct text."); + is(rows[0].querySelectorAll("span")[1].textContent, "label2header", + "The second column of the header displays the correct text."); + + ok(rows[1].querySelector(".table-chart-row-box.chart-colored-blob"), + "A colored blob exists for the firt row."); + is(rows[1].querySelectorAll("span")[0].getAttribute("name"), "label1", + "The first column of the first row exists."); + is(rows[1].querySelectorAll("span")[1].getAttribute("name"), "label2", "The second column of the first row exists."); - is(rows[0].querySelectorAll("label")[0].getAttribute("value"), "1", + is(rows[1].querySelectorAll("label")[0].getAttribute("value"), "1", "The first column of the first row displays the correct text."); - is(rows[0].querySelectorAll("label")[1].getAttribute("value"), "11.1foo", + is(rows[1].querySelectorAll("label")[1].getAttribute("value"), "11.1foo", "The second column of the first row displays the correct text."); - ok(rows[1].querySelector(".table-chart-row-box.chart-colored-blob"), + ok(rows[2].querySelector(".table-chart-row-box.chart-colored-blob"), "A colored blob exists for the second row."); - is(rows[1].querySelectorAll("label")[0].getAttribute("name"), "label1", + is(rows[2].querySelectorAll("label")[0].getAttribute("name"), "label1", "The first column of the second row exists."); - is(rows[1].querySelectorAll("label")[1].getAttribute("name"), "label2", + is(rows[2].querySelectorAll("label")[1].getAttribute("name"), "label2", "The second column of the second row exists."); - is(rows[1].querySelectorAll("label")[0].getAttribute("value"), "2", + is(rows[2].querySelectorAll("label")[0].getAttribute("value"), "2", "The first column of the second row displays the correct text."); - is(rows[1].querySelectorAll("label")[1].getAttribute("value"), "12.2bar", + is(rows[2].querySelectorAll("label")[1].getAttribute("value"), "12.2bar", "The second column of the first row displays the correct text."); - ok(rows[2].querySelector(".table-chart-row-box.chart-colored-blob"), + ok(rows[3].querySelector(".table-chart-row-box.chart-colored-blob"), "A colored blob exists for the third row."); - is(rows[2].querySelectorAll("label")[0].getAttribute("name"), "label1", + is(rows[3].querySelectorAll("label")[0].getAttribute("name"), "label1", "The first column of the third row exists."); - is(rows[2].querySelectorAll("label")[1].getAttribute("name"), "label2", + is(rows[3].querySelectorAll("label")[1].getAttribute("name"), "label2", "The second column of the third row exists."); - is(rows[2].querySelectorAll("label")[0].getAttribute("value"), "3", + is(rows[3].querySelectorAll("label")[0].getAttribute("value"), "3", "The first column of the third row displays the correct text."); - is(rows[2].querySelectorAll("label")[1].getAttribute("value"), "13.3baz", + is(rows[3].querySelectorAll("label")[1].getAttribute("value"), "13.3baz", "The second column of the third row displays the correct text."); is(sums.length, 2, "There should be 2 total summaries created."); diff --git a/devtools/client/netmonitor/test/browser_net_charts-04.js b/devtools/client/netmonitor/test/browser_net_charts-04.js index 0d150c409..921701ae5 100644 --- a/devtools/client/netmonitor/test/browser_net_charts-04.js +++ b/devtools/client/netmonitor/test/browser_net_charts-04.js @@ -22,6 +22,10 @@ add_task(function* () { totals: { label1: value => "Hello " + L10N.numberWithDecimals(value, 2), label2: value => "World " + L10N.numberWithDecimals(value, 2) + }, + header: { + label1: "", + label2: "" } }); @@ -40,17 +44,17 @@ add_task(function* () { is(title.getAttribute("value"), "Table title", "The title node displays the correct text."); - is(rows.length, 1, "There should be 1 table chart row created."); + is(rows.length, 2, "There should be 1 table chart row and a 1 header created."); - ok(rows[0].querySelector(".table-chart-row-box.chart-colored-blob"), + ok(rows[1].querySelector(".table-chart-row-box.chart-colored-blob"), "A colored blob exists for the firt row."); - is(rows[0].querySelectorAll("label")[0].getAttribute("name"), "size", + is(rows[1].querySelectorAll("label")[0].getAttribute("name"), "size", "The first column of the first row exists."); - is(rows[0].querySelectorAll("label")[1].getAttribute("name"), "label", + is(rows[1].querySelectorAll("label")[1].getAttribute("name"), "label", "The second column of the first row exists."); - is(rows[0].querySelectorAll("label")[0].getAttribute("value"), "", + is(rows[1].querySelectorAll("label")[0].getAttribute("value"), "", "The first column of the first row displays the correct text."); - is(rows[0].querySelectorAll("label")[1].getAttribute("value"), + is(rows[1].querySelectorAll("label")[1].getAttribute("value"), L10N.getStr("tableChart.loading"), "The second column of the first row displays the correct text."); diff --git a/devtools/client/netmonitor/test/browser_net_charts-05.js b/devtools/client/netmonitor/test/browser_net_charts-05.js index 00445b132..c444d2c65 100644 --- a/devtools/client/netmonitor/test/browser_net_charts-05.js +++ b/devtools/client/netmonitor/test/browser_net_charts-05.js @@ -33,6 +33,10 @@ add_task(function* () { totals: { size: value => "Hello " + L10N.numberWithDecimals(value, 2), label: value => "World " + L10N.numberWithDecimals(value, 2) + }, + header: { + label1: "", + label2: "" } }); @@ -53,9 +57,9 @@ add_task(function* () { ok(node.querySelector(".table-chart-container"), "A table chart was created successfully."); - is(rows.length, 3, "There should be 3 pie chart slices created."); - is(rows.length, 3, "There should be 3 table chart rows created."); - is(sums.length, 2, "There should be 2 total summaries created."); + is(rows.length, 4, "There should be 3 pie chart slices and 1 header created."); + is(rows.length, 4, "There should be 3 table chart rows and 1 header created."); + is(sums.length, 2, "There should be 2 total summaries and 1 header created."); yield teardown(monitor); }); diff --git a/devtools/client/netmonitor/test/browser_net_charts-07.js b/devtools/client/netmonitor/test/browser_net_charts-07.js index bb992e4eb..a655f258c 100644 --- a/devtools/client/netmonitor/test/browser_net_charts-07.js +++ b/devtools/client/netmonitor/test/browser_net_charts-07.js @@ -20,6 +20,10 @@ add_task(function* () { totals: { label1: value => "Hello " + L10N.numberWithDecimals(value, 2), label2: value => "World " + L10N.numberWithDecimals(value, 2) + }, + header: { + label1: "", + label2: "" } }); @@ -29,17 +33,17 @@ add_task(function* () { let rows = grid.querySelectorAll(".table-chart-row"); let sums = node.querySelectorAll(".table-chart-summary-label"); - is(rows.length, 1, "There should be 1 table chart row created."); + is(rows.length, 2, "There should be 1 table chart row and 1 header created."); - ok(rows[0].querySelector(".table-chart-row-box.chart-colored-blob"), + ok(rows[1].querySelector(".table-chart-row-box.chart-colored-blob"), "A colored blob exists for the firt row."); - is(rows[0].querySelectorAll("label")[0].getAttribute("name"), "size", + is(rows[1].querySelectorAll("label")[0].getAttribute("name"), "size", "The first column of the first row exists."); - is(rows[0].querySelectorAll("label")[1].getAttribute("name"), "label", + is(rows[1].querySelectorAll("label")[1].getAttribute("name"), "label", "The second column of the first row exists."); - is(rows[0].querySelectorAll("label")[0].getAttribute("value"), "", + is(rows[1].querySelectorAll("label")[0].getAttribute("value"), "", "The first column of the first row displays the correct text."); - is(rows[0].querySelectorAll("label")[1].getAttribute("value"), + is(rows[1].querySelectorAll("label")[1].getAttribute("value"), L10N.getStr("tableChart.unavailable"), "The second column of the first row displays the correct text."); diff --git a/devtools/client/netmonitor/test/browser_net_curl-utils.js b/devtools/client/netmonitor/test/browser_net_curl-utils.js index 7a5fc7926..0d35c6141 100644 --- a/devtools/client/netmonitor/test/browser_net_curl-utils.js +++ b/devtools/client/netmonitor/test/browser_net_curl-utils.js @@ -7,7 +7,7 @@ * Tests Curl Utils functionality. */ -const { CurlUtils } = require("devtools/client/shared/curl"); +const { Curl, CurlUtils } = require("devtools/client/shared/curl"); add_task(function* () { let { tab, monitor } = yield initNetMonitor(CURL_UTILS_URL); @@ -37,6 +37,8 @@ add_task(function* () { data = yield createCurlData(requests.post.attachment, gNetwork); testIsUrlEncodedRequest(data); testWritePostDataTextParams(data); + testWriteEmptyPostDataTextParams(data); + testDataArgumentOnGeneratedCommand(data); data = yield createCurlData(requests.multipart.attachment, gNetwork); testIsMultipartRequest(data); @@ -85,6 +87,18 @@ function testWritePostDataTextParams(data) { "Should return a serialized representation of the request parameters"); } +function testWriteEmptyPostDataTextParams(data) { + let params = CurlUtils.writePostDataTextParams(null); + is(params, "", + "Should return a empty string when no parameters provided"); +} + +function testDataArgumentOnGeneratedCommand(data) { + let curlCommand = Curl.generateCommand(data); + ok(curlCommand.includes("--data"), + "Should return a curl command with --data"); +} + function testGetMultipartBoundary(data) { let boundary = CurlUtils.getMultipartBoundary(data); ok(/-{3,}\w+/.test(boundary), diff --git a/devtools/client/netmonitor/test/browser_net_footer-summary.js b/devtools/client/netmonitor/test/browser_net_footer-summary.js index e484b2097..8faa8470b 100644 --- a/devtools/client/netmonitor/test/browser_net_footer-summary.js +++ b/devtools/client/netmonitor/test/browser_net_footer-summary.js @@ -10,13 +10,14 @@ add_task(function* () { requestLongerTimeout(2); + let { getSummary } = require("devtools/client/netmonitor/selectors/index"); let { L10N } = require("devtools/client/netmonitor/l10n"); let { PluralForm } = require("devtools/shared/plural-form"); let { tab, monitor } = yield initNetMonitor(FILTERING_URL); info("Starting test... "); - let { $, NetMonitorView } = monitor.panelWin; + let { $, NetMonitorView, gStore } = monitor.panelWin; let { RequestsMenu } = NetMonitorView; RequestsMenu.lazyUpdate = false; @@ -43,33 +44,27 @@ add_task(function* () { yield teardown(monitor); function testStatus() { - let summary = $("#requests-menu-network-summary-button"); - let value = summary.getAttribute("label"); + const { count, contentSize, transferredSize, millis } = getSummary(gStore.getState()); + let value = $("#requests-menu-network-summary-button").textContent; info("Current summary: " + value); - let visibleItems = RequestsMenu.visibleItems; - let visibleRequestsCount = visibleItems.length; let totalRequestsCount = RequestsMenu.itemCount; - info("Current requests: " + visibleRequestsCount + " of " + totalRequestsCount + "."); + info("Current requests: " + count + " of " + totalRequestsCount + "."); - if (!totalRequestsCount || !visibleRequestsCount) { + if (!totalRequestsCount || !count) { is(value, L10N.getStr("networkMenu.empty"), "The current summary text is incorrect, expected an 'empty' label."); return; } - let totalBytes = RequestsMenu._getTotalBytesOfRequests(visibleItems); - let totalMillis = - RequestsMenu._getNewestRequest(visibleItems).attachment.endedMillis - - RequestsMenu._getOldestRequest(visibleItems).attachment.startedMillis; + info("Computed total bytes: " + contentSize); + info("Computed total millis: " + millis); - info("Computed total bytes: " + totalBytes); - info("Computed total millis: " + totalMillis); - - is(value, PluralForm.get(visibleRequestsCount, L10N.getStr("networkMenu.summary")) - .replace("#1", visibleRequestsCount) - .replace("#2", L10N.numberWithDecimals((totalBytes || 0) / 1024, 2)) - .replace("#3", L10N.numberWithDecimals((totalMillis || 0) / 1000, 2)) + is(value, PluralForm.get(count, L10N.getStr("networkMenu.summary2")) + .replace("#1", count) + .replace("#2", L10N.numberWithDecimals((contentSize || 0) / 1024, 2)) + .replace("#3", L10N.numberWithDecimals((transferredSize || 0) / 1024, 2)) + .replace("#4", L10N.numberWithDecimals((millis || 0) / 1000, 2)) , "The current summary text is incorrect."); } }); diff --git a/devtools/client/netmonitor/test/browser_net_security-details.js b/devtools/client/netmonitor/test/browser_net_security-details.js index 0a83b3ed9..61f39a414 100644 --- a/devtools/client/netmonitor/test/browser_net_security-details.js +++ b/devtools/client/netmonitor/test/browser_net_security-details.js @@ -66,6 +66,10 @@ add_task(function* () { checkLabel("#security-cert-issuer-o", "Mozilla Testing"); checkLabel("#security-cert-issuer-ou", "<Not Available>"); + // These two values can change. So only check they're not empty. + checkLabelNotEmpty("#security-keagroup-value"); + checkLabelNotEmpty("#security-signaturescheme-value"); + // Locale sensitive and varies between timezones. Cant't compare equality or // the test fails depending on which part of the world the test is executed. checkLabelNotEmpty("#security-cert-validity-begins"); 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 1b952bd71..f21318d7a 100644 --- a/devtools/client/netmonitor/test/browser_net_simple-request-data.js +++ b/devtools/client/netmonitor/test/browser_net_simple-request-data.js @@ -226,6 +226,8 @@ function test() { "The eventTimings attachment has an incorrect |timings.blocked| property."); is(typeof requestItem.attachment.eventTimings.timings.dns, "number", "The eventTimings attachment has an incorrect |timings.dns| property."); + is(typeof requestItem.attachment.eventTimings.timings.ssl, "number", + "The eventTimings attachment has an incorrect |timings.ssl| property."); is(typeof requestItem.attachment.eventTimings.timings.connect, "number", "The eventTimings attachment has an incorrect |timings.connect| property."); is(typeof requestItem.attachment.eventTimings.timings.send, "number", diff --git a/devtools/client/netmonitor/toolbar-view.js b/devtools/client/netmonitor/toolbar-view.js index 28c3cf99b..1834d3ee9 100644 --- a/devtools/client/netmonitor/toolbar-view.js +++ b/devtools/client/netmonitor/toolbar-view.js @@ -7,6 +7,7 @@ const Provider = createFactory(require("devtools/client/shared/vendor/react-redu const FilterButtons = createFactory(require("./components/filter-buttons")); const ToggleButton = createFactory(require("./components/toggle-button")); const SearchBox = createFactory(require("./components/search-box")); +const SummaryButton = createFactory(require("./components/summary-button")); const { L10N } = require("./l10n"); // Shortcuts @@ -28,8 +29,9 @@ ToolbarView.prototype = { this._clearContainerNode = $("#react-clear-button-hook"); this._filterContainerNode = $("#react-filter-buttons-hook"); - this._toggleContainerNode = $("#react-details-pane-toggle-hook"); + this._summaryContainerNode = $("#react-summary-button-hook"); this._searchContainerNode = $("#react-search-box-hook"); + this._toggleContainerNode = $("#react-details-pane-toggle-hook"); // clear button ReactDOM.render(button({ @@ -47,6 +49,12 @@ ToolbarView.prototype = { FilterButtons() ), this._filterContainerNode); + // summary button + ReactDOM.render(Provider( + { store }, + SummaryButton() + ), this._summaryContainerNode); + // search box ReactDOM.render(Provider( { store }, @@ -68,8 +76,9 @@ ToolbarView.prototype = { ReactDOM.unmountComponentAtNode(this._clearContainerNode); ReactDOM.unmountComponentAtNode(this._filterContainerNode); - ReactDOM.unmountComponentAtNode(this._toggleContainerNode); + ReactDOM.unmountComponentAtNode(this._summaryContainerNode); ReactDOM.unmountComponentAtNode(this._searchContainerNode); + ReactDOM.unmountComponentAtNode(this._toggleContainerNode); } }; |