--- a/devtools/client/framework/test/browser_ignore_toolbox_network_requests.js
+++ b/devtools/client/framework/test/browser_ignore_toolbox_network_requests.js
@@ -18,16 +18,18 @@ add_task(function* () {
let tab = yield addTab(URL_ROOT + "doc_viewsource.html");
let target = TargetFactory.forTab(tab);
let toolbox = yield gDevTools.showToolbox(target, "styleeditor");
let panel = toolbox.getPanel("styleeditor");
is(panel.UI.editors.length, 1, "correct number of editors opened");
let monitor = yield toolbox.selectTool("netmonitor");
- let { RequestsMenu } = monitor.panelWin.NetMonitorView;
- is(RequestsMenu.itemCount, 0, "No network requests appear in the network panel");
+ let { gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+
+ is(gStore.getState().requests.requests.size, 0, "No network requests appear in the network panel");
yield gDevTools.closeToolbox(target);
tab = target = toolbox = panel = null;
gBrowser.removeCurrentTab();
flags.testing = isTesting;
});
--- a/devtools/client/netmonitor/actions/selection.js
+++ b/devtools/client/netmonitor/actions/selection.js
@@ -1,28 +1,45 @@
/* 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 { getDisplayedRequests } = require("../selectors/index");
const { SELECT_REQUEST } = require("../constants");
+const {
+ getDisplayedRequests,
+ getSortedRequests,
+} = require("../selectors/index");
+
+const PAGE_SIZE_ITEM_COUNT_RATIO = 5;
/**
* Select request with a given id.
*/
function selectRequest(id) {
return {
type: SELECT_REQUEST,
- id
+ id,
};
}
-const PAGE_SIZE_ITEM_COUNT_RATIO = 5;
+/**
+ * Select request with a given index (sorted order)
+ */
+function selectRequestByIndex(index) {
+ return (dispatch, getState) => {
+ const requests = getSortedRequests(getState());
+ let itemId;
+ if (index >= 0 && index < requests.size) {
+ itemId = requests.get(index).id;
+ }
+ dispatch(selectRequest(itemId));
+ };
+}
/**
* Move the selection up to down according to the "delta" parameter. Possible values:
* - Number: positive or negative, move up or down by specified distance
* - "PAGE_UP" | "PAGE_DOWN" (String): page up or page down
* - +Infinity | -Infinity: move to the start or end of the list
*/
function selectDelta(delta) {
@@ -45,10 +62,11 @@ function selectDelta(delta) {
const newIndex = Math.min(Math.max(0, selIndex + delta), requests.size - 1);
const newItem = requests.get(newIndex);
dispatch(selectRequest(newItem.id));
};
}
module.exports = {
selectRequest,
+ selectRequestByIndex,
selectDelta,
};
--- a/devtools/client/netmonitor/actions/ui.js
+++ b/devtools/client/netmonitor/actions/ui.js
@@ -19,19 +19,19 @@ const {
function openNetworkDetails(open) {
return {
type: OPEN_NETWORK_DETAILS,
open,
};
}
/**
- * Change performance statistics view open state.
+ * Change performance statistics panel open state.
*
- * @param {boolean} visible - expected performance statistics open state
+ * @param {boolean} visible - expected performance statistics panel open state
*/
function openStatistics(open) {
return {
type: OPEN_STATISTICS,
open,
};
}
@@ -61,20 +61,21 @@ function selectDetailsPanelTab(id) {
* Toggle network details panel.
*/
function toggleNetworkDetails() {
return (dispatch, getState) =>
dispatch(openNetworkDetails(!getState().ui.networkDetailsOpen));
}
/**
- * Toggle to show/hide performance statistics view.
+ * Toggle performance statistics panel.
*/
function toggleStatistics() {
- return (dispatch, getState) => dispatch(openStatistics(!getState().ui.statisticsOpen));
+ return (dispatch, getState) =>
+ dispatch(openStatistics(!getState().ui.statisticsOpen));
}
module.exports = {
openNetworkDetails,
openStatistics,
resizeWaterfall,
selectDetailsPanelTab,
toggleNetworkDetails,
--- a/devtools/client/netmonitor/components/moz.build
+++ b/devtools/client/netmonitor/components/moz.build
@@ -1,14 +1,15 @@
# 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/.
DevToolsModules(
'request-list-content.js',
+ 'request-list-context-menu.js',
'request-list-empty.js',
'request-list-header.js',
'request-list-item.js',
'request-list-tooltip.js',
'request-list.js',
'statistics-panel.js',
'toolbar.js',
)
--- a/devtools/client/netmonitor/components/request-list-content.js
+++ b/devtools/client/netmonitor/components/request-list-content.js
@@ -1,58 +1,83 @@
/* 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 */
+
+/* globals NetMonitorController */
"use strict";
-const { Task } = require("devtools/shared/task");
-const { createClass, createFactory, DOM, PropTypes } = require("devtools/client/shared/vendor/react");
-const { div } = DOM;
-const Actions = require("../actions/index");
-const RequestListItem = createFactory(require("./request-list-item"));
+const { KeyCodes } = require("devtools/client/shared/keycodes");
+const {
+ createClass,
+ createFactory,
+ DOM,
+ PropTypes,
+} = require("devtools/client/shared/vendor/react");
const { connect } = require("devtools/client/shared/vendor/react-redux");
-const { setTooltipImageContent,
- setTooltipStackTraceContent } = require("./request-list-tooltip");
-const { getDisplayedRequests,
- getWaterfallScale } = require("../selectors/index");
-const { KeyCodes } = require("devtools/client/shared/keycodes");
+const { HTMLTooltip } = require("devtools/client/shared/widgets/tooltip/HTMLTooltip");
+const { Task } = require("devtools/shared/task");
+const Actions = require("../actions/index");
+const {
+ setTooltipImageContent,
+ setTooltipStackTraceContent,
+} = require("./request-list-tooltip");
+const {
+ getDisplayedRequests,
+ getWaterfallScale,
+} = require("../selectors/index");
+
+// Components
+const RequestListItem = createFactory(require("./request-list-item"));
+const RequestListContextMenu = require("./request-list-context-menu");
+
+const { div } = DOM;
// tooltip show/hide delay in ms
const REQUESTS_TOOLTIP_TOGGLE_DELAY = 500;
/**
* Renders the actual contents of the request list.
*/
const RequestListContent = createClass({
displayName: "RequestListContent",
propTypes: {
+ contextMenu: PropTypes.object.isRequired,
+ dispatch: PropTypes.func.isRequired,
displayedRequests: PropTypes.object.isRequired,
firstRequestStartedMillis: PropTypes.number.isRequired,
- onItemContextMenu: PropTypes.func.isRequired,
onItemMouseDown: PropTypes.func.isRequired,
onSecurityIconClick: PropTypes.func.isRequired,
onSelectDelta: PropTypes.func.isRequired,
scale: PropTypes.number,
selectedRequestId: PropTypes.string,
tooltip: PropTypes.shape({
hide: PropTypes.func.isRequired,
startTogglingOnHover: PropTypes.func.isRequired,
stopTogglingOnHover: PropTypes.func.isRequired,
}).isRequired
},
+ componentWillMount() {
+ const { dispatch } = this.props;
+ this.contextMenu = new RequestListContextMenu({
+ cloneSelectedRequest: () => dispatch(Actions.cloneSelectedRequest()),
+ openStatistics: (open) => dispatch(Actions.openStatistics(open)),
+ });
+ this.tooltip = new HTMLTooltip(NetMonitorController._toolbox.doc, { type: "arrow" });
+ },
+
componentDidMount() {
// Set the CSS variables for waterfall scaling
this.setScalingStyles();
// Install event handler for displaying a tooltip
- this.props.tooltip.startTogglingOnHover(this.refs.contentEl, this.onHover, {
+ this.tooltip.startTogglingOnHover(this.refs.contentEl, this.onHover, {
toggleDelay: REQUESTS_TOOLTIP_TOGGLE_DELAY,
interactive: true
});
// Install event handler to hide the tooltip on scroll
this.refs.contentEl.addEventListener("scroll", this.onScroll, true);
},
@@ -73,17 +98,17 @@ const RequestListContent = createClass({
node.scrollTop = node.scrollHeight;
}
},
componentWillUnmount() {
this.refs.contentEl.removeEventListener("scroll", this.onScroll, true);
// Uninstall the tooltip event handler
- this.props.tooltip.stopTogglingOnHover();
+ this.tooltip.stopTogglingOnHover();
},
/**
* Set the CSS variables for waterfall scaling. If React supported setting CSS
* variables as part of the "style" property of a DOM element, we would use that.
*
* However, React doesn't support this, so we need to use a hack and update the
* DOM element directly: https://github.com/facebook/react/issues/6411
@@ -147,17 +172,17 @@ const RequestListContent = createClass({
return false;
}),
/**
* Scroll listener for the requests menu view.
*/
onScroll() {
- this.props.tooltip.hide();
+ this.tooltip.hide();
},
/**
* Handler for keyboard events. For arrow up/down, page up/down, home/end,
* move the selection up or down.
*/
onKeyDown(e) {
let delta;
@@ -188,16 +213,21 @@ const RequestListContent = createClass({
if (delta) {
// Prevent scrolling when pressing navigation keys.
e.preventDefault();
e.stopPropagation();
this.props.onSelectDelta(delta);
}
},
+ onContextMenu(evt) {
+ evt.preventDefault();
+ this.contextMenu.open(evt);
+ },
+
/**
* If selection has just changed (by keyboard navigation), don't keep the list
* scrolled to bottom, but allow scrolling up with the selection.
*/
onFocusedNodeChange() {
this.shouldScrollBottom = false;
},
@@ -206,66 +236,62 @@ const RequestListContent = createClass({
*/
onFocusedNodeUnmount() {
if (this.refs.contentEl) {
this.refs.contentEl.focus();
}
},
render() {
- const { selectedRequestId,
- displayedRequests,
- firstRequestStartedMillis,
- onItemMouseDown,
- onItemContextMenu,
- onSecurityIconClick } = this.props;
+ const {
+ displayedRequests,
+ firstRequestStartedMillis,
+ selectedRequestId,
+ onItemMouseDown,
+ onSecurityIconClick,
+ } = this.props;
- return div(
- {
+ return (
+ div({
ref: "contentEl",
className: "requests-menu-contents",
tabIndex: 0,
onKeyDown: this.onKeyDown,
},
- displayedRequests.map((item, index) => RequestListItem({
- key: item.id,
- item,
- index,
- isSelected: item.id === selectedRequestId,
- firstRequestStartedMillis,
- onMouseDown: e => onItemMouseDown(e, item.id),
- onContextMenu: e => onItemContextMenu(e, item.id),
- onSecurityIconClick: e => onSecurityIconClick(e, item),
- onFocusedNodeChange: this.onFocusedNodeChange,
- onFocusedNodeUnmount: this.onFocusedNodeUnmount,
- }))
+ displayedRequests.map((item, index) => RequestListItem({
+ key: item.id,
+ item,
+ index,
+ isSelected: item.id === selectedRequestId,
+ firstRequestStartedMillis,
+ onMouseDown: () => onItemMouseDown(item.id),
+ onContextMenu: this.onContextMenu,
+ onFocusedNodeChange: this.onFocusedNodeChange,
+ onFocusedNodeUnmount: this.onFocusedNodeUnmount,
+ onSecurityIconClick: () => onSecurityIconClick(item.securityState),
+ }))
+ )
);
},
});
module.exports = connect(
- state => ({
+ (state) => ({
displayedRequests: getDisplayedRequests(state),
+ firstRequestStartedMillis: state.requests.firstStartedMillis,
selectedRequestId: state.requests.selectedId,
scale: getWaterfallScale(state),
- firstRequestStartedMillis: state.requests.firstStartedMillis,
- tooltip: NetMonitorView.RequestsMenu.tooltip,
}),
- dispatch => ({
- onItemMouseDown: (e, item) => dispatch(Actions.selectRequest(item)),
- onItemContextMenu: (e, item) => {
- e.preventDefault();
- NetMonitorView.RequestsMenu.contextMenu.open(e);
- },
- onSelectDelta: (delta) => dispatch(Actions.selectDelta(delta)),
+ (dispatch) => ({
+ dispatch,
+ onItemMouseDown: (id) => dispatch(Actions.selectRequest(id)),
/**
* A handler that opens the security tab in the details view if secure or
* broken security indicator is clicked.
*/
- onSecurityIconClick: (e, item) => {
- const { securityState } = item;
- // Choose the security tab.
+ onSecurityIconClick: (securityState) => {
if (securityState && securityState !== "insecure") {
dispatch(Actions.selectDetailsPanelTab("security"));
}
},
- })
+ onSelectDelta: (delta) => dispatch(Actions.selectDelta(delta)),
+ }),
)(RequestListContent);
new file mode 100644
--- /dev/null
+++ b/devtools/client/netmonitor/components/request-list-context-menu.js
@@ -0,0 +1,360 @@
+/* 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 NetMonitorController, gNetwork, gStore */
+
+"use strict";
+
+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 Menu = require("devtools/client/framework/menu");
+const MenuItem = require("devtools/client/framework/menu-item");
+const { L10N } = require("../l10n");
+const {
+ formDataURI,
+ getFormDataSections,
+ getUrlQuery,
+ parseQueryString,
+} = require("../request-utils");
+const {
+ getSelectedRequest,
+ getSortedRequests,
+} = require("../selectors/index");
+
+loader.lazyRequireGetter(this, "HarExporter",
+ "devtools/client/netmonitor/har/har-exporter", true);
+
+loader.lazyServiceGetter(this, "clipboardHelper",
+ "@mozilla.org/widget/clipboardhelper;1", "nsIClipboardHelper");
+
+function RequestListContextMenu({
+ cloneSelectedRequest,
+ openStatistics,
+}) {
+ this.cloneSelectedRequest = cloneSelectedRequest;
+ this.openStatistics = openStatistics;
+}
+
+RequestListContextMenu.prototype = {
+ get selectedRequest() {
+ return getSelectedRequest(gStore.getState());
+ },
+
+ get sortedRequests() {
+ return getSortedRequests(gStore.getState());
+ },
+
+ /**
+ * Handle the context menu opening. Hide items if no request is selected.
+ * Since visible attribute only accept boolean value but the method call may
+ * return undefined, we use !! to force convert any object to boolean
+ */
+ open({ screenX = 0, screenY = 0 } = {}) {
+ let selectedRequest = this.selectedRequest;
+
+ let menu = new Menu();
+ menu.append(new MenuItem({
+ id: "request-menu-context-copy-url",
+ label: L10N.getStr("netmonitor.context.copyUrl"),
+ accesskey: L10N.getStr("netmonitor.context.copyUrl.accesskey"),
+ visible: !!selectedRequest,
+ click: () => this.copyUrl(),
+ }));
+
+ menu.append(new MenuItem({
+ id: "request-menu-context-copy-url-params",
+ label: L10N.getStr("netmonitor.context.copyUrlParams"),
+ accesskey: L10N.getStr("netmonitor.context.copyUrlParams.accesskey"),
+ visible: !!(selectedRequest && getUrlQuery(selectedRequest.url)),
+ click: () => this.copyUrlParams(),
+ }));
+
+ menu.append(new MenuItem({
+ id: "request-menu-context-copy-post-data",
+ label: L10N.getStr("netmonitor.context.copyPostData"),
+ accesskey: L10N.getStr("netmonitor.context.copyPostData.accesskey"),
+ visible: !!(selectedRequest && selectedRequest.requestPostData),
+ click: () => this.copyPostData(),
+ }));
+
+ menu.append(new MenuItem({
+ id: "request-menu-context-copy-as-curl",
+ label: L10N.getStr("netmonitor.context.copyAsCurl"),
+ accesskey: L10N.getStr("netmonitor.context.copyAsCurl.accesskey"),
+ visible: !!selectedRequest,
+ click: () => this.copyAsCurl(),
+ }));
+
+ menu.append(new MenuItem({
+ type: "separator",
+ visible: !!selectedRequest,
+ }));
+
+ menu.append(new MenuItem({
+ id: "request-menu-context-copy-request-headers",
+ label: L10N.getStr("netmonitor.context.copyRequestHeaders"),
+ accesskey: L10N.getStr("netmonitor.context.copyRequestHeaders.accesskey"),
+ visible: !!(selectedRequest && selectedRequest.requestHeaders),
+ click: () => this.copyRequestHeaders(),
+ }));
+
+ menu.append(new MenuItem({
+ id: "response-menu-context-copy-response-headers",
+ label: L10N.getStr("netmonitor.context.copyResponseHeaders"),
+ accesskey: L10N.getStr("netmonitor.context.copyResponseHeaders.accesskey"),
+ visible: !!(selectedRequest && selectedRequest.responseHeaders),
+ click: () => this.copyResponseHeaders(),
+ }));
+
+ menu.append(new MenuItem({
+ id: "request-menu-context-copy-response",
+ label: L10N.getStr("netmonitor.context.copyResponse"),
+ accesskey: L10N.getStr("netmonitor.context.copyResponse.accesskey"),
+ visible: !!(selectedRequest &&
+ selectedRequest.responseContent &&
+ selectedRequest.responseContent.content.text &&
+ selectedRequest.responseContent.content.text.length !== 0),
+ click: () => this.copyResponse(),
+ }));
+
+ menu.append(new MenuItem({
+ id: "request-menu-context-copy-image-as-data-uri",
+ label: L10N.getStr("netmonitor.context.copyImageAsDataUri"),
+ accesskey: L10N.getStr("netmonitor.context.copyImageAsDataUri.accesskey"),
+ visible: !!(selectedRequest &&
+ selectedRequest.responseContent &&
+ selectedRequest.responseContent.content.mimeType.includes("image/")),
+ click: () => this.copyImageAsDataUri(),
+ }));
+
+ menu.append(new MenuItem({
+ type: "separator",
+ visible: !!selectedRequest,
+ }));
+
+ menu.append(new MenuItem({
+ id: "request-menu-context-copy-all-as-har",
+ label: L10N.getStr("netmonitor.context.copyAllAsHar"),
+ accesskey: L10N.getStr("netmonitor.context.copyAllAsHar.accesskey"),
+ visible: this.sortedRequests.size > 0,
+ click: () => this.copyAllAsHar(),
+ }));
+
+ menu.append(new MenuItem({
+ id: "request-menu-context-save-all-as-har",
+ label: L10N.getStr("netmonitor.context.saveAllAsHar"),
+ accesskey: L10N.getStr("netmonitor.context.saveAllAsHar.accesskey"),
+ visible: this.sortedRequests.size > 0,
+ click: () => this.saveAllAsHar(),
+ }));
+
+ menu.append(new MenuItem({
+ type: "separator",
+ visible: !!selectedRequest,
+ }));
+
+ menu.append(new MenuItem({
+ id: "request-menu-context-resend",
+ label: L10N.getStr("netmonitor.context.editAndResend"),
+ accesskey: L10N.getStr("netmonitor.context.editAndResend.accesskey"),
+ visible: !!(NetMonitorController.supportsCustomRequest &&
+ selectedRequest && !selectedRequest.isCustom),
+ click: this.cloneSelectedRequest,
+ }));
+
+ menu.append(new MenuItem({
+ type: "separator",
+ visible: !!selectedRequest,
+ }));
+
+ menu.append(new MenuItem({
+ id: "request-menu-context-newtab",
+ label: L10N.getStr("netmonitor.context.newTab"),
+ accesskey: L10N.getStr("netmonitor.context.newTab.accesskey"),
+ visible: !!selectedRequest,
+ click: () => this.openRequestInTab()
+ }));
+
+ menu.append(new MenuItem({
+ id: "request-menu-context-perf",
+ label: L10N.getStr("netmonitor.context.perfTools"),
+ accesskey: L10N.getStr("netmonitor.context.perfTools.accesskey"),
+ visible: !!NetMonitorController.supportsPerfStats,
+ click: () => this.openStatistics(true)
+ }));
+
+ menu.popup(screenX, screenY, NetMonitorController._toolbox);
+ return menu;
+ },
+
+ /**
+ * Opens selected item in a new tab.
+ */
+ openRequestInTab() {
+ let win = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
+ win.openUILinkIn(this.selectedRequest.url, "tab", { relatedToCurrent: true });
+ },
+
+ /**
+ * Copy the request url from the currently selected item.
+ */
+ copyUrl() {
+ clipboardHelper.copyString(this.selectedRequest.url);
+ },
+
+ /**
+ * Copy the request url query string parameters from the currently
+ * selected item.
+ */
+ copyUrlParams() {
+ let { url } = this.selectedRequest;
+ let params = getUrlQuery(url).split("&");
+ let string = params.join(Services.appinfo.OS === "WINNT" ? "\r\n" : "\n");
+ clipboardHelper.copyString(string);
+ },
+
+ /**
+ * Copy the request form data parameters (or raw payload) from
+ * the currently selected item.
+ */
+ copyPostData: Task.async(function* () {
+ let selected = this.selectedRequest;
+
+ // Try to extract any form data parameters.
+ let formDataSections = yield getFormDataSections(
+ selected.requestHeaders,
+ selected.requestHeadersFromUploadStream,
+ selected.requestPostData,
+ gNetwork.getString.bind(gNetwork));
+
+ let params = [];
+ formDataSections.forEach(section => {
+ let paramsArray = parseQueryString(section);
+ if (paramsArray) {
+ params = [...params, ...paramsArray];
+ }
+ });
+
+ let string = params
+ .map(param => param.name + (param.value ? "=" + param.value : ""))
+ .join(Services.appinfo.OS === "WINNT" ? "\r\n" : "\n");
+
+ // Fall back to raw payload.
+ if (!string) {
+ let postData = selected.requestPostData.postData.text;
+ string = yield gNetwork.getString(postData);
+ if (Services.appinfo.OS !== "WINNT") {
+ string = string.replace(/\r/g, "");
+ }
+ }
+
+ clipboardHelper.copyString(string);
+ }),
+
+ /**
+ * Copy a cURL command from the currently selected item.
+ */
+ copyAsCurl: Task.async(function* () {
+ let selected = this.selectedRequest;
+
+ // Create a sanitized object for the Curl command generator.
+ let data = {
+ url: selected.url,
+ method: selected.method,
+ headers: [],
+ httpVersion: selected.httpVersion,
+ postDataText: null
+ };
+
+ // Fetch header values.
+ for (let { name, value } of selected.requestHeaders.headers) {
+ let text = yield gNetwork.getString(value);
+ data.headers.push({ name: name, value: text });
+ }
+
+ // Fetch the request payload.
+ if (selected.requestPostData) {
+ let postData = selected.requestPostData.postData.text;
+ data.postDataText = yield gNetwork.getString(postData);
+ }
+
+ clipboardHelper.copyString(Curl.generateCommand(data));
+ }),
+
+ /**
+ * Copy the raw request headers from the currently selected item.
+ */
+ copyRequestHeaders() {
+ let rawHeaders = this.selectedRequest.requestHeaders.rawHeaders.trim();
+ if (Services.appinfo.OS !== "WINNT") {
+ rawHeaders = rawHeaders.replace(/\r/g, "");
+ }
+ clipboardHelper.copyString(rawHeaders);
+ },
+
+ /**
+ * Copy the raw response headers from the currently selected item.
+ */
+ copyResponseHeaders() {
+ let rawHeaders = this.selectedRequest.responseHeaders.rawHeaders.trim();
+ if (Services.appinfo.OS !== "WINNT") {
+ rawHeaders = rawHeaders.replace(/\r/g, "");
+ }
+ clipboardHelper.copyString(rawHeaders);
+ },
+
+ /**
+ * Copy image as data uri.
+ */
+ copyImageAsDataUri() {
+ const { mimeType, text, encoding } = this.selectedRequest.responseContent.content;
+
+ gNetwork.getString(text).then(string => {
+ let data = formDataURI(mimeType, encoding, string);
+ clipboardHelper.copyString(data);
+ });
+ },
+
+ /**
+ * Copy response data as a string.
+ */
+ copyResponse() {
+ const { text } = this.selectedRequest.responseContent.content;
+
+ gNetwork.getString(text).then(string => {
+ clipboardHelper.copyString(string);
+ });
+ },
+
+ /**
+ * Copy HAR from the network panel content to the clipboard.
+ */
+ copyAllAsHar() {
+ let options = this.getDefaultHarOptions();
+ return HarExporter.copy(options);
+ },
+
+ /**
+ * Save HAR from the network panel content to a file.
+ */
+ saveAllAsHar() {
+ let options = this.getDefaultHarOptions();
+ return HarExporter.save(options);
+ },
+
+ getDefaultHarOptions() {
+ let form = NetMonitorController._target.form;
+ let title = form.title || form.url;
+
+ return {
+ getString: gNetwork.getString.bind(gNetwork),
+ items: this.sortedRequests,
+ title: title
+ };
+ }
+};
+
+module.exports = RequestListContextMenu;
--- a/devtools/client/netmonitor/components/request-list-empty.js
+++ b/devtools/client/netmonitor/components/request-list-empty.js
@@ -62,13 +62,13 @@ const RequestListEmptyNotice = createCla
)
);
}
});
module.exports = connect(
undefined,
dispatch => ({
- onPerfClick: e => dispatch(Actions.openStatistics(true)),
- onReloadClick: e =>
+ onPerfClick: () => dispatch(Actions.openStatistics(true)),
+ onReloadClick: () =>
NetMonitorController.triggerActivity(ACTIVITY_TYPE.RELOAD.WITH_CACHE_DEFAULT),
})
)(RequestListEmptyNotice);
--- a/devtools/client/netmonitor/components/request-list-item.js
+++ b/devtools/client/netmonitor/components/request-list-item.js
@@ -1,21 +1,27 @@
/* 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 react/prop-types */
"use strict";
-const { createClass, createFactory, PropTypes, DOM } = require("devtools/client/shared/vendor/react");
-const { div, span, img } = DOM;
+const {
+ createClass,
+ createFactory,
+ DOM,
+ PropTypes,
+} = require("devtools/client/shared/vendor/react");
const { L10N } = require("../l10n");
+const { getAbbreviatedMimeType } = require("../request-utils");
const { getFormattedSize } = require("../utils/format-utils");
-const { getAbbreviatedMimeType } = require("../request-utils");
+
+const { div, img, span } = DOM;
/**
* Compare two objects on a subset of their properties
*/
function propertiesEqual(props, item1, item2) {
return item1 === item2 || props.every(p => item1[p] === item2[p]);
}
@@ -42,17 +48,17 @@ const UPDATED_REQ_ITEM_PROPS = [
"transferredSize",
"startedMillis",
"totalTime",
];
const UPDATED_REQ_PROPS = [
"index",
"isSelected",
- "firstRequestStartedMillis"
+ "firstRequestStartedMillis",
];
/**
* Render one row in the request list.
*/
const RequestListItem = createClass({
displayName: "RequestListItem",
@@ -71,17 +77,17 @@ const RequestListItem = createClass({
componentDidMount() {
if (this.props.isSelected) {
this.refs.el.focus();
}
},
shouldComponentUpdate(nextProps) {
return !propertiesEqual(UPDATED_REQ_ITEM_PROPS, this.props.item, nextProps.item) ||
- !propertiesEqual(UPDATED_REQ_PROPS, this.props, nextProps);
+ !propertiesEqual(UPDATED_REQ_PROPS, this.props, nextProps);
},
componentDidUpdate(prevProps) {
if (!prevProps.isSelected && this.props.isSelected) {
this.refs.el.focus();
if (this.props.onFocusedNodeChange) {
this.props.onFocusedNodeChange();
}
@@ -114,46 +120,49 @@ const RequestListItem = createClass({
} = this.props;
let classList = [ "request-list-item" ];
if (isSelected) {
classList.push("selected");
}
classList.push(index % 2 ? "odd" : "even");
- return div(
- {
+ return (
+ div({
ref: "el",
className: classList.join(" "),
"data-id": item.id,
tabIndex: 0,
onContextMenu,
onMouseDown,
},
- StatusColumn({ item }),
- MethodColumn({ item }),
- FileColumn({ item }),
- DomainColumn({ item, onSecurityIconClick }),
- CauseColumn({ item }),
- TypeColumn({ item }),
- TransferredSizeColumn({ item }),
- ContentSizeColumn({ item }),
- WaterfallColumn({ item, firstRequestStartedMillis })
+ StatusColumn({ item }),
+ MethodColumn({ item }),
+ FileColumn({ item }),
+ DomainColumn({ item, onSecurityIconClick }),
+ CauseColumn({ item }),
+ TypeColumn({ item }),
+ TransferredSizeColumn({ item }),
+ ContentSizeColumn({ item }),
+ WaterfallColumn({ item, firstRequestStartedMillis }),
+ )
);
}
});
const UPDATED_STATUS_PROPS = [
"status",
"statusText",
"fromCache",
"fromServiceWorker",
];
const StatusColumn = createFactory(createClass({
+ displayName: "StatusColumn",
+
shouldComponentUpdate(nextProps) {
return !propertiesEqual(UPDATED_STATUS_PROPS, this.props.item, nextProps.item);
},
render() {
const { status, statusText, fromCache, fromServiceWorker } = this.props.item;
let code, title;
@@ -173,74 +182,85 @@ const StatusColumn = createFactory(creat
title += " (cached)";
}
if (fromServiceWorker) {
title += " (service worker)";
}
}
}
- return div({ className: "requests-menu-subitem requests-menu-status", title },
- div({ className: "requests-menu-status-icon", "data-code": code }),
- span({ className: "subitem-label requests-menu-status-code" }, status)
+ return (
+ div({ className: "requests-menu-subitem requests-menu-status", title },
+ div({ className: "requests-menu-status-icon", "data-code": code }),
+ span({ className: "subitem-label requests-menu-status-code" }, status),
+ )
);
}
}));
const MethodColumn = createFactory(createClass({
+ displayName: "MethodColumn",
+
shouldComponentUpdate(nextProps) {
return this.props.item.method !== nextProps.item.method;
},
render() {
const { method } = this.props.item;
- return div({ className: "requests-menu-subitem requests-menu-method-box" },
- span({ className: "subitem-label requests-menu-method" }, method)
+ return (
+ div({ className: "requests-menu-subitem requests-menu-method-box" },
+ span({ className: "subitem-label requests-menu-method" }, method)
+ )
);
}
}));
const UPDATED_FILE_PROPS = [
"urlDetails",
"responseContentDataUri",
];
const FileColumn = createFactory(createClass({
+ displayName: "FileColumn",
+
shouldComponentUpdate(nextProps) {
return !propertiesEqual(UPDATED_FILE_PROPS, this.props.item, nextProps.item);
},
render() {
const { urlDetails, responseContentDataUri } = this.props.item;
- return div({ className: "requests-menu-subitem requests-menu-icon-and-file" },
- img({
- className: "requests-menu-icon",
- src: responseContentDataUri,
- hidden: !responseContentDataUri,
- "data-type": responseContentDataUri ? "thumbnail" : undefined
- }),
- div(
- {
+ return (
+ div({ className: "requests-menu-subitem requests-menu-icon-and-file" },
+ img({
+ className: "requests-menu-icon",
+ src: responseContentDataUri,
+ hidden: !responseContentDataUri,
+ "data-type": responseContentDataUri ? "thumbnail" : undefined,
+ }),
+ div({
className: "subitem-label requests-menu-file",
- title: urlDetails.unicodeUrl
+ title: urlDetails.unicodeUrl,
},
- urlDetails.baseNameWithQuery
+ urlDetails.baseNameWithQuery,
+ ),
)
);
}
}));
const UPDATED_DOMAIN_PROPS = [
"urlDetails",
"remoteAddress",
"securityState",
];
const DomainColumn = createFactory(createClass({
+ displayName: "DomainColumn",
+
shouldComponentUpdate(nextProps) {
return !propertiesEqual(UPDATED_DOMAIN_PROPS, this.props.item, nextProps.item);
},
render() {
const { item, onSecurityIconClick } = this.props;
const { urlDetails, remoteAddress, securityState } = item;
@@ -251,29 +271,32 @@ const DomainColumn = createFactory(creat
iconTitle = L10N.getStr("netmonitor.security.state.secure");
} else if (securityState) {
iconClassList.push(`security-state-${securityState}`);
iconTitle = L10N.getStr(`netmonitor.security.state.${securityState}`);
}
let title = urlDetails.host + (remoteAddress ? ` (${remoteAddress})` : "");
- return div(
- { className: "requests-menu-subitem requests-menu-security-and-domain" },
- div({
- className: iconClassList.join(" "),
- title: iconTitle,
- onClick: onSecurityIconClick,
- }),
- span({ className: "subitem-label requests-menu-domain", title }, urlDetails.host)
+ return (
+ div({ className: "requests-menu-subitem requests-menu-security-and-domain" },
+ div({
+ className: iconClassList.join(" "),
+ title: iconTitle,
+ onClick: onSecurityIconClick,
+ }),
+ span({ className: "subitem-label requests-menu-domain", title }, urlDetails.host),
+ )
);
}
}));
const CauseColumn = createFactory(createClass({
+ displayName: "CauseColumn",
+
shouldComponentUpdate(nextProps) {
return this.props.item.cause !== nextProps.item.cause;
},
render() {
const { cause } = this.props.item;
let causeType = "";
@@ -282,57 +305,72 @@ const CauseColumn = createFactory(create
if (cause) {
// Legacy server might send a numeric value. Display it as "unknown"
causeType = typeof cause.type === "string" ? cause.type : "unknown";
causeUri = cause.loadingDocumentUri;
causeHasStack = cause.stacktrace && cause.stacktrace.length > 0;
}
- return div(
- { className: "requests-menu-subitem requests-menu-cause", title: causeUri },
- span({ className: "requests-menu-cause-stack", hidden: !causeHasStack }, "JS"),
- span({ className: "subitem-label" }, causeType)
+ return (
+ div({
+ className: "requests-menu-subitem requests-menu-cause",
+ title: causeUri,
+ },
+ span({
+ className: "requests-menu-cause-stack",
+ hidden: !causeHasStack,
+ }, "JS"),
+ span({ className: "subitem-label" }, causeType),
+ )
);
}
}));
const CONTENT_MIME_TYPE_ABBREVIATIONS = {
"ecmascript": "js",
"javascript": "js",
"x-javascript": "js"
};
const TypeColumn = createFactory(createClass({
+ displayName: "TypeColumn",
+
shouldComponentUpdate(nextProps) {
return this.props.item.mimeType !== nextProps.item.mimeType;
},
render() {
const { mimeType } = this.props.item;
let abbrevType;
if (mimeType) {
abbrevType = getAbbreviatedMimeType(mimeType);
abbrevType = CONTENT_MIME_TYPE_ABBREVIATIONS[abbrevType] || abbrevType;
}
- return div(
- { className: "requests-menu-subitem requests-menu-type", title: mimeType },
- span({ className: "subitem-label" }, abbrevType)
+ return (
+ div({
+ className: "requests-menu-subitem requests-menu-type",
+ title: mimeType,
+ },
+ span({ className: "subitem-label" }, abbrevType),
+ )
);
}
}));
const UPDATED_TRANSFERRED_PROPS = [
"transferredSize",
"fromCache",
"fromServiceWorker",
];
const TransferredSizeColumn = createFactory(createClass({
+ displayName: "TransferredSizeColumn",
+
shouldComponentUpdate(nextProps) {
return !propertiesEqual(UPDATED_TRANSFERRED_PROPS, this.props.item, nextProps.item);
},
render() {
const { transferredSize, fromCache, fromServiceWorker } = this.props.item;
let text;
@@ -344,68 +382,81 @@ const TransferredSizeColumn = createFact
text = L10N.getStr("networkMenu.sizeServiceWorker");
className += " theme-comment";
} else if (typeof transferredSize == "number") {
text = getFormattedSize(transferredSize);
} else if (transferredSize === null) {
text = L10N.getStr("networkMenu.sizeUnavailable");
}
- return div(
- { className: "requests-menu-subitem requests-menu-transferred", title: text },
- span({ className }, text)
+ return (
+ div({
+ className: "requests-menu-subitem requests-menu-transferred",
+ title: text,
+ },
+ span({ className }, text),
+ )
);
}
}));
const ContentSizeColumn = createFactory(createClass({
+ displayName: "ContentSizeColumn",
+
shouldComponentUpdate(nextProps) {
return this.props.item.contentSize !== nextProps.item.contentSize;
},
render() {
const { contentSize } = this.props.item;
let text;
if (typeof contentSize == "number") {
text = getFormattedSize(contentSize);
}
- return div(
- {
+ return (
+ div({
className: "requests-menu-subitem subitem-label requests-menu-size",
- title: text
+ title: text,
},
- span({ className: "subitem-label" }, text)
+ span({ className: "subitem-label" }, text),
+ )
);
}
}));
const UPDATED_WATERFALL_PROPS = [
"eventTimings",
"totalTime",
"fromCache",
"fromServiceWorker",
];
const WaterfallColumn = createFactory(createClass({
+ displayName: "WaterfallColumn",
+
shouldComponentUpdate(nextProps) {
return this.props.firstRequestStartedMillis !== nextProps.firstRequestStartedMillis ||
- !propertiesEqual(UPDATED_WATERFALL_PROPS, this.props.item, nextProps.item);
+ !propertiesEqual(UPDATED_WATERFALL_PROPS, this.props.item, nextProps.item);
},
render() {
const { item, firstRequestStartedMillis } = this.props;
- const startedDeltaMillis = item.startedMillis - firstRequestStartedMillis;
- const paddingInlineStart = `${startedDeltaMillis}px`;
- return div({ className: "requests-menu-subitem requests-menu-waterfall" },
- div(
- { className: "requests-menu-timings", style: { paddingInlineStart } },
- timingBoxes(item)
+ return (
+ div({ className: "requests-menu-subitem requests-menu-waterfall" },
+ div({
+ className: "requests-menu-timings",
+ style: {
+ paddingInlineStart: `${item.startedMillis - firstRequestStartedMillis}px`,
+ },
+ },
+ timingBoxes(item),
+ )
)
);
}
}));
// List of properties of the timing info we want to create boxes for
const TIMING_KEYS = ["blocked", "dns", "connect", "send", "wait", "receive"];
--- a/devtools/client/netmonitor/components/request-list-tooltip.js
+++ b/devtools/client/netmonitor/components/request-list-tooltip.js
@@ -2,20 +2,22 @@
* 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 gNetwork, NetMonitorController */
"use strict";
const { Task } = require("devtools/shared/task");
-const { formDataURI } = require("../request-utils");
+const {
+ setImageTooltip,
+ getImageDimensions,
+} = require("devtools/client/shared/widgets/tooltip/ImageTooltipHelper");
const { WEBCONSOLE_L10N } = require("../l10n");
-const { setImageTooltip,
- getImageDimensions } = require("devtools/client/shared/widgets/tooltip/ImageTooltipHelper");
+const { formDataURI } = require("../request-utils");
// px
const REQUESTS_TOOLTIP_IMAGE_MAX_DIM = 400;
// px
const REQUESTS_TOOLTIP_STACK_TRACE_WIDTH = 600;
const HTML_NS = "http://www.w3.org/1999/xhtml";
--- a/devtools/client/netmonitor/components/request-list.js
+++ b/devtools/client/netmonitor/components/request-list.js
@@ -1,34 +1,127 @@
/* 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-env browser */
+/* globals gNetwork */
+
"use strict";
-const { createFactory, PropTypes, DOM } = require("devtools/client/shared/vendor/react");
-const { div } = DOM;
+const {
+ createClass,
+ createFactory,
+ DOM,
+ PropTypes,
+} = require("devtools/client/shared/vendor/react");
const { connect } = require("devtools/client/shared/vendor/react-redux");
-const RequestListHeader = createFactory(require("./request-list-header"));
+const { setNamedTimeout } = require("devtools/client/shared/widgets/view-helpers");
+const Actions = require("../actions/index");
+const { Prefs } = require("../prefs");
+const { getFormDataSections } = require("../request-utils");
+const {
+ getActiveFilters,
+ getSelectedRequest,
+} = require("../selectors/index");
+
+// Components
+const RequestListContent = createFactory(require("./request-list-content"));
const RequestListEmptyNotice = createFactory(require("./request-list-empty"));
-const RequestListContent = createFactory(require("./request-list-content"));
+const RequestListHeader = createFactory(require("./request-list-header"));
+
+const { div } = DOM;
/**
- * Renders the request list - header, empty text, the actual content with rows
+ * Request panel component
*/
-const RequestList = function ({ isEmpty }) {
- return div({ className: "request-list-container" },
- RequestListHeader(),
- isEmpty ? RequestListEmptyNotice() : RequestListContent()
- );
-};
+const RequestList = createClass({
+ displayName: "RequestList",
+
+ propTypes: {
+ activeFilters: PropTypes.array,
+ dispatch: PropTypes.func,
+ isEmpty: PropTypes.bool.isRequired,
+ request: PropTypes.object,
+ networkDetailsOpen: PropTypes.bool,
+ },
+
+ componentDidMount() {
+ const { dispatch } = this.props;
+
+ Prefs.filters.forEach((type) => dispatch(Actions.toggleRequestFilterType(type)));
+ this.splitter = document.querySelector("#network-inspector-view-splitter");
+ this.splitter.addEventListener("mouseup", this.resize);
+ window.addEventListener("resize", this.resize);
+ },
+
+ componentWillReceiveProps(nextProps) {
+ const { dispatch, request = {}, networkDetailsOpen } = this.props;
+
+ if (nextProps.request && nextProps.request !== request) {
+ dispatch(Actions.openNetworkDetails(true));
+ }
+
+ if (nextProps.networkDetailsOpen !== networkDetailsOpen) {
+ this.resize();
+ }
+
+ const {
+ formDataSections,
+ requestHeaders,
+ requestHeadersFromUploadStream,
+ requestPostData,
+ } = nextProps.request || {};
-RequestList.displayName = "RequestList";
+ if (!formDataSections && requestHeaders &&
+ requestHeadersFromUploadStream && requestPostData) {
+ getFormDataSections(
+ requestHeaders,
+ requestHeadersFromUploadStream,
+ requestPostData,
+ gNetwork.getString.bind(gNetwork),
+ ).then((newFormDataSections) => {
+ dispatch(Actions.updateRequest(
+ request.id,
+ { formDataSections: newFormDataSections },
+ true,
+ ));
+ });
+ }
+ },
+
+ componentWillUnmount() {
+ Prefs.filters = this.props.activeFilters;
+ this.splitter.removeEventListener("mouseup", this.resize);
+ window.removeEventListener("resize", this.resize);
+ },
-RequestList.propTypes = {
- isEmpty: PropTypes.bool.isRequired,
-};
+ resize() {
+ const { dispatch } = this.props;
+ // Allow requests to settle down first.
+ setNamedTimeout("resize-events", 50, () => {
+ const waterfallHeaderEl =
+ document.querySelector("#requests-menu-waterfall-header-box");
+ if (waterfallHeaderEl) {
+ const { width } = waterfallHeaderEl.getBoundingClientRect();
+ dispatch(Actions.resizeWaterfall(width));
+ }
+ });
+ },
+
+ render() {
+ return (
+ div({ className: "request-list-container" },
+ RequestListHeader(),
+ this.props.isEmpty ? RequestListEmptyNotice() : RequestListContent(),
+ )
+ );
+ }
+});
module.exports = connect(
- state => ({
- isEmpty: state.requests.requests.isEmpty()
+ (state) => ({
+ activeFilters: getActiveFilters(state),
+ isEmpty: state.requests.requests.isEmpty(),
+ request: getSelectedRequest(state),
+ networkDetailsOpen: state.ui.networkDetailsOpen,
})
)(RequestList);
--- a/devtools/client/netmonitor/components/toolbar.js
+++ b/devtools/client/netmonitor/components/toolbar.js
@@ -111,17 +111,17 @@ function Toolbar({
type: "filter",
onChange: setRequestFilterText,
}),
button({
className: toggleButtonClassName.join(" "),
title: networkDetailsOpen ? COLLPASE_DETAILS_PANE : EXPAND_DETAILS_PANE,
disabled: networkDetailsToggleDisabled,
tabIndex: "0",
- onMouseDown: toggleNetworkDetails,
+ onClick: toggleNetworkDetails,
}),
)
)
);
}
Toolbar.displayName = "Toolbar";
--- a/devtools/client/netmonitor/har/har-builder.js
+++ b/devtools/client/netmonitor/har/har-builder.js
@@ -25,18 +25,17 @@ const HAR_VERSION = "1.1";
* This object is responsible for building HAR file. See HAR spec:
* https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/HAR/Overview.html
* http://www.softwareishard.com/blog/har-12-spec/
*
* @param {Object} options configuration object
*
* The following options are supported:
*
- * - items {Array}: List of Network requests to be exported. It is possible
- * to use directly: NetMonitorView.RequestsMenu.items
+ * - items {Array}: List of Network requests to be exported.
*
* - id {String}: ID of the exported page.
*
* - title {String}: Title of the exported page.
*
* - includeResponseBodies {Boolean}: Set to true to include HTTP response
* bodies in the result data structure.
*/
--- a/devtools/client/netmonitor/har/har-exporter.js
+++ b/devtools/client/netmonitor/har/har-exporter.js
@@ -41,18 +41,17 @@ const HarExporter = {
* Configuration object
*
* The following options are supported:
*
* - includeResponseBodies {Boolean}: If set to true, HTTP response bodies
* are also included in the HAR file (can produce significantly bigger
* amount of data).
*
- * - items {Array}: List of Network requests to be exported. It is possible
- * to use directly: NetMonitorView.RequestsMenu.items
+ * - items {Array}: List of Network requests to be exported.
*
* - jsonp {Boolean}: If set to true the export format is HARP (support
* for JSONP syntax).
*
* - jsonpCallback {String}: Default name of JSONP callback (used for
* HARP format).
*
* - compress {Boolean}: If set to true the final HAR file is zipped.
--- a/devtools/client/netmonitor/har/test/browser_net_har_copy_all_as_har.js
+++ b/devtools/client/netmonitor/har/test/browser_net_har_copy_all_as_har.js
@@ -6,26 +6,29 @@
/**
* Basic tests for exporting Network panel content into HAR format.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(SIMPLE_URL);
info("Starting test... ");
- let { NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let RequestListContextMenu = windowRequire(
+ "devtools/client/netmonitor/components/request-list-context-menu");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, 1);
tab.linkedBrowser.reload();
yield wait;
- yield RequestsMenu.contextMenu.copyAllAsHar();
+ let contextMenu = new RequestListContextMenu({});
+ yield contextMenu.copyAllAsHar();
let jsonString = SpecialPowers.getClipboardData("text/unicode");
let har = JSON.parse(jsonString);
// Check out HAR log
isnot(har.log, null, "The HAR log must exist");
is(har.log.creator.name, "Firefox", "The creator field must be set");
is(har.log.browser.name, "Firefox", "The browser field must be set");
--- a/devtools/client/netmonitor/har/test/browser_net_har_post_data.js
+++ b/devtools/client/netmonitor/har/test/browser_net_har_post_data.js
@@ -7,30 +7,33 @@
* Tests for exporting POST data into HAR format.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(
HAR_EXAMPLE_URL + "html_har_post-data-test-page.html");
info("Starting test... ");
- let { NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let RequestListContextMenu = windowRequire(
+ "devtools/client/netmonitor/components/request-list-context-menu");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
// Execute one POST request on the page and wait till its done.
let wait = waitForNetworkEvents(monitor, 0, 1);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.executeTest();
});
yield wait;
// Copy HAR into the clipboard (asynchronous).
- let jsonString = yield RequestsMenu.contextMenu.copyAllAsHar();
+ let contextMenu = new RequestListContextMenu({});
+ let jsonString = yield contextMenu.copyAllAsHar();
let har = JSON.parse(jsonString);
// Check out the HAR log.
isnot(har.log, null, "The HAR log must exist");
is(har.log.pages.length, 1, "There must be one page");
is(har.log.entries.length, 1, "There must be one request");
let entry = har.log.entries[0];
--- a/devtools/client/netmonitor/har/test/browser_net_har_throttle_upload.js
+++ b/devtools/client/netmonitor/har/test/browser_net_har_throttle_upload.js
@@ -11,18 +11,22 @@ add_task(function* () {
});
function* throttleUploadTest(actuallyThrottle) {
let { tab, monitor } = yield initNetMonitor(
HAR_EXAMPLE_URL + "html_har_post-data-test-page.html");
info("Starting test... (actuallyThrottle = " + actuallyThrottle + ")");
- let { NetMonitorController, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire, NetMonitorController } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let RequestListContextMenu = windowRequire(
+ "devtools/client/netmonitor/components/request-list-context-menu");
+
+ gStore.dispatch(Actions.batchEnable(false));
const size = 4096;
const uploadSize = actuallyThrottle ? size / 3 : 0;
const request = {
"NetworkMonitor.throttleData": {
latencyMean: 0,
latencyMax: 0,
@@ -30,33 +34,32 @@ function* throttleUploadTest(actuallyThr
downloadBPSMax: 200000,
uploadBPSMean: uploadSize,
uploadBPSMax: uploadSize,
},
};
let client = NetMonitorController.webConsoleClient;
info("sending throttle request");
- let deferred = promise.defer();
- client.setPreferences(request, response => {
- deferred.resolve(response);
+ yield new Promise((resolve) => {
+ client.setPreferences(request, response => {
+ resolve(response);
+ });
});
- yield deferred.promise;
-
- RequestsMenu.lazyUpdate = false;
// Execute one POST request on the page and wait till its done.
let wait = waitForNetworkEvents(monitor, 0, 1);
yield ContentTask.spawn(tab.linkedBrowser, { size }, function* (args) {
content.wrappedJSObject.executeTest2(args.size);
});
yield wait;
// Copy HAR into the clipboard (asynchronous).
- let jsonString = yield RequestsMenu.contextMenu.copyAllAsHar();
+ let contextMenu = new RequestListContextMenu({});
+ let jsonString = yield contextMenu.copyAllAsHar();
let har = JSON.parse(jsonString);
// Check out the HAR log.
isnot(har.log, null, "The HAR log must exist");
is(har.log.pages.length, 1, "There must be one page");
is(har.log.entries.length, 1, "There must be one request");
let entry = har.log.entries[0];
--- a/devtools/client/netmonitor/moz.build
+++ b/devtools/client/netmonitor/moz.build
@@ -17,19 +17,17 @@ DevToolsModules(
'constants.js',
'events.js',
'filter-predicates.js',
'l10n.js',
'netmonitor-controller.js',
'netmonitor-view.js',
'panel.js',
'prefs.js',
- 'request-list-context-menu.js',
'request-utils.js',
- 'requests-menu-view.js',
'sort-predicates.js',
'store.js',
'waterfall-background.js',
)
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
with Files('**'):
--- a/devtools/client/netmonitor/netmonitor-controller.js
+++ b/devtools/client/netmonitor/netmonitor-controller.js
@@ -1,35 +1,35 @@
/* 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 */
-/* globals window, NetMonitorView, gStore, dumpn */
+/* globals window, NetMonitorView, gStore, gNetwork, dumpn */
"use strict";
const promise = require("promise");
const Services = require("Services");
-const {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm");
const EventEmitter = require("devtools/shared/event-emitter");
-const Editor = require("devtools/client/sourceeditor/editor");
-const {TimelineFront} = require("devtools/shared/fronts/timeline");
-const {Task} = require("devtools/shared/task");
+const { TimelineFront } = require("devtools/shared/fronts/timeline");
+const { CurlUtils } = require("devtools/client/shared/curl");
+const { Task } = require("devtools/shared/task");
const { ACTIVITY_TYPE } = require("./constants");
const { EVENTS } = require("./events");
const { configureStore } = require("./store");
const Actions = require("./actions/index");
-const { getDisplayedRequestById } = require("./selectors/index");
-const { Prefs } = require("./prefs");
-
-XPCOMUtils.defineConstant(window, "EVENTS", EVENTS);
-XPCOMUtils.defineConstant(window, "ACTIVITY_TYPE", ACTIVITY_TYPE);
-XPCOMUtils.defineConstant(window, "Editor", Editor);
-XPCOMUtils.defineConstant(window, "Prefs", Prefs);
+const {
+ fetchHeaders,
+ formDataURI,
+} = require("./request-utils");
+const {
+ getRequestById,
+ getDisplayedRequestById,
+} = require("./selectors/index");
// Initialize the global Redux store
window.gStore = configureStore();
/**
* Object defining the network monitor controller components.
*/
var NetMonitorController = {
@@ -413,17 +413,18 @@ TargetEventsHandler.prototype = {
* @param object packet
* Packet received from the server.
*/
_onTabNavigated: function (type, packet) {
switch (type) {
case "will-navigate": {
// Reset UI.
if (!Services.prefs.getBoolPref("devtools.webconsole.persistlog")) {
- NetMonitorView.RequestsMenu.reset();
+ gStore.dispatch(Actions.batchReset());
+ gStore.dispatch(Actions.clearRequests());
} else {
// If the log is persistent, just clear all accumulated timing markers.
gStore.dispatch(Actions.clearTimingMarkers());
}
window.emit(EVENTS.TARGET_WILL_NAVIGATE);
break;
}
@@ -441,25 +442,28 @@ TargetEventsHandler.prototype = {
NetMonitorController.shutdownNetMonitor();
}
};
/**
* Functions handling target network events.
*/
function NetworkEventsHandler() {
+ this.addRequest = this.addRequest.bind(this);
+ this.updateRequest = this.updateRequest.bind(this);
this._onNetworkEvent = this._onNetworkEvent.bind(this);
this._onNetworkEventUpdate = this._onNetworkEventUpdate.bind(this);
this._onDocLoadingMarker = this._onDocLoadingMarker.bind(this);
this._onRequestHeaders = this._onRequestHeaders.bind(this);
this._onRequestCookies = this._onRequestCookies.bind(this);
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);
}
NetworkEventsHandler.prototype = {
get client() {
return NetMonitorController._target.client;
},
@@ -543,203 +547,343 @@ NetworkEventsHandler.prototype = {
startedDateTime,
request: { method, url },
isXHR,
cause,
fromCache,
fromServiceWorker
} = networkInfo;
- NetMonitorView.RequestsMenu.addRequest(
+ this.addRequest(
actor, {startedDateTime, method, url, isXHR, cause, fromCache, fromServiceWorker}
);
window.emit(EVENTS.NETWORK_EVENT, actor);
},
+ addRequest(id, data) {
+ let { method, url, isXHR, cause, startedDateTime, fromCache,
+ fromServiceWorker } = data;
+
+ gStore.dispatch(Actions.addRequest(
+ id,
+ {
+ // Convert the received date/time string to a unix timestamp.
+ startedMillis: Date.parse(startedDateTime),
+ method,
+ url,
+ isXHR,
+ cause,
+ fromCache,
+ fromServiceWorker,
+ },
+ true
+ ))
+ .then(() => window.emit(EVENTS.REQUEST_ADDED, id));
+ },
+
+ updateRequest: Task.async(function* (id, data) {
+ const action = Actions.updateRequest(id, data, true);
+ yield gStore.dispatch(action);
+ let {
+ responseContent,
+ responseCookies,
+ responseHeaders,
+ requestCookies,
+ requestHeaders,
+ requestPostData,
+ } = action.data;
+ let request = getRequestById(gStore.getState(), action.id);
+
+ if (requestHeaders && requestHeaders.headers && requestHeaders.headers.length) {
+ let headers = yield fetchHeaders(
+ requestHeaders, gNetwork.getString.bind(gNetwork));
+ if (headers) {
+ yield gStore.dispatch(Actions.updateRequest(
+ action.id,
+ { requestHeaders: headers },
+ true,
+ ));
+ }
+ }
+
+ if (responseHeaders && responseHeaders.headers && responseHeaders.headers.length) {
+ let headers = yield fetchHeaders(
+ responseHeaders, gNetwork.getString.bind(gNetwork));
+ if (headers) {
+ yield gStore.dispatch(Actions.updateRequest(
+ action.id,
+ { responseHeaders: headers },
+ true,
+ ));
+ }
+ }
+
+ if (request && responseContent && responseContent.content) {
+ let { mimeType } = request;
+ let { text, encoding } = responseContent.content;
+ let response = yield gNetwork.getString(text);
+ let payload = {};
+
+ if (mimeType.includes("image/")) {
+ payload.responseContentDataUri = formDataURI(mimeType, encoding, response);
+ }
+
+ responseContent.content.text = response;
+ payload.responseContent = responseContent;
+
+ yield gStore.dispatch(Actions.updateRequest(action.id, payload, true));
+
+ if (mimeType.includes("image/")) {
+ window.emit(EVENTS.RESPONSE_IMAGE_THUMBNAIL_DISPLAYED);
+ }
+ }
+
+ // 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 = yield gNetwork.getString(text);
+ const headers = CurlUtils.getHeadersFromMultipartText(postData);
+ 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 };
+
+ yield gStore.dispatch(Actions.updateRequest(action.id, payload, true));
+ }
+
+ // 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
+ let cookies = requestCookies.cookies ?
+ requestCookies.cookies : requestCookies;
+ // make sure cookies is iterable
+ if (typeof cookies[Symbol.iterator] === "function") {
+ for (let cookie of cookies) {
+ reqCookies.push(Object.assign({}, cookie, {
+ value: yield gNetwork.getString(cookie.value),
+ }));
+ }
+ if (reqCookies.length) {
+ yield gStore.dispatch(Actions.updateRequest(
+ action.id,
+ { requestCookies: reqCookies },
+ 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: yield gNetwork.getString(cookie.value),
+ }));
+ }
+ if (resCookies.length) {
+ yield gStore.dispatch(Actions.updateRequest(
+ action.id,
+ { responseCookies: resCookies },
+ true));
+ }
+ }
+ }
+ }),
+
/**
* The "networkEventUpdate" message type handler.
*
* @param string type
* Message type.
* @param object packet
* The message received from the server.
* @param object networkInfo
* The network request information.
*/
_onNetworkEventUpdate: function (type, { packet, networkInfo }) {
let { actor } = networkInfo;
-
switch (packet.updateType) {
case "requestHeaders":
this.webConsoleClient.getRequestHeaders(actor, this._onRequestHeaders);
window.emit(EVENTS.UPDATING_REQUEST_HEADERS, actor);
break;
case "requestCookies":
this.webConsoleClient.getRequestCookies(actor, this._onRequestCookies);
window.emit(EVENTS.UPDATING_REQUEST_COOKIES, actor);
break;
case "requestPostData":
this.webConsoleClient.getRequestPostData(actor,
this._onRequestPostData);
window.emit(EVENTS.UPDATING_REQUEST_POST_DATA, actor);
break;
case "securityInfo":
- NetMonitorView.RequestsMenu.updateRequest(actor, {
+ this.updateRequest(actor, {
securityState: networkInfo.securityInfo,
});
this.webConsoleClient.getSecurityInfo(actor, this._onSecurityInfo);
window.emit(EVENTS.UPDATING_SECURITY_INFO, actor);
break;
case "responseHeaders":
this.webConsoleClient.getResponseHeaders(actor,
this._onResponseHeaders);
window.emit(EVENTS.UPDATING_RESPONSE_HEADERS, actor);
break;
case "responseCookies":
this.webConsoleClient.getResponseCookies(actor,
this._onResponseCookies);
window.emit(EVENTS.UPDATING_RESPONSE_COOKIES, actor);
break;
case "responseStart":
- NetMonitorView.RequestsMenu.updateRequest(actor, {
+ this.updateRequest(actor, {
httpVersion: networkInfo.response.httpVersion,
remoteAddress: networkInfo.response.remoteAddress,
remotePort: networkInfo.response.remotePort,
status: networkInfo.response.status,
statusText: networkInfo.response.statusText,
headersSize: networkInfo.response.headersSize
});
window.emit(EVENTS.STARTED_RECEIVING_RESPONSE, actor);
break;
case "responseContent":
- NetMonitorView.RequestsMenu.updateRequest(actor, {
+ this.updateRequest(actor, {
contentSize: networkInfo.response.bodySize,
transferredSize: networkInfo.response.transferredSize,
mimeType: networkInfo.response.content.mimeType
});
this.webConsoleClient.getResponseContent(actor,
this._onResponseContent);
window.emit(EVENTS.UPDATING_RESPONSE_CONTENT, actor);
break;
case "eventTimings":
- NetMonitorView.RequestsMenu.updateRequest(actor, {
+ this.updateRequest(actor, {
totalTime: networkInfo.totalTime
});
this.webConsoleClient.getEventTimings(actor, this._onEventTimings);
window.emit(EVENTS.UPDATING_EVENT_TIMINGS, actor);
break;
}
},
/**
* Handles additional information received for a "requestHeaders" packet.
*
* @param object response
* The message received from the server.
*/
_onRequestHeaders: function (response) {
- NetMonitorView.RequestsMenu.updateRequest(response.from, {
+ this.updateRequest(response.from, {
requestHeaders: response
}).then(() => {
window.emit(EVENTS.RECEIVED_REQUEST_HEADERS, response.from);
});
},
/**
* Handles additional information received for a "requestCookies" packet.
*
* @param object response
* The message received from the server.
*/
_onRequestCookies: function (response) {
- NetMonitorView.RequestsMenu.updateRequest(response.from, {
+ this.updateRequest(response.from, {
requestCookies: response
}).then(() => {
window.emit(EVENTS.RECEIVED_REQUEST_COOKIES, response.from);
});
},
/**
* Handles additional information received for a "requestPostData" packet.
*
* @param object response
* The message received from the server.
*/
_onRequestPostData: function (response) {
- NetMonitorView.RequestsMenu.updateRequest(response.from, {
+ this.updateRequest(response.from, {
requestPostData: response
}).then(() => {
window.emit(EVENTS.RECEIVED_REQUEST_POST_DATA, response.from);
});
},
/**
* Handles additional information received for a "securityInfo" packet.
*
* @param object response
* The message received from the server.
*/
_onSecurityInfo: function (response) {
- NetMonitorView.RequestsMenu.updateRequest(response.from, {
+ this.updateRequest(response.from, {
securityInfo: response.securityInfo
}).then(() => {
window.emit(EVENTS.RECEIVED_SECURITY_INFO, response.from);
});
},
/**
* Handles additional information received for a "responseHeaders" packet.
*
* @param object response
* The message received from the server.
*/
_onResponseHeaders: function (response) {
- NetMonitorView.RequestsMenu.updateRequest(response.from, {
+ this.updateRequest(response.from, {
responseHeaders: response
}).then(() => {
window.emit(EVENTS.RECEIVED_RESPONSE_HEADERS, response.from);
});
},
/**
* Handles additional information received for a "responseCookies" packet.
*
* @param object response
* The message received from the server.
*/
_onResponseCookies: function (response) {
- NetMonitorView.RequestsMenu.updateRequest(response.from, {
+ this.updateRequest(response.from, {
responseCookies: response
}).then(() => {
window.emit(EVENTS.RECEIVED_RESPONSE_COOKIES, response.from);
});
},
/**
* Handles additional information received for a "responseContent" packet.
*
* @param object response
* The message received from the server.
*/
_onResponseContent: function (response) {
- NetMonitorView.RequestsMenu.updateRequest(response.from, {
+ this.updateRequest(response.from, {
responseContent: response
}).then(() => {
window.emit(EVENTS.RECEIVED_RESPONSE_CONTENT, response.from);
});
},
/**
* Handles additional information received for a "eventTimings" packet.
*
* @param object response
* The message received from the server.
*/
_onEventTimings: function (response) {
- NetMonitorView.RequestsMenu.updateRequest(response.from, {
+ this.updateRequest(response.from, {
eventTimings: response
}).then(() => {
window.emit(EVENTS.RECEIVED_EVENT_TIMINGS, response.from);
});
},
/**
* Fetches the full text of a LongString.
--- a/devtools/client/netmonitor/netmonitor-view.js
+++ b/devtools/client/netmonitor/netmonitor-view.js
@@ -1,102 +1,97 @@
/* 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 */
-/* globals $, gStore, NetMonitorController */
+/* eslint-env browser */
+/* globals gStore, NetMonitorController */
"use strict";
-const { RequestsMenuView } = require("./requests-menu-view");
const { ACTIVITY_TYPE } = require("./constants");
const { createFactory } = require("devtools/client/shared/vendor/react");
const ReactDOM = require("devtools/client/shared/vendor/react-dom");
const Provider = createFactory(require("devtools/client/shared/vendor/react-redux").Provider);
// Components
const NetworkDetailsPanel = createFactory(require("./shared/components/network-details-panel"));
+const RequestList = createFactory(require("./components/request-list"));
const StatisticsPanel = createFactory(require("./components/statistics-panel"));
const Toolbar = createFactory(require("./components/toolbar"));
/**
* Object defining the network monitor view components.
*/
-var NetMonitorView = {
+exports.NetMonitorView = {
/**
* Initializes the network monitor view.
*/
initialize: function () {
- this._body = $("#body");
+ this._body = document.querySelector("#body");
- this.networkDetailsPanel = $("#react-network-details-panel-hook");
-
+ this.networkDetailsPanel = document.querySelector(
+ "#react-network-details-panel-hook");
ReactDOM.render(Provider(
{ store: gStore },
NetworkDetailsPanel({ toolbox: NetMonitorController._toolbox }),
), this.networkDetailsPanel);
- this.statisticsPanel = $("#react-statistics-panel-hook");
+ this.requestList = document.querySelector("#react-request-list-hook");
+ ReactDOM.render(Provider(
+ { store: gStore },
+ RequestList({ toolbox: NetMonitorController._toolbox })
+ ), this.requestList);
+ this.statisticsPanel = document.querySelector("#react-statistics-panel-hook");
ReactDOM.render(Provider(
{ store: gStore },
StatisticsPanel(),
), this.statisticsPanel);
- this.toolbar = $("#react-toolbar-hook");
-
+ this.toolbar = document.querySelector("#react-toolbar-hook");
ReactDOM.render(Provider(
{ store: gStore },
Toolbar(),
), this.toolbar);
- this.RequestsMenu.initialize(gStore);
-
// Store watcher here is for observing the statisticsOpen state change.
// It should be removed once we migrate to react and apply react/redex binding.
this.unsubscribeStore = gStore.subscribe(storeWatcher(
false,
() => gStore.getState().ui.statisticsOpen,
this.toggleFrontendMode.bind(this)
));
},
/**
* Destroys the network monitor view.
*/
destroy: function () {
- this.RequestsMenu.destroy();
ReactDOM.unmountComponentAtNode(this.networkDetailsPanel);
+ ReactDOM.unmountComponentAtNode(this.requestList);
ReactDOM.unmountComponentAtNode(this.statisticsPanel);
ReactDOM.unmountComponentAtNode(this.toolbar);
this.unsubscribeStore();
},
toggleFrontendMode: function () {
if (gStore.getState().ui.statisticsOpen) {
- this._body.selectedPanel = $("#react-statistics-panel-hook");
+ this._body.selectedPanel = document.querySelector("#react-statistics-panel-hook");
NetMonitorController.triggerActivity(ACTIVITY_TYPE.RELOAD.WITH_CACHE_ENABLED);
} else {
- this._body.selectedPanel = $("#inspector-panel");
+ this._body.selectedPanel = document.querySelector("#inspector-panel");
}
},
};
// A smart store watcher to notify store changes as necessary
function storeWatcher(initialValue, reduceValue, onChange) {
let currentValue = initialValue;
return () => {
const newValue = reduceValue();
if (newValue !== currentValue) {
onChange();
currentValue = newValue;
}
};
}
-
-/**
- * Preliminary setup for the NetMonitorView object.
- */
-NetMonitorView.RequestsMenu = new RequestsMenuView();
-
-exports.NetMonitorView = NetMonitorView;
--- a/devtools/client/netmonitor/netmonitor.xul
+++ b/devtools/client/netmonitor/netmonitor.xul
@@ -21,17 +21,17 @@
<vbox id="inspector-panel" flex="1">
<html:div xmlns="http://www.w3.org/1999/xhtml"
id="react-toolbar-hook"/>
<hbox id="network-table-and-sidebar"
class="devtools-responsive-container"
flex="1">
<html:div xmlns="http://www.w3.org/1999/xhtml"
- id="network-table"
+ id="react-request-list-hook"
class="devtools-main-content">
</html:div>
<splitter id="network-inspector-view-splitter"
class="devtools-side-splitter"/>
<box id="splitter-adjustable-box"
hidden="true">
deleted file mode 100644
--- a/devtools/client/netmonitor/request-list-context-menu.js
+++ /dev/null
@@ -1,358 +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/. */
-
-/* globals NetMonitorController, NetMonitorView, gNetwork */
-
-"use strict";
-
-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 Menu = require("devtools/client/framework/menu");
-const MenuItem = require("devtools/client/framework/menu-item");
-const { L10N } = require("./l10n");
-const {
- formDataURI,
- getFormDataSections,
- getUrlQuery,
- parseQueryString,
-} = require("./request-utils");
-const Actions = require("./actions/index");
-
-loader.lazyRequireGetter(this, "HarExporter",
- "devtools/client/netmonitor/har/har-exporter", true);
-
-loader.lazyServiceGetter(this, "clipboardHelper",
- "@mozilla.org/widget/clipboardhelper;1", "nsIClipboardHelper");
-
-function RequestListContextMenu() {}
-
-RequestListContextMenu.prototype = {
- get selectedItem() {
- return NetMonitorView.RequestsMenu.selectedItem;
- },
-
- get items() {
- return NetMonitorView.RequestsMenu.items;
- },
-
- /**
- * Initialization function, called when the RequestsMenu is initialized.
- */
- initialize: function (store) {
- this.store = store;
- },
-
- /**
- * Handle the context menu opening. Hide items if no request is selected.
- * Since visible attribute only accept boolean value but the method call may
- * return undefined, we use !! to force convert any object to boolean
- */
- open({ screenX = 0, screenY = 0 } = {}) {
- let selectedItem = this.selectedItem;
-
- let menu = new Menu();
- menu.append(new MenuItem({
- id: "request-menu-context-copy-url",
- label: L10N.getStr("netmonitor.context.copyUrl"),
- accesskey: L10N.getStr("netmonitor.context.copyUrl.accesskey"),
- visible: !!selectedItem,
- click: () => this.copyUrl(),
- }));
-
- menu.append(new MenuItem({
- id: "request-menu-context-copy-url-params",
- label: L10N.getStr("netmonitor.context.copyUrlParams"),
- accesskey: L10N.getStr("netmonitor.context.copyUrlParams.accesskey"),
- visible: !!(selectedItem && getUrlQuery(selectedItem.url)),
- click: () => this.copyUrlParams(),
- }));
-
- menu.append(new MenuItem({
- id: "request-menu-context-copy-post-data",
- label: L10N.getStr("netmonitor.context.copyPostData"),
- accesskey: L10N.getStr("netmonitor.context.copyPostData.accesskey"),
- visible: !!(selectedItem && selectedItem.requestPostData),
- click: () => this.copyPostData(),
- }));
-
- menu.append(new MenuItem({
- id: "request-menu-context-copy-as-curl",
- label: L10N.getStr("netmonitor.context.copyAsCurl"),
- accesskey: L10N.getStr("netmonitor.context.copyAsCurl.accesskey"),
- visible: !!selectedItem,
- click: () => this.copyAsCurl(),
- }));
-
- menu.append(new MenuItem({
- type: "separator",
- visible: !!selectedItem,
- }));
-
- menu.append(new MenuItem({
- id: "request-menu-context-copy-request-headers",
- label: L10N.getStr("netmonitor.context.copyRequestHeaders"),
- accesskey: L10N.getStr("netmonitor.context.copyRequestHeaders.accesskey"),
- visible: !!(selectedItem && selectedItem.requestHeaders),
- click: () => this.copyRequestHeaders(),
- }));
-
- menu.append(new MenuItem({
- id: "response-menu-context-copy-response-headers",
- label: L10N.getStr("netmonitor.context.copyResponseHeaders"),
- accesskey: L10N.getStr("netmonitor.context.copyResponseHeaders.accesskey"),
- visible: !!(selectedItem && selectedItem.responseHeaders),
- click: () => this.copyResponseHeaders(),
- }));
-
- menu.append(new MenuItem({
- id: "request-menu-context-copy-response",
- label: L10N.getStr("netmonitor.context.copyResponse"),
- accesskey: L10N.getStr("netmonitor.context.copyResponse.accesskey"),
- visible: !!(selectedItem &&
- selectedItem.responseContent &&
- selectedItem.responseContent.content.text &&
- selectedItem.responseContent.content.text.length !== 0),
- click: () => this.copyResponse(),
- }));
-
- menu.append(new MenuItem({
- id: "request-menu-context-copy-image-as-data-uri",
- label: L10N.getStr("netmonitor.context.copyImageAsDataUri"),
- accesskey: L10N.getStr("netmonitor.context.copyImageAsDataUri.accesskey"),
- visible: !!(selectedItem &&
- selectedItem.responseContent &&
- selectedItem.responseContent.content.mimeType.includes("image/")),
- click: () => this.copyImageAsDataUri(),
- }));
-
- menu.append(new MenuItem({
- type: "separator",
- visible: !!selectedItem,
- }));
-
- menu.append(new MenuItem({
- id: "request-menu-context-copy-all-as-har",
- label: L10N.getStr("netmonitor.context.copyAllAsHar"),
- accesskey: L10N.getStr("netmonitor.context.copyAllAsHar.accesskey"),
- visible: this.items.size > 0,
- click: () => this.copyAllAsHar(),
- }));
-
- menu.append(new MenuItem({
- id: "request-menu-context-save-all-as-har",
- label: L10N.getStr("netmonitor.context.saveAllAsHar"),
- accesskey: L10N.getStr("netmonitor.context.saveAllAsHar.accesskey"),
- visible: this.items.size > 0,
- click: () => this.saveAllAsHar(),
- }));
-
- menu.append(new MenuItem({
- type: "separator",
- visible: !!selectedItem,
- }));
-
- menu.append(new MenuItem({
- id: "request-menu-context-resend",
- label: L10N.getStr("netmonitor.context.editAndResend"),
- accesskey: L10N.getStr("netmonitor.context.editAndResend.accesskey"),
- visible: !!(NetMonitorController.supportsCustomRequest &&
- selectedItem && !selectedItem.isCustom),
- click: () => NetMonitorView.RequestsMenu.cloneSelectedRequest(),
- }));
-
- menu.append(new MenuItem({
- type: "separator",
- visible: !!selectedItem,
- }));
-
- menu.append(new MenuItem({
- id: "request-menu-context-newtab",
- label: L10N.getStr("netmonitor.context.newTab"),
- accesskey: L10N.getStr("netmonitor.context.newTab.accesskey"),
- visible: !!selectedItem,
- click: () => this.openRequestInTab()
- }));
-
- menu.append(new MenuItem({
- id: "request-menu-context-perf",
- label: L10N.getStr("netmonitor.context.perfTools"),
- accesskey: L10N.getStr("netmonitor.context.perfTools.accesskey"),
- visible: !!NetMonitorController.supportsPerfStats,
- click: () => this.store.dispatch(Actions.openStatistics(true))
- }));
-
- menu.popup(screenX, screenY, NetMonitorController._toolbox);
- return menu;
- },
-
- /**
- * Opens selected item in a new tab.
- */
- openRequestInTab() {
- let win = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
- win.openUILinkIn(this.selectedItem.url, "tab", { relatedToCurrent: true });
- },
-
- /**
- * Copy the request url from the currently selected item.
- */
- copyUrl() {
- clipboardHelper.copyString(this.selectedItem.url);
- },
-
- /**
- * Copy the request url query string parameters from the currently
- * selected item.
- */
- copyUrlParams() {
- let { url } = this.selectedItem;
- let params = getUrlQuery(url).split("&");
- let string = params.join(Services.appinfo.OS === "WINNT" ? "\r\n" : "\n");
- clipboardHelper.copyString(string);
- },
-
- /**
- * Copy the request form data parameters (or raw payload) from
- * the currently selected item.
- */
- copyPostData: Task.async(function* () {
- let selected = this.selectedItem;
-
- // Try to extract any form data parameters.
- let formDataSections = yield getFormDataSections(
- selected.requestHeaders,
- selected.requestHeadersFromUploadStream,
- selected.requestPostData,
- gNetwork.getString.bind(gNetwork));
-
- let params = [];
- formDataSections.forEach(section => {
- let paramsArray = parseQueryString(section);
- if (paramsArray) {
- params = [...params, ...paramsArray];
- }
- });
-
- let string = params
- .map(param => param.name + (param.value ? "=" + param.value : ""))
- .join(Services.appinfo.OS === "WINNT" ? "\r\n" : "\n");
-
- // Fall back to raw payload.
- if (!string) {
- let postData = selected.requestPostData.postData.text;
- string = yield gNetwork.getString(postData);
- if (Services.appinfo.OS !== "WINNT") {
- string = string.replace(/\r/g, "");
- }
- }
-
- clipboardHelper.copyString(string);
- }),
-
- /**
- * Copy a cURL command from the currently selected item.
- */
- copyAsCurl: Task.async(function* () {
- let selected = this.selectedItem;
-
- // Create a sanitized object for the Curl command generator.
- let data = {
- url: selected.url,
- method: selected.method,
- headers: [],
- httpVersion: selected.httpVersion,
- postDataText: null
- };
-
- // Fetch header values.
- for (let { name, value } of selected.requestHeaders.headers) {
- let text = yield gNetwork.getString(value);
- data.headers.push({ name: name, value: text });
- }
-
- // Fetch the request payload.
- if (selected.requestPostData) {
- let postData = selected.requestPostData.postData.text;
- data.postDataText = yield gNetwork.getString(postData);
- }
-
- clipboardHelper.copyString(Curl.generateCommand(data));
- }),
-
- /**
- * Copy the raw request headers from the currently selected item.
- */
- copyRequestHeaders() {
- let rawHeaders = this.selectedItem.requestHeaders.rawHeaders.trim();
- if (Services.appinfo.OS !== "WINNT") {
- rawHeaders = rawHeaders.replace(/\r/g, "");
- }
- clipboardHelper.copyString(rawHeaders);
- },
-
- /**
- * Copy the raw response headers from the currently selected item.
- */
- copyResponseHeaders() {
- let rawHeaders = this.selectedItem.responseHeaders.rawHeaders.trim();
- if (Services.appinfo.OS !== "WINNT") {
- rawHeaders = rawHeaders.replace(/\r/g, "");
- }
- clipboardHelper.copyString(rawHeaders);
- },
-
- /**
- * Copy image as data uri.
- */
- copyImageAsDataUri() {
- const { mimeType, text, encoding } = this.selectedItem.responseContent.content;
-
- gNetwork.getString(text).then(string => {
- let data = formDataURI(mimeType, encoding, string);
- clipboardHelper.copyString(data);
- });
- },
-
- /**
- * Copy response data as a string.
- */
- copyResponse() {
- const { text } = this.selectedItem.responseContent.content;
-
- gNetwork.getString(text).then(string => {
- clipboardHelper.copyString(string);
- });
- },
-
- /**
- * Copy HAR from the network panel content to the clipboard.
- */
- copyAllAsHar() {
- let options = this.getDefaultHarOptions();
- return HarExporter.copy(options);
- },
-
- /**
- * Save HAR from the network panel content to a file.
- */
- saveAllAsHar() {
- let options = this.getDefaultHarOptions();
- return HarExporter.save(options);
- },
-
- getDefaultHarOptions() {
- let form = NetMonitorController._target.form;
- let title = form.title || form.url;
-
- return {
- getString: gNetwork.getString.bind(gNetwork),
- items: this.items,
- title: title
- };
- }
-};
-
-module.exports = RequestListContextMenu;
deleted file mode 100644
--- a/devtools/client/netmonitor/requests-menu-view.js
+++ /dev/null
@@ -1,410 +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/. */
-
-/* globals window, dumpn, $, gNetwork, NetMonitorController */
-
-"use strict";
-
-const { Task } = require("devtools/shared/task");
-const { HTMLTooltip } = require("devtools/client/shared/widgets/tooltip/HTMLTooltip");
-const { setNamedTimeout } = require("devtools/client/shared/widgets/view-helpers");
-const { CurlUtils } = require("devtools/client/shared/curl");
-const { L10N } = require("./l10n");
-const { EVENTS } = require("./events");
-const { createElement, createFactory } = require("devtools/client/shared/vendor/react");
-const ReactDOM = require("devtools/client/shared/vendor/react-dom");
-const { Provider } = require("devtools/client/shared/vendor/react-redux");
-const RequestList = createFactory(require("./components/request-list"));
-const RequestListContextMenu = require("./request-list-context-menu");
-const Actions = require("./actions/index");
-const { Prefs } = require("./prefs");
-
-const {
- fetchHeaders,
- formDataURI,
- getFormDataSections,
-} = require("./request-utils");
-
-const {
- getActiveFilters,
- getDisplayedRequests,
- getRequestById,
- getSelectedRequest,
- getSortedRequests,
-} = require("./selectors/index");
-
-// ms
-const RESIZE_REFRESH_RATE = 50;
-
-// A smart store watcher to notify store changes as necessary
-function storeWatcher(initialValue, reduceValue, onChange) {
- let currentValue = initialValue;
-
- return () => {
- const oldValue = currentValue;
- const newValue = reduceValue(currentValue);
- if (newValue !== oldValue) {
- currentValue = newValue;
- onChange(newValue, oldValue);
- }
- };
-}
-
-/**
- * Functions handling the requests menu (containing details about each request,
- * like status, method, file, domain, as well as a waterfall representing
- * timing information).
- */
-function RequestsMenuView() {
- dumpn("RequestsMenuView was instantiated");
-}
-
-RequestsMenuView.prototype = {
- /**
- * Initialization function, called when the network monitor is started.
- */
- initialize: function (store) {
- dumpn("Initializing the RequestsMenuView");
-
- this.store = store;
-
- this.contextMenu = new RequestListContextMenu();
- this.contextMenu.initialize(store);
-
- Prefs.filters.forEach(type => store.dispatch(Actions.toggleRequestFilterType(type)));
-
- // Watch selection changes
- this.store.subscribe(storeWatcher(
- null,
- () => getSelectedRequest(this.store.getState()),
- (newSelected, oldSelected) => this.onSelectionUpdate(newSelected, oldSelected)
- ));
-
- // Watch the network details panel toggle and resize the waterfall column on change
- this.store.subscribe(storeWatcher(
- false,
- () => this.store.getState().ui.networkDetailsOpen,
- () => this.onResize()
- ));
-
- // Watch the requestHeaders, requestHeadersFromUploadStream and requestPostData
- // in order to update formDataSections for composing form data
- this.store.subscribe(storeWatcher(
- false,
- (currentRequest) => {
- const request = getSelectedRequest(this.store.getState());
- if (!request) {
- return {};
- }
-
- const isChanged = request.requestHeaders !== currentRequest.requestHeaders ||
- request.requestHeadersFromUploadStream !==
- currentRequest.requestHeadersFromUploadStream ||
- request.requestPostData !== currentRequest.requestPostData;
-
- if (isChanged) {
- return {
- id: request.id,
- requestHeaders: request.requestHeaders,
- requestHeadersFromUploadStream: request.requestHeadersFromUploadStream,
- requestPostData: request.requestPostData,
- };
- }
-
- return currentRequest;
- },
- (newRequest) => {
- const {
- id,
- requestHeaders,
- requestHeadersFromUploadStream,
- requestPostData,
- } = newRequest;
-
- if (requestHeaders && requestHeadersFromUploadStream && requestPostData) {
- getFormDataSections(
- requestHeaders,
- requestHeadersFromUploadStream,
- requestPostData,
- gNetwork.getString.bind(gNetwork),
- ).then((formDataSections) => {
- this.store.dispatch(Actions.updateRequest(
- id,
- { formDataSections },
- true,
- ));
- });
- }
- },
- ));
-
- this._summary = $("#requests-menu-network-summary-button");
- this._summary.setAttribute("label", L10N.getStr("networkMenu.empty"));
-
- this.onResize = this.onResize.bind(this);
- this._splitter = $("#network-inspector-view-splitter");
- this._splitter.addEventListener("mouseup", this.onResize);
- window.addEventListener("resize", this.onResize);
-
- this.tooltip = new HTMLTooltip(NetMonitorController._toolbox.doc, { type: "arrow" });
-
- this.mountPoint = $("#network-table");
- ReactDOM.render(createElement(Provider,
- { store: this.store },
- RequestList()
- ), this.mountPoint);
- },
-
- /**
- * Destruction function, called when the network monitor is closed.
- */
- destroy() {
- dumpn("Destroying the RequestsMenuView");
-
- Prefs.filters = getActiveFilters(this.store.getState());
-
- this._splitter.removeEventListener("mouseup", this.onResize);
- window.removeEventListener("resize", this.onResize);
-
- this.tooltip.destroy();
-
- ReactDOM.unmountComponentAtNode(this.mountPoint);
- },
-
- /**
- * Resets this container (removes all the networking information).
- */
- reset() {
- this.store.dispatch(Actions.batchReset());
- this.store.dispatch(Actions.clearRequests());
- },
-
- /**
- * Removes all network requests and closes the network details panel if open.
- */
- clear() {
- this.store.dispatch(Actions.clearRequests());
- },
-
- addRequest(id, data) {
- let { method, url, isXHR, cause, startedDateTime, fromCache,
- fromServiceWorker } = data;
-
- // Convert the received date/time string to a unix timestamp.
- let startedMillis = Date.parse(startedDateTime);
-
- const action = Actions.addRequest(
- id,
- {
- startedMillis,
- method,
- url,
- isXHR,
- cause,
- fromCache,
- fromServiceWorker,
- },
- true
- );
-
- this.store.dispatch(action).then(() => window.emit(EVENTS.REQUEST_ADDED, action.id));
- },
-
- updateRequest: Task.async(function* (id, data) {
- const action = Actions.updateRequest(id, data, true);
- yield this.store.dispatch(action);
- let {
- responseContent,
- responseCookies,
- responseHeaders,
- requestCookies,
- requestHeaders,
- requestPostData,
- } = action.data;
- let request = getRequestById(this.store.getState(), action.id);
-
- if (requestHeaders && requestHeaders.headers && requestHeaders.headers.length) {
- let headers = yield fetchHeaders(
- requestHeaders, gNetwork.getString.bind(gNetwork));
- if (headers) {
- yield this.store.dispatch(Actions.updateRequest(
- action.id,
- { requestHeaders: headers },
- true,
- ));
- }
- }
-
- if (responseHeaders && responseHeaders.headers && responseHeaders.headers.length) {
- let headers = yield fetchHeaders(
- responseHeaders, gNetwork.getString.bind(gNetwork));
- if (headers) {
- yield this.store.dispatch(Actions.updateRequest(
- action.id,
- { responseHeaders: headers },
- true,
- ));
- }
- }
-
- if (request && responseContent && responseContent.content) {
- let { mimeType } = request;
- let { text, encoding } = responseContent.content;
- let response = yield gNetwork.getString(text);
- let payload = {};
-
- if (mimeType.includes("image/")) {
- payload.responseContentDataUri = formDataURI(mimeType, encoding, response);
- }
-
- responseContent.content.text = response;
- payload.responseContent = responseContent;
-
- yield this.store.dispatch(Actions.updateRequest(action.id, payload, true));
-
- if (mimeType.includes("image/")) {
- window.emit(EVENTS.RESPONSE_IMAGE_THUMBNAIL_DISPLAYED);
- }
- }
-
- // 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 = yield gNetwork.getString(text);
- const headers = CurlUtils.getHeadersFromMultipartText(postData);
- 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 };
-
- yield this.store.dispatch(Actions.updateRequest(action.id, payload, true));
- }
-
- // 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
- let cookies = requestCookies.cookies ?
- requestCookies.cookies : requestCookies;
- // make sure cookies is iterable
- if (typeof cookies[Symbol.iterator] === "function") {
- for (let cookie of cookies) {
- reqCookies.push(Object.assign({}, cookie, {
- value: yield gNetwork.getString(cookie.value),
- }));
- }
- if (reqCookies.length) {
- yield this.store.dispatch(Actions.updateRequest(
- action.id,
- { requestCookies: reqCookies },
- 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: yield gNetwork.getString(cookie.value),
- }));
- }
- if (resCookies.length) {
- yield this.store.dispatch(Actions.updateRequest(
- action.id,
- { responseCookies: resCookies },
- true));
- }
- }
- }
- }),
-
- /**
- * Disable batched updates. Used by tests.
- */
- set lazyUpdate(value) {
- this.store.dispatch(Actions.batchEnable(value));
- },
-
- get items() {
- return getSortedRequests(this.store.getState());
- },
-
- get visibleItems() {
- return getDisplayedRequests(this.store.getState());
- },
-
- get itemCount() {
- return this.store.getState().requests.requests.size;
- },
-
- getItemAtIndex(index) {
- return getSortedRequests(this.store.getState()).get(index);
- },
-
- get selectedIndex() {
- const state = this.store.getState();
- if (!state.requests.selectedId) {
- return -1;
- }
- return getSortedRequests(state).findIndex(r => r.id === state.requests.selectedId);
- },
-
- set selectedIndex(index) {
- const requests = getSortedRequests(this.store.getState());
- let itemId = null;
- if (index >= 0 && index < requests.size) {
- itemId = requests.get(index).id;
- }
- this.store.dispatch(Actions.selectRequest(itemId));
- },
-
- get selectedItem() {
- return getSelectedRequest(this.store.getState());
- },
-
- set selectedItem(item) {
- this.store.dispatch(Actions.selectRequest(item ? item.id : null));
- },
-
- /**
- * Updates the network details panel state when something about the selection changes
- */
- onSelectionUpdate(newSelected, oldSelected) {
- if (newSelected) {
- // Another item just got selected
- this.store.dispatch(Actions.openNetworkDetails(true));
- } else {
- // Selection just got empty
- this.store.dispatch(Actions.openNetworkDetails(false));
- }
- },
-
- /**
- * The resize listener for this container's window.
- */
- onResize() {
- // Allow requests to settle down first.
- setNamedTimeout("resize-events", RESIZE_REFRESH_RATE, () => {
- const waterfallHeaderEl = $("#requests-menu-waterfall-header-box");
- if (waterfallHeaderEl) {
- const { width } = waterfallHeaderEl.getBoundingClientRect();
- this.store.dispatch(Actions.resizeWaterfall(width));
- }
- });
- }
-};
-
-exports.RequestsMenuView = RequestsMenuView;
--- a/devtools/client/netmonitor/test/browser.ini
+++ b/devtools/client/netmonitor/test/browser.ini
@@ -143,24 +143,21 @@ skip-if = true # bug 1309183, it should
[browser_net_security-state.js]
[browser_net_security-tab-deselect.js]
[browser_net_security-tab-visibility.js]
[browser_net_security-warnings.js]
[browser_net_send-beacon.js]
[browser_net_send-beacon-other-tab.js]
[browser_net_simple-init.js]
[browser_net_simple-request-data.js]
-skip-if = true # Bug 1258809
[browser_net_simple-request-details.js]
skip-if = true # Bug 1258809
[browser_net_simple-request.js]
[browser_net_sort-01.js]
-skip-if = true # Redundant for React/Redux version
[browser_net_sort-02.js]
-[browser_net_sort-03.js]
[browser_net_statistics-01.js]
[browser_net_statistics-02.js]
[browser_net_status-codes.js]
[browser_net_streaming-response.js]
[browser_net_throttle.js]
[browser_net_timeline_ticks.js]
skip-if = true # TODO: fix the test
[browser_net_timing-division.js]
--- a/devtools/client/netmonitor/test/browser_net_accessibility-01.js
+++ b/devtools/client/netmonitor/test/browser_net_accessibility-01.js
@@ -9,28 +9,27 @@
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(CUSTOM_GET_URL);
info("Starting test... ");
// It seems that this test may be slow on Ubuntu builds running on ec2.
requestLongerTimeout(2);
- let { document, NetMonitorView, gStore, windowRequire } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
- RequestsMenu.lazyUpdate = false;
-
- let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ gStore.dispatch(Actions.batchEnable(false));
let count = 0;
function check(selectedIndex, panelVisibility) {
info("Performing check " + (count++) + ".");
- is(RequestsMenu.selectedIndex, selectedIndex,
+ let requestItems = Array.from(document.querySelectorAll(".request-list-item"));
+ is(requestItems.findIndex((item) => item.matches(".selected")), selectedIndex,
"The selected item in the requests menu was incorrect.");
is(!!document.querySelector(".network-details-panel"), panelVisibility,
"The network details panel should render correctly.");
}
let wait = waitForNetworkEvents(monitor, 2);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests(2);
--- a/devtools/client/netmonitor/test/browser_net_accessibility-02.js
+++ b/devtools/client/netmonitor/test/browser_net_accessibility-02.js
@@ -9,26 +9,27 @@
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(CUSTOM_GET_URL);
info("Starting test... ");
// It seems that this test may be slow on Ubuntu builds running on ec2.
requestLongerTimeout(2);
- let { window, document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { window, document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let count = 0;
function check(selectedIndex, panelVisibility) {
info("Performing check " + (count++) + ".");
- is(RequestsMenu.selectedIndex, selectedIndex,
+ let requestItems = Array.from(document.querySelectorAll(".request-list-item"));
+ is(requestItems.findIndex((item) => item.matches(".selected")), selectedIndex,
"The selected item in the requests menu was incorrect.");
is(!!document.querySelector(".network-details-panel"), panelVisibility,
"The network details panel should render correctly.");
}
let wait = waitForNetworkEvents(monitor, 2);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests(2);
--- a/devtools/client/netmonitor/test/browser_net_api-calls.js
+++ b/devtools/client/netmonitor/test/browser_net_api-calls.js
@@ -7,33 +7,43 @@
* Tests whether API call URLs (without a filename) are correctly displayed
* (including Unicode)
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(API_CALLS_URL);
info("Starting test... ");
- let { NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
const REQUEST_URIS = [
"http://example.com/api/fileName.xml",
"http://example.com/api/file%E2%98%A2.xml",
"http://example.com/api/ascii/get/",
"http://example.com/api/unicode/%E2%98%A2/",
"http://example.com/api/search/?q=search%E2%98%A2"
];
let wait = waitForNetworkEvents(monitor, 5);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
REQUEST_URIS.forEach(function (uri, index) {
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(index), "GET", uri);
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(index),
+ "GET",
+ uri
+ );
});
yield teardown(monitor);
});
--- a/devtools/client/netmonitor/test/browser_net_autoscroll.js
+++ b/devtools/client/netmonitor/test/browser_net_autoscroll.js
@@ -5,22 +5,23 @@
/**
* Bug 863102 - Automatically scroll down upon new network requests.
*/
add_task(function* () {
requestLongerTimeout(2);
let { monitor } = yield initNetMonitor(INFINITE_GET_URL);
- let { $ } = monitor.panelWin;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
// Wait until the first request makes the empty notice disappear
yield waitForRequestListToAppear();
- let requestsContainer = $(".requests-menu-contents");
+ let requestsContainer = document.querySelector(".requests-menu-contents");
ok(requestsContainer, "Container element exists as expected.");
// (1) Check that the scroll position is maintained at the bottom
// when the requests overflow the vertical size of the container.
yield waitForRequestsToOverflowContainer();
yield waitForScroll();
ok(true, "Scrolled to bottom on overflow.");
@@ -41,34 +42,36 @@ add_task(function* () {
requestsContainer.scrollTop = requestsContainer.scrollHeight;
ok(scrolledToBottom(requestsContainer), "Set scroll position to bottom.");
yield waitForNetworkEvents(monitor, 8);
yield waitForScroll();
ok(true, "Still scrolled to bottom.");
// (4) Now select an item in the list and check that additional requests
// do not change the scroll position.
- monitor.panelWin.NetMonitorView.RequestsMenu.selectedIndex = 0;
+ gStore.dispatch(Actions.selectRequestByIndex(0));
yield waitForNetworkEvents(monitor, 8);
yield waitSomeTime();
is(requestsContainer.scrollTop, 0, "Did not scroll.");
// Done: clean up.
return teardown(monitor);
function waitForRequestListToAppear() {
info("Waiting until the empty notice disappears and is replaced with the list");
- return waitUntil(() => !!$(".requests-menu-contents"));
+ return waitUntil(() => !!document.querySelector(".requests-menu-contents"));
}
function* waitForRequestsToOverflowContainer() {
info("Waiting for enough requests to overflow the container");
while (true) {
info("Waiting for one network request");
yield waitForNetworkEvents(monitor, 1);
+ console.log(requestsContainer.scrollHeight);
+ console.log(requestsContainer.clientHeight)
if (requestsContainer.scrollHeight > requestsContainer.clientHeight) {
info("The list is long enough, returning");
return;
}
}
}
function scrolledToBottom(element) {
--- a/devtools/client/netmonitor/test/browser_net_brotli.js
+++ b/devtools/client/netmonitor/test/browser_net_brotli.js
@@ -11,42 +11,50 @@ const BROTLI_REQUESTS = 1;
*/
add_task(function* () {
let { L10N } = require("devtools/client/netmonitor/l10n");
let { tab, monitor } = yield initNetMonitor(BROTLI_URL);
info("Starting test... ");
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, BROTLI_REQUESTS);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(0),
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(0),
"GET", HTTPS_CONTENT_TYPE_SJS + "?fmt=br", {
status: 200,
statusText: "Connected",
type: "plain",
fullMimeType: "text/plain",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 10),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 64),
time: true
});
wait = waitForDOM(document, "#response-panel .editor-mount iframe");
- EventUtils.sendMouseEvent({ type: "mousedown" },
+ EventUtils.sendMouseEvent({ type: "click" },
document.querySelector(".network-details-panel-toggle"));
- document.querySelector("#response-tab").click();
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#response-tab"));
let [editorFrame] = yield wait;
yield once(editorFrame, "DOMContentLoaded");
yield waitForDOM(editorFrame.contentDocument, ".CodeMirror-code");
yield testResponse("br");
yield teardown(monitor);
--- a/devtools/client/netmonitor/test/browser_net_cached-status.js
+++ b/devtools/client/netmonitor/test/browser_net_cached-status.js
@@ -6,20 +6,24 @@
/**
* Tests if cached requests have the correct status code
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(STATUS_CODES_URL, null, true);
info("Starting test... ");
- let { NetMonitorView } = monitor.panelWin;
- let { RequestsMenu, NetworkDetails } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
const REQUEST_DATA = [
{
method: "GET",
uri: STATUS_CODES_SJS + "?sts=ok&cached",
details: {
status: 200,
statusText: "OK",
@@ -84,21 +88,25 @@ add_task(function* () {
info("Performing requests #1...");
yield performRequestsAndWait();
info("Performing requests #2...");
yield performRequestsAndWait();
let index = 0;
for (let request of REQUEST_DATA) {
- let item = RequestsMenu.getItemAtIndex(index);
-
info("Verifying request #" + index);
- yield verifyRequestItemTarget(RequestsMenu, item,
- request.method, request.uri, request.details);
+ yield verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(index),
+ request.method,
+ request.uri,
+ request.details
+ );
index++;
}
yield teardown(monitor);
function* performRequestsAndWait() {
let wait = waitForNetworkEvents(monitor, 3);
--- a/devtools/client/netmonitor/test/browser_net_cause.js
+++ b/devtools/client/netmonitor/test/browser_net_cause.js
@@ -83,33 +83,43 @@ add_task(function* () {
// the initNetMonitor function clears the network request list after the
// page is loaded. That's why we first load a bogus page from SIMPLE_URL,
// and only then load the real thing from CAUSE_URL - we want to catch
// all the requests the page is making, not only the XHRs.
// We can't use about:blank here, because initNetMonitor checks that the
// page has actually made at least one request.
let { tab, monitor } = yield initNetMonitor(SIMPLE_URL);
- let { $, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
- RequestsMenu.lazyUpdate = false;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
+
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, EXPECTED_REQUESTS.length);
tab.linkedBrowser.loadURI(CAUSE_URL);
yield wait;
- is(RequestsMenu.itemCount, EXPECTED_REQUESTS.length,
+ is(gStore.getState().requests.requests.size, EXPECTED_REQUESTS.length,
"All the page events should be recorded.");
EXPECTED_REQUESTS.forEach((spec, i) => {
let { method, url, causeType, causeUri, stack } = spec;
- let requestItem = RequestsMenu.getItemAtIndex(i);
- verifyRequestItemTarget(RequestsMenu, requestItem,
- method, url, { cause: { type: causeType, loadingDocumentUri: causeUri } }
+ let requestItem = getSortedRequests(gStore.getState()).get(i);
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ requestItem,
+ method,
+ url,
+ { cause: { type: causeType, loadingDocumentUri: causeUri } }
);
let { stacktrace } = requestItem.cause;
let stackLen = stacktrace ? stacktrace.length : 0;
if (stack) {
ok(stacktrace, `Request #${i} has a stacktrace`);
ok(stackLen > 0,
@@ -129,17 +139,18 @@ add_task(function* () {
});
}
} else {
is(stackLen, 0, `Request #${i} (${causeType}) has an empty stacktrace`);
}
});
// Sort the requests by cause and check the order
- EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-cause-button"));
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#requests-menu-cause-button"));
let expectedOrder = EXPECTED_REQUESTS.map(r => r.causeType).sort();
expectedOrder.forEach((expectedCause, i) => {
- const cause = RequestsMenu.getItemAtIndex(i).cause.type;
+ const cause = getSortedRequests(gStore.getState()).get(i).cause.type;
is(cause, expectedCause, `The request #${i} has the expected cause after sorting`);
});
yield teardown(monitor);
});
--- a/devtools/client/netmonitor/test/browser_net_cause_redirect.js
+++ b/devtools/client/netmonitor/test/browser_net_cause_redirect.js
@@ -14,25 +14,28 @@ add_task(function* () {
{ status: 302, hasStack: true },
// Serves HTTPS, sets the Strict-Transport-Security header, no stack
{ status: 200, hasStack: false },
// Second request to HTTP redirects to HTTPS internally
{ status: 200, hasStack: true },
];
let { tab, monitor } = yield initNetMonitor(CUSTOM_GET_URL);
- let { RequestsMenu } = monitor.panelWin.NetMonitorView;
- RequestsMenu.lazyUpdate = false;
+ let { gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let { getSortedRequests } = windowRequire("devtools/client/netmonitor/selectors/index");
+
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, EXPECTED_REQUESTS.length);
yield performRequests(2, HSTS_SJS);
yield wait;
EXPECTED_REQUESTS.forEach(({status, hasStack}, i) => {
- let item = RequestsMenu.getItemAtIndex(i);
+ let item = getSortedRequests(gStore.getState()).get(i);
is(item.status, status, `Request #${i} has the expected status`);
let { stacktrace } = item.cause;
let stackLen = stacktrace ? stacktrace.length : 0;
if (hasStack) {
ok(stacktrace, `Request #${i} has a stacktrace`);
--- a/devtools/client/netmonitor/test/browser_net_clear.js
+++ b/devtools/client/netmonitor/test/browser_net_clear.js
@@ -6,72 +6,74 @@
/**
* Tests if the clear button empties the request menu.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(SIMPLE_URL);
info("Starting test... ");
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let { EVENTS } = windowRequire("devtools/client/netmonitor/events");
+ let detailsPane = document.querySelector("#details-pane");
let detailsPanelToggleButton = document.querySelector(".network-details-panel-toggle");
let clearButton = document.querySelector("#requests-menu-clear-button");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
// Make sure we start in a sane state
- assertNoRequestState(RequestsMenu, detailsPanelToggleButton);
+ assertNoRequestState();
// Load one request and assert it shows up in the list
- let networkEvent = monitor.panelWin.once(monitor.panelWin.EVENTS.NETWORK_EVENT);
+ let networkEvent = monitor.panelWin.once(EVENTS.NETWORK_EVENT);
tab.linkedBrowser.reload();
yield networkEvent;
assertSingleRequestState();
// Click clear and make sure the requests are gone
EventUtils.sendMouseEvent({ type: "click" }, clearButton);
assertNoRequestState();
// Load a second request and make sure they still show up
- networkEvent = monitor.panelWin.once(monitor.panelWin.EVENTS.NETWORK_EVENT);
+ networkEvent = monitor.panelWin.once(EVENTS.NETWORK_EVENT);
tab.linkedBrowser.reload();
yield networkEvent;
assertSingleRequestState();
// Make sure we can now open the network details panel
- EventUtils.sendMouseEvent({ type: "mousedown" }, detailsPanelToggleButton);
+ EventUtils.sendMouseEvent({ type: "click" }, detailsPanelToggleButton);
ok(document.querySelector(".network-details-panel") &&
!detailsPanelToggleButton.classList.contains("pane-collapsed"),
"The details pane should be visible after clicking the toggle button.");
// Click clear and make sure the details pane closes
EventUtils.sendMouseEvent({ type: "click" }, clearButton);
+
assertNoRequestState();
- ok(!document.querySelector(".network-details-panel") &&
- detailsPanelToggleButton.classList.contains("pane-collapsed"),
+ ok(!document.querySelector(".network-details-panel"),
"The details pane should not be visible clicking 'clear'.");
return teardown(monitor);
/**
* Asserts the state of the network monitor when one request has loaded
*/
function assertSingleRequestState() {
- is(RequestsMenu.itemCount, 1,
+ is(gStore.getState().requests.requests.size, 1,
"The request menu should have one item at this point.");
is(detailsPanelToggleButton.hasAttribute("disabled"), false,
"The pane toggle button should be enabled after a request is made.");
}
/**
* Asserts the state of the network monitor when no requests have loaded
*/
function assertNoRequestState() {
- is(RequestsMenu.itemCount, 0,
+ is(gStore.getState().requests.requests.size, 0,
"The request menu should be empty at this point.");
is(detailsPanelToggleButton.hasAttribute("disabled"), true,
"The pane toggle button should be disabled when the request menu is cleared.");
}
});
--- a/devtools/client/netmonitor/test/browser_net_complex-params.js
+++ b/devtools/client/netmonitor/test/browser_net_complex-params.js
@@ -4,69 +4,68 @@
"use strict";
/**
* Tests whether complex request params and payload sent via POST are
* displayed correctly.
*/
add_task(function* () {
- let { L10N } = require("devtools/client/netmonitor/l10n");
-
let { tab, monitor } = yield initNetMonitor(PARAMS_URL);
info("Starting test... ");
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let { L10N } = windowRequire("devtools/client/netmonitor/l10n");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, 1, 6);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
wait = waitForDOM(document, "#params-panel .tree-section", 2);
- EventUtils.sendMouseEvent({ type: "mousedown" },
- document.querySelector(".network-details-panel-toggle"));
- document.querySelector("#params-tab").click();
+ gStore.dispatch(Actions.selectRequestByIndex(0));
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#params-tab"));
yield wait;
testParamsTab1("a", '""', '{ "foo": "bar" }', '""');
wait = waitForDOM(document, "#params-panel .tree-section", 2);
- RequestsMenu.selectedIndex = 1;
+ gStore.dispatch(Actions.selectRequestByIndex(1));
yield wait;
testParamsTab1("a", '"b"', '{ "foo": "bar" }', '""');
wait = waitForDOM(document, "#params-panel .tree-section", 2);
- RequestsMenu.selectedIndex = 2;
+ gStore.dispatch(Actions.selectRequestByIndex(2));
yield wait;
testParamsTab1("a", '"b"', "foo", '"bar"');
wait = waitForDOM(document, "#params-panel tr:not(.tree-section).treeRow", 2);
- RequestsMenu.selectedIndex = 3;
+ gStore.dispatch(Actions.selectRequestByIndex(3));
yield wait;
testParamsTab2("a", '""', '{ "foo": "bar" }', "js");
wait = waitForDOM(document, "#params-panel tr:not(.tree-section).treeRow", 2);
- RequestsMenu.selectedIndex = 4;
+ gStore.dispatch(Actions.selectRequestByIndex(4));
yield wait;
testParamsTab2("a", '"b"', '{ "foo": "bar" }', "js");
// Wait for all tree sections and editor updated by react
let waitSections = waitForDOM(document, "#params-panel .tree-section", 2);
let waitEditor = waitForDOM(document, "#params-panel .editor-mount iframe");
- RequestsMenu.selectedIndex = 5;
+ gStore.dispatch(Actions.selectRequestByIndex(5));
let [, editorFrames] = yield Promise.all([waitSections, waitEditor]);
yield once(editorFrames[0], "DOMContentLoaded");
yield waitForDOM(editorFrames[0].contentDocument, ".CodeMirror-code");
testParamsTab2("a", '"b"', "?foo=bar", "text");
- RequestsMenu.selectedIndex = 6;
+ gStore.dispatch(Actions.selectRequestByIndex(6));
testParamsTab3();
yield teardown(monitor);
function testParamsTab1(queryStringParamName, queryStringParamValue,
formDataParamName, formDataParamValue) {
let tabpanel = document.querySelector("#params-panel");
--- a/devtools/client/netmonitor/test/browser_net_content-type.js
+++ b/devtools/client/netmonitor/test/browser_net_content-type.js
@@ -8,84 +8,120 @@
*/
add_task(function* () {
let { L10N } = require("devtools/client/netmonitor/l10n");
let { tab, monitor } = yield initNetMonitor(CONTENT_TYPE_WITHOUT_CACHE_URL);
info("Starting test... ");
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, CONTENT_TYPE_WITHOUT_CACHE_REQUESTS);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(0),
- "GET", CONTENT_TYPE_SJS + "?fmt=xml", {
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(0),
+ "GET",
+ CONTENT_TYPE_SJS + "?fmt=xml",
+ {
status: 200,
statusText: "OK",
type: "xml",
fullMimeType: "text/xml; charset=utf-8",
size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 42),
time: true
});
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(1),
- "GET", CONTENT_TYPE_SJS + "?fmt=css", {
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(1),
+ "GET",
+ CONTENT_TYPE_SJS + "?fmt=css",
+ {
status: 200,
statusText: "OK",
type: "css",
fullMimeType: "text/css; charset=utf-8",
size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 34),
time: true
});
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(2),
- "GET", CONTENT_TYPE_SJS + "?fmt=js", {
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(2),
+ "GET",
+ CONTENT_TYPE_SJS + "?fmt=js",
+ {
status: 200,
statusText: "OK",
type: "js",
fullMimeType: "application/javascript; charset=utf-8",
size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 34),
time: true
});
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(3),
- "GET", CONTENT_TYPE_SJS + "?fmt=json", {
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(3),
+ "GET",
+ CONTENT_TYPE_SJS + "?fmt=json",
+ {
status: 200,
statusText: "OK",
type: "json",
fullMimeType: "application/json; charset=utf-8",
size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 29),
time: true
});
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(4),
- "GET", CONTENT_TYPE_SJS + "?fmt=bogus", {
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(4),
+ "GET",
+ CONTENT_TYPE_SJS + "?fmt=bogus", {
status: 404,
statusText: "Not Found",
type: "html",
fullMimeType: "text/html; charset=utf-8",
size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 24),
time: true
});
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(5),
- "GET", TEST_IMAGE, {
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(5),
+ "GET",
+ TEST_IMAGE, {
fuzzyUrl: true,
status: 200,
statusText: "OK",
type: "png",
fullMimeType: "image/png",
size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 580),
time: true
});
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(6),
- "GET", CONTENT_TYPE_SJS + "?fmt=gzip", {
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(6),
+ "GET",
+ CONTENT_TYPE_SJS + "?fmt=gzip", {
status: 200,
statusText: "OK",
type: "plain",
fullMimeType: "text/plain",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 73),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 10.73),
time: true
});
@@ -222,34 +258,34 @@ add_task(function* () {
}
}
}
function* selectIndexAndWaitForEditor(index) {
let editor = document.querySelector("#response-panel .editor-mount iframe");
if (!editor) {
let waitDOM = waitForDOM(document, "#response-panel .editor-mount iframe");
- RequestsMenu.selectedIndex = index;
+ gStore.dispatch(Actions.selectRequestByIndex(index));
document.querySelector("#response-tab").click();
[editor] = yield waitDOM;
yield once(editor, "DOMContentLoaded");
} else {
- RequestsMenu.selectedIndex = index;
+ gStore.dispatch(Actions.selectRequestByIndex(index));
}
yield waitForDOM(editor.contentDocument, ".CodeMirror-code");
}
function* selectIndexAndWaitForJSONView(index) {
let tabpanel = document.querySelector("#response-panel");
let waitDOM = waitForDOM(tabpanel, ".treeTable");
- RequestsMenu.selectedIndex = index;
+ gStore.dispatch(Actions.selectRequestByIndex(index));
yield waitDOM;
}
function* selectIndexAndWaitForImageView(index) {
let tabpanel = document.querySelector("#response-panel");
let waitDOM = waitForDOM(tabpanel, ".response-image");
- RequestsMenu.selectedIndex = index;
+ gStore.dispatch(Actions.selectRequestByIndex(index));
let [imageNode] = yield waitDOM;
yield once(imageNode, "load");
}
});
--- a/devtools/client/netmonitor/test/browser_net_copy_as_curl.js
+++ b/devtools/client/netmonitor/test/browser_net_copy_as_curl.js
@@ -36,31 +36,35 @@ add_task(function* () {
header("X-Custom-Header-2: 8.8.8.8"),
header("X-Custom-Header-3: Mon, 3 Mar 2014 11:11:11 GMT"),
header("Referer: " + CURL_URL),
header("Connection: keep-alive"),
header("Pragma: no-cache"),
header("Cache-Control: no-cache")
];
- let { NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
- RequestsMenu.lazyUpdate = false;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
let wait = waitForNetworkEvents(monitor, 1);
yield ContentTask.spawn(tab.linkedBrowser, SIMPLE_SJS, function* (url) {
content.wrappedJSObject.performRequest(url);
});
yield wait;
- let requestItem = RequestsMenu.getItemAtIndex(0);
- RequestsMenu.selectedItem = requestItem;
+ EventUtils.sendMouseEvent({ type: "mousedown" },
+ document.querySelectorAll(".request-list-item")[0]);
+ EventUtils.sendMouseEvent({ type: "contextmenu" },
+ document.querySelectorAll(".request-list-item")[0]);
yield waitForClipboardPromise(function setup() {
- RequestsMenu.contextMenu.copyAsCurl();
+ // Context menu is appending in XUL document, we must select it from
+ // _toolbox.doc
+ monitor._toolbox.doc
+ .querySelector("#request-menu-context-copy-as-curl").click();
}, function validate(result) {
if (typeof result !== "string") {
return false;
}
// Different setups may produce the same command, but with the
// parameters in a different order in the commandline (which is fine).
// Here we confirm that the commands are the same even in that case.
--- a/devtools/client/netmonitor/test/browser_net_copy_headers.js
+++ b/devtools/client/netmonitor/test/browser_net_copy_headers.js
@@ -6,45 +6,50 @@
/**
* Tests if copying a request's request/response headers works.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(SIMPLE_URL);
info("Starting test... ");
- let { NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
-
- RequestsMenu.lazyUpdate = false;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let { getSortedRequests } = windowRequire("devtools/client/netmonitor/selectors/index");
let wait = waitForNetworkEvents(monitor, 1);
tab.linkedBrowser.reload();
yield wait;
- let requestItem = RequestsMenu.getItemAtIndex(0);
- RequestsMenu.selectedItem = requestItem;
+ EventUtils.sendMouseEvent({ type: "mousedown" },
+ document.querySelectorAll(".request-list-item")[0]);
+ let requestItem = getSortedRequests(gStore.getState()).get(0);
let { method, httpVersion, status, statusText } = requestItem;
+ EventUtils.sendMouseEvent({ type: "contextmenu" },
+ document.querySelectorAll(".request-list-item")[0]);
+
const EXPECTED_REQUEST_HEADERS = [
`${method} ${SIMPLE_URL} ${httpVersion}`,
"Host: example.com",
"User-Agent: " + navigator.userAgent + "",
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language: " + navigator.languages.join(",") + ";q=0.5",
"Accept-Encoding: gzip, deflate",
"Connection: keep-alive",
"Upgrade-Insecure-Requests: 1",
"Pragma: no-cache",
"Cache-Control: no-cache"
].join("\n");
yield waitForClipboardPromise(function setup() {
- RequestsMenu.contextMenu.copyRequestHeaders();
+ // Context menu is appending in XUL document, we must select it from
+ // _toolbox.doc
+ monitor._toolbox.doc
+ .querySelector("#request-menu-context-copy-request-headers").click();
}, function validate(result) {
// Sometimes, a "Cookie" header is left over from other tests. Remove it:
result = String(result).replace(/Cookie: [^\n]+\n/, "");
return result === EXPECTED_REQUEST_HEADERS;
});
info("Clipboard contains the currently selected item's request headers.");
const EXPECTED_RESPONSE_HEADERS = [
@@ -52,18 +57,24 @@ add_task(function* () {
"Last-Modified: Sun, 3 May 2015 11:11:11 GMT",
"Content-Type: text/html",
"Content-Length: 465",
"Connection: close",
"Server: httpd.js",
"Date: Sun, 3 May 2015 11:11:11 GMT"
].join("\n");
+ EventUtils.sendMouseEvent({ type: "contextmenu" },
+ document.querySelectorAll(".request-list-item")[0]);
+
yield waitForClipboardPromise(function setup() {
- RequestsMenu.contextMenu.copyResponseHeaders();
+ // Context menu is appending in XUL document, we must select it from
+ // _toolbox.doc
+ monitor._toolbox.doc
+ .querySelector("#response-menu-context-copy-response-headers").click();
}, function validate(result) {
// Fake the "Last-Modified" and "Date" headers because they will vary:
result = String(result)
.replace(/Last-Modified: [^\n]+ GMT/, "Last-Modified: Sun, 3 May 2015 11:11:11 GMT")
.replace(/Date: [^\n]+ GMT/, "Date: Sun, 3 May 2015 11:11:11 GMT");
return result === EXPECTED_RESPONSE_HEADERS;
});
info("Clipboard contains the currently selected item's response headers.");
--- a/devtools/client/netmonitor/test/browser_net_copy_image_as_data_uri.js
+++ b/devtools/client/netmonitor/test/browser_net_copy_image_as_data_uri.js
@@ -6,30 +6,32 @@
/**
* Tests if copying an image as data uri works.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(CONTENT_TYPE_WITHOUT_CACHE_URL);
info("Starting test... ");
- let { NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
-
- RequestsMenu.lazyUpdate = false;
+ let { document, gStore, windowRequire } = monitor.panelWin;
let wait = waitForNetworkEvents(monitor, CONTENT_TYPE_WITHOUT_CACHE_REQUESTS);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
- let requestItem = RequestsMenu.getItemAtIndex(5);
- RequestsMenu.selectedItem = requestItem;
+ EventUtils.sendMouseEvent({ type: "mousedown" },
+ document.querySelectorAll(".request-list-item")[5]);
+ EventUtils.sendMouseEvent({ type: "contextmenu" },
+ document.querySelectorAll(".request-list-item")[5]);
yield waitForClipboardPromise(function setup() {
- RequestsMenu.contextMenu.copyImageAsDataUri();
+ // Context menu is appending in XUL document, we must select it from
+ // _toolbox.doc
+ monitor._toolbox.doc
+ .querySelector("#request-menu-context-copy-image-as-data-uri").click();
}, TEST_IMAGE_DATA_URI);
ok(true, "Clipboard contains the currently selected image as data uri.");
yield teardown(monitor);
});
--- a/devtools/client/netmonitor/test/browser_net_copy_params.js
+++ b/devtools/client/netmonitor/test/browser_net_copy_params.js
@@ -6,93 +6,102 @@
/**
* Tests whether copying a request item's parameters works.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(PARAMS_URL);
info("Starting test... ");
- let { NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, 1, 6);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
- RequestsMenu.selectedItem = RequestsMenu.getItemAtIndex(0);
- yield testCopyUrlParamsHidden(false);
- yield testCopyUrlParams("a");
- yield testCopyPostDataHidden(false);
- yield testCopyPostData("{ \"foo\": \"bar\" }");
+ yield testCopyUrlParamsHidden(0, false);
+ yield testCopyUrlParams(0, "a");
+ yield testCopyPostDataHidden(0, false);
+ yield testCopyPostData(0, "{ \"foo\": \"bar\" }");
- RequestsMenu.selectedItem = RequestsMenu.getItemAtIndex(1);
- yield testCopyUrlParamsHidden(false);
- yield testCopyUrlParams("a=b");
- yield testCopyPostDataHidden(false);
- yield testCopyPostData("{ \"foo\": \"bar\" }");
+ yield testCopyUrlParamsHidden(1, false);
+ yield testCopyUrlParams(1, "a=b");
+ yield testCopyPostDataHidden(1, false);
+ yield testCopyPostData(1, "{ \"foo\": \"bar\" }");
- RequestsMenu.selectedItem = RequestsMenu.getItemAtIndex(2);
- yield testCopyUrlParamsHidden(false);
- yield testCopyUrlParams("a=b");
- yield testCopyPostDataHidden(false);
- yield testCopyPostData("foo=bar");
+ yield testCopyUrlParamsHidden(2, false);
+ yield testCopyUrlParams(2, "a=b");
+ yield testCopyPostDataHidden(2, false);
+ yield testCopyPostData(2, "foo=bar");
- RequestsMenu.selectedItem = RequestsMenu.getItemAtIndex(3);
- yield testCopyUrlParamsHidden(false);
- yield testCopyUrlParams("a");
- yield testCopyPostDataHidden(false);
- yield testCopyPostData("{ \"foo\": \"bar\" }");
+ yield testCopyUrlParamsHidden(3, false);
+ yield testCopyUrlParams(3, "a");
+ yield testCopyPostDataHidden(3, false);
+ yield testCopyPostData(3, "{ \"foo\": \"bar\" }");
- RequestsMenu.selectedItem = RequestsMenu.getItemAtIndex(4);
- yield testCopyUrlParamsHidden(false);
- yield testCopyUrlParams("a=b");
- yield testCopyPostDataHidden(false);
- yield testCopyPostData("{ \"foo\": \"bar\" }");
+ yield testCopyUrlParamsHidden(4, false);
+ yield testCopyUrlParams(4, "a=b");
+ yield testCopyPostDataHidden(4, false);
+ yield testCopyPostData(4, "{ \"foo\": \"bar\" }");
- RequestsMenu.selectedItem = RequestsMenu.getItemAtIndex(5);
- yield testCopyUrlParamsHidden(false);
- yield testCopyUrlParams("a=b");
- yield testCopyPostDataHidden(false);
- yield testCopyPostData("?foo=bar");
+ yield testCopyUrlParamsHidden(5, false);
+ yield testCopyUrlParams(5, "a=b");
+ yield testCopyPostDataHidden(5, false);
+ yield testCopyPostData(5, "?foo=bar");
- RequestsMenu.selectedItem = RequestsMenu.getItemAtIndex(6);
- yield testCopyUrlParamsHidden(true);
- yield testCopyPostDataHidden(true);
+ yield testCopyUrlParamsHidden(6, true);
+ yield testCopyPostDataHidden(6, true);
return teardown(monitor);
- function testCopyUrlParamsHidden(hidden) {
- let allMenuItems = openContextMenuAndGetAllItems(NetMonitorView);
- let copyUrlParamsNode = allMenuItems.find(item =>
- item.id === "request-menu-context-copy-url-params");
- is(copyUrlParamsNode.visible, !hidden,
+ function testCopyUrlParamsHidden(index, hidden) {
+ EventUtils.sendMouseEvent({ type: "mousedown" },
+ document.querySelectorAll(".request-list-item")[index]);
+ EventUtils.sendMouseEvent({ type: "contextmenu" },
+ document.querySelectorAll(".request-list-item")[index]);
+ let copyUrlParamsNode = monitor._toolbox.doc
+ .querySelector("#request-menu-context-copy-url-params");
+ is(!!copyUrlParamsNode, !hidden,
"The \"Copy URL Parameters\" context menu item should" + (hidden ? " " : " not ") +
"be hidden.");
}
- function* testCopyUrlParams(queryString) {
+ function* testCopyUrlParams(index, queryString) {
+ EventUtils.sendMouseEvent({ type: "mousedown" },
+ document.querySelectorAll(".request-list-item")[index]);
+ EventUtils.sendMouseEvent({ type: "contextmenu" },
+ document.querySelectorAll(".request-list-item")[index]);
yield waitForClipboardPromise(function setup() {
- RequestsMenu.contextMenu.copyUrlParams();
+ monitor._toolbox.doc
+ .querySelector("#request-menu-context-copy-url-params").click();
}, queryString);
ok(true, "The url query string copied from the selected item is correct.");
}
- function testCopyPostDataHidden(hidden) {
- let allMenuItems = openContextMenuAndGetAllItems(NetMonitorView);
- let copyPostDataNode = allMenuItems.find(item =>
- item.id === "request-menu-context-copy-post-data");
- is(copyPostDataNode.visible, !hidden,
+ function testCopyPostDataHidden(index, hidden) {
+ EventUtils.sendMouseEvent({ type: "mousedown" },
+ document.querySelectorAll(".request-list-item")[index]);
+ EventUtils.sendMouseEvent({ type: "contextmenu" },
+ document.querySelectorAll(".request-list-item")[index]);
+ let copyPostDataNode = monitor._toolbox.doc
+ .querySelector("#request-menu-context-copy-post-data");
+ is(!!copyPostDataNode, !hidden,
"The \"Copy POST Data\" context menu item should" + (hidden ? " " : " not ") +
"be hidden.");
}
- function* testCopyPostData(postData) {
+ function* testCopyPostData(index, postData) {
+ EventUtils.sendMouseEvent({ type: "mousedown" },
+ document.querySelectorAll(".request-list-item")[index]);
+ EventUtils.sendMouseEvent({ type: "contextmenu" },
+ document.querySelectorAll(".request-list-item")[index]);
yield waitForClipboardPromise(function setup() {
- RequestsMenu.contextMenu.copyPostData();
+ monitor._toolbox.doc
+ .querySelector("#request-menu-context-copy-post-data").click();
}, postData);
ok(true, "The post data string copied from the selected item is correct.");
}
});
--- a/devtools/client/netmonitor/test/browser_net_copy_response.js
+++ b/devtools/client/netmonitor/test/browser_net_copy_response.js
@@ -8,28 +8,30 @@
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(CONTENT_TYPE_WITHOUT_CACHE_URL);
info("Starting test... ");
const EXPECTED_RESULT = '{ "greeting": "Hello JSON!" }';
- let { NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
-
- RequestsMenu.lazyUpdate = false;
+ let { document } = monitor.panelWin;
let wait = waitForNetworkEvents(monitor, CONTENT_TYPE_WITHOUT_CACHE_REQUESTS);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
- let requestItem = RequestsMenu.getItemAtIndex(3);
- RequestsMenu.selectedItem = requestItem;
+ EventUtils.sendMouseEvent({ type: "mousedown" },
+ document.querySelectorAll(".request-list-item")[3]);
+ EventUtils.sendMouseEvent({ type: "contextmenu" },
+ document.querySelectorAll(".request-list-item")[3]);
yield waitForClipboardPromise(function setup() {
- RequestsMenu.contextMenu.copyResponse();
+ // Context menu is appending in XUL document, we must select it from
+ // _toolbox.doc
+ monitor._toolbox.doc
+ .querySelector("#request-menu-context-copy-response").click();
}, EXPECTED_RESULT);
yield teardown(monitor);
});
--- a/devtools/client/netmonitor/test/browser_net_copy_svg_image_as_data_uri.js
+++ b/devtools/client/netmonitor/test/browser_net_copy_svg_image_as_data_uri.js
@@ -8,30 +8,32 @@
*/
const SVG_URL = EXAMPLE_URL + "dropmarker.svg";
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(CURL_URL);
info("Starting test... ");
- let { NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
-
- RequestsMenu.lazyUpdate = false;
+ let { document } = monitor.panelWin;
let wait = waitForNetworkEvents(monitor, 1);
yield ContentTask.spawn(tab.linkedBrowser, SVG_URL, function* (url) {
content.wrappedJSObject.performRequest(url);
});
yield wait;
- let requestItem = RequestsMenu.getItemAtIndex(0);
- RequestsMenu.selectedItem = requestItem;
+ EventUtils.sendMouseEvent({ type: "mousedown" },
+ document.querySelectorAll(".request-list-item")[0]);
+ EventUtils.sendMouseEvent({ type: "contextmenu" },
+ document.querySelectorAll(".request-list-item")[0]);
yield waitForClipboardPromise(function setup() {
- RequestsMenu.contextMenu.copyImageAsDataUri();
+ // Context menu is appending in XUL document, we must select it from
+ // _toolbox.doc
+ monitor._toolbox.doc
+ .querySelector("#request-menu-context-copy-image-as-data-uri").click();
}, function check(text) {
return text.startsWith("data:") && !/undefined/.test(text);
});
yield teardown(monitor);
});
--- a/devtools/client/netmonitor/test/browser_net_copy_url.js
+++ b/devtools/client/netmonitor/test/browser_net_copy_url.js
@@ -6,26 +6,33 @@
/**
* Tests if copying a request's url works.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(CUSTOM_GET_URL);
info("Starting test... ");
- let { NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let { getSortedRequests } = windowRequire("devtools/client/netmonitor/selectors/index");
let wait = waitForNetworkEvents(monitor, 1);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests(1);
});
yield wait;
- let requestItem = RequestsMenu.getItemAtIndex(0);
- RequestsMenu.selectedItem = requestItem;
+ EventUtils.sendMouseEvent({ type: "mousedown" },
+ document.querySelectorAll(".request-list-item")[0]);
+ EventUtils.sendMouseEvent({ type: "contextmenu" },
+ document.querySelectorAll(".request-list-item")[0]);
+
+ let requestItem = getSortedRequests(gStore.getState()).get(0);
yield waitForClipboardPromise(function setup() {
- RequestsMenu.contextMenu.copyUrl();
+ // Context menu is appending in XUL document, we must select it from
+ // _toolbox.doc
+ monitor._toolbox.doc
+ .querySelector("#request-menu-context-copy-url").click();
}, requestItem.url);
yield teardown(monitor);
});
--- a/devtools/client/netmonitor/test/browser_net_cors_requests.js
+++ b/devtools/client/netmonitor/test/browser_net_cors_requests.js
@@ -4,30 +4,42 @@
"use strict";
/**
* Test that CORS preflight requests are displayed by network monitor
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(CORS_URL);
- let { RequestsMenu } = monitor.panelWin.NetMonitorView;
- RequestsMenu.lazyUpdate = false;
+
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
+
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, 1, 1);
info("Performing a CORS request");
let requestUrl = "http://test1.example.com" + CORS_SJS_PATH;
yield ContentTask.spawn(tab.linkedBrowser, requestUrl, function* (url) {
content.wrappedJSObject.performRequests(url, "triggering/preflight", "post-data");
});
info("Waiting until the requests appear in netmonitor");
yield wait;
info("Checking the preflight and flight methods");
- ["OPTIONS", "POST"].forEach((method, i) => {
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(i),
- method, requestUrl);
+ ["OPTIONS", "POST"].forEach((method, index) => {
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(index),
+ method,
+ requestUrl
+ );
});
yield teardown(monitor);
});
--- a/devtools/client/netmonitor/test/browser_net_curl-utils.js
+++ b/devtools/client/netmonitor/test/browser_net_curl-utils.js
@@ -8,32 +8,33 @@
*/
const { CurlUtils } = require("devtools/client/shared/curl");
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(CURL_UTILS_URL);
info("Starting test... ");
- let { NetMonitorView, gNetwork } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire, gNetwork } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let { getSortedRequests } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, 1, 3);
yield ContentTask.spawn(tab.linkedBrowser, SIMPLE_SJS, function* (url) {
content.wrappedJSObject.performRequests(url);
});
yield wait;
let requests = {
- get: RequestsMenu.getItemAtIndex(0),
- post: RequestsMenu.getItemAtIndex(1),
- multipart: RequestsMenu.getItemAtIndex(2),
- multipartForm: RequestsMenu.getItemAtIndex(3)
+ get: getSortedRequests(gStore.getState()).get(0),
+ post: getSortedRequests(gStore.getState()).get(1),
+ multipart: getSortedRequests(gStore.getState()).get(2),
+ multipartForm: getSortedRequests(gStore.getState()).get(3),
};
let data = yield createCurlData(requests.get, gNetwork);
testFindHeader(data);
data = yield createCurlData(requests.post, gNetwork);
testIsUrlEncodedRequest(data);
testWritePostDataTextParams(data);
--- a/devtools/client/netmonitor/test/browser_net_cyrillic-01.js
+++ b/devtools/client/netmonitor/test/browser_net_cyrillic-01.js
@@ -6,37 +6,50 @@
/**
* Tests if cyrillic text is rendered correctly in the source editor.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(CYRILLIC_URL);
info("Starting test... ");
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, 1);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(0),
- "GET", CONTENT_TYPE_SJS + "?fmt=txt", {
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(0),
+ "GET",
+ CONTENT_TYPE_SJS + "?fmt=txt",
+ {
status: 200,
statusText: "DA DA DA"
- });
+ }
+ );
+ wait = waitForDOM(document, "#headers-panel");
+ EventUtils.sendMouseEvent({ type: "mousedown" },
+ document.querySelectorAll(".request-list-item")[0]);
+ yield wait;
wait = waitForDOM(document, "#response-panel .editor-mount iframe");
- EventUtils.sendMouseEvent({ type: "mousedown" },
- document.querySelector(".network-details-panel-toggle"));
- document.querySelector("#response-tab").click();
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#response-tab"));
let [editor] = yield wait;
yield once(editor, "DOMContentLoaded");
yield waitForDOM(editor.contentDocument, ".CodeMirror-code");
let text = editor.contentDocument
.querySelector(".CodeMirror-line").textContent;
ok(text.includes("\u0411\u0440\u0430\u0442\u0430\u043d"),
"The text shown in the source editor is correct.");
--- a/devtools/client/netmonitor/test/browser_net_cyrillic-02.js
+++ b/devtools/client/netmonitor/test/browser_net_cyrillic-02.js
@@ -7,35 +7,45 @@
* Tests if cyrillic text is rendered correctly in the source editor
* when loaded directly from an HTML page.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(CYRILLIC_URL);
info("Starting test... ");
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
-
- RequestsMenu.lazyUpdate = false;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
let wait = waitForNetworkEvents(monitor, 1);
tab.linkedBrowser.reload();
yield wait;
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(0),
- "GET", CYRILLIC_URL, {
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(0),
+ "GET",
+ CYRILLIC_URL,
+ {
status: 200,
statusText: "OK"
});
- wait = waitForDOM(document, "#response-panel .editor-mount iframe");
+ wait = waitForDOM(document, "#headers-panel");
EventUtils.sendMouseEvent({ type: "mousedown" },
- document.querySelector(".network-details-panel-toggle"));
- document.querySelector("#response-tab").click();
+ document.querySelectorAll(".request-list-item")[0]);
+ yield wait;
+ wait = waitForDOM(document, "#response-panel .editor-mount iframe");
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#response-tab"));
let [editor] = yield wait;
yield once(editor, "DOMContentLoaded");
yield waitForDOM(editor.contentDocument, ".CodeMirror-code");
let text = editor.contentDocument
.querySelector(".CodeMirror-code").textContent;
ok(text.includes("\u0411\u0440\u0430\u0442\u0430\u043d"),
"The text shown in the source editor is correct.");
--- a/devtools/client/netmonitor/test/browser_net_filter-01.js
+++ b/devtools/client/netmonitor/test/browser_net_filter-01.js
@@ -124,46 +124,47 @@ const EXPECTED_REQUESTS = [
fuzzyUrl: true,
status: 101,
statusText: "Switching Protocols",
}
}
];
add_task(function* () {
- let Actions = require("devtools/client/netmonitor/actions/index");
+ let { monitor } = yield initNetMonitor(FILTERING_URL);
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSelectedRequest,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
- let { monitor } = yield initNetMonitor(FILTERING_URL);
- let { gStore } = monitor.panelWin;
+ gStore.dispatch(Actions.batchEnable(false));
function setFreetextFilter(value) {
gStore.dispatch(Actions.setRequestFilterText(value));
}
info("Starting test... ");
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
-
- RequestsMenu.lazyUpdate = false;
-
let wait = waitForNetworkEvents(monitor, 9);
loadCommonFrameScript();
yield performRequestsInContent(REQUESTS_WITH_MEDIA_AND_FLASH_AND_WS);
yield wait;
EventUtils.sendMouseEvent({ type: "mousedown" },
- document.querySelector(".network-details-panel-toggle"));
+ document.querySelectorAll(".request-list-item")[0]);
- isnot(RequestsMenu.selectedItem, null,
+ isnot(getSelectedRequest(gStore.getState()), null,
"There should be a selected item in the requests menu.");
- is(RequestsMenu.selectedIndex, 0,
+ is(getSelectedIndex(gStore.getState()), 0,
"The first item should be selected in the requests menu.");
is(!!document.querySelector(".network-details-panel"), true,
- "The network details panel should render correctly.");
+ "The network details panel should render correctly.");
// First test with single filters...
testFilterButtons(monitor, "all");
testContents([1, 1, 1, 1, 1, 1, 1, 1, 1]);
EventUtils.sendMouseEvent({ type: "click" },
document.querySelector("#requests-menu-filter-html-button"));
testFilterButtons(monitor, "html");
@@ -301,38 +302,50 @@ add_task(function* () {
testFilterButtonsCustom(monitor, [0, 1, 1, 0, 0, 0, 0, 0, 0, 1]);
EventUtils.sendMouseEvent({ type: "click" },
document.querySelector("#requests-menu-filter-all-button"));
testFilterButtons(monitor, "all");
testContents([1, 1, 1, 1, 1, 1, 1, 1, 1]);
yield teardown(monitor);
+ function getSelectedIndex(state) {
+ if (!state.requests.selectedId) {
+ return -1;
+ }
+ return getSortedRequests(state).findIndex(r => r.id === state.requests.selectedId);
+ }
+
function testContents(visibility) {
- isnot(RequestsMenu.selectedItem, null,
+ isnot(getSelectedRequest(gStore.getState()), undefined,
"There should still be a selected item after filtering.");
- is(RequestsMenu.selectedIndex, 0,
+ is(getSelectedIndex(gStore.getState()), 0,
"The first item should be still selected after filtering.");
- is(!!document.querySelector(".network-details-panel"), true,
- "The network details panel should render correctly.");
- const items = RequestsMenu.items;
- const visibleItems = RequestsMenu.visibleItems;
+ const items = getSortedRequests(gStore.getState());
+ const visibleItems = getDisplayedRequests(gStore.getState());
is(items.size, visibility.length,
"There should be a specific amount of items in the requests menu.");
is(visibleItems.size, visibility.filter(e => e).length,
"There should be a specific amount of visible items in the requests menu.");
for (let i = 0; i < visibility.length; i++) {
let itemId = items.get(i).id;
let shouldBeVisible = !!visibility[i];
let isThere = visibleItems.some(r => r.id == itemId);
is(isThere, shouldBeVisible,
`The item at index ${i} has visibility=${shouldBeVisible}`);
if (shouldBeVisible) {
let { method, url, data } = EXPECTED_REQUESTS[i];
- verifyRequestItemTarget(RequestsMenu, items.get(i), method, url, data);
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(i),
+ method,
+ url,
+ data
+ );
}
}
}
});
--- a/devtools/client/netmonitor/test/browser_net_filter-02.js
+++ b/devtools/client/netmonitor/test/browser_net_filter-02.js
@@ -131,32 +131,37 @@ const EXPECTED_REQUESTS = [
add_task(function* () {
let { monitor } = yield initNetMonitor(FILTERING_URL);
info("Starting test... ");
// It seems that this test may be slow on Ubuntu builds running on ec2.
requestLongerTimeout(2);
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSelectedRequest,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, 9);
loadCommonFrameScript();
yield performRequestsInContent(REQUESTS_WITH_MEDIA_AND_FLASH_AND_WS);
yield wait;
EventUtils.sendMouseEvent({ type: "mousedown" },
- document.querySelector(".network-details-panel-toggle"));
+ document.querySelectorAll(".request-list-item")[0]);
- isnot(RequestsMenu.selectedItem, null,
+ isnot(getSelectedRequest(gStore.getState()), null,
"There should be a selected item in the requests menu.");
- is(RequestsMenu.selectedIndex, 0,
+ is(getSelectedIndex(gStore.getState()), 0,
"The first item should be selected in the requests menu.");
is(!!document.querySelector(".network-details-panel"), true,
"The network details panel should be visible after toggle button was pressed.");
testFilterButtons(monitor, "all");
testContents([1, 1, 1, 1, 1, 1, 1, 1, 1]);
info("Testing html filtering.");
@@ -188,26 +193,33 @@ add_task(function* () {
EventUtils.sendMouseEvent({ type: "click" },
document.querySelector("#requests-menu-filter-all-button"));
testFilterButtons(monitor, "all");
testContents([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]);
yield teardown(monitor);
+ function getSelectedIndex(state) {
+ if (!state.requests.selectedId) {
+ return -1;
+ }
+ return getSortedRequests(state).findIndex(r => r.id === state.requests.selectedId);
+ }
+
function testContents(visibility) {
- isnot(RequestsMenu.selectedItem, null,
+ isnot(getSelectedRequest(gStore.getState()), null,
"There should still be a selected item after filtering.");
- is(RequestsMenu.selectedIndex, 0,
+ is(getSelectedIndex(gStore.getState()), 0,
"The first item should be still selected after filtering.");
is(!!document.querySelector(".network-details-panel"), true,
"The network details panel should still be visible after filtering.");
- const items = RequestsMenu.items;
- const visibleItems = RequestsMenu.visibleItems;
+ const items = getSortedRequests(gStore.getState());
+ const visibleItems = getDisplayedRequests(gStore.getState());
is(items.size, visibility.length,
"There should be a specific amount of items in the requests menu.");
is(visibleItems.size, visibility.filter(e => e).length,
"There should be a specific amount of visible items in the requests menu.");
for (let i = 0; i < visibility.length; i++) {
let itemId = items.get(i).id;
@@ -216,14 +228,21 @@ add_task(function* () {
is(isThere, shouldBeVisible,
`The item at index ${i} has visibility=${shouldBeVisible}`);
}
for (let i = 0; i < EXPECTED_REQUESTS.length; i++) {
let { method, url, data } = EXPECTED_REQUESTS[i];
for (let j = i; j < visibility.length; j += EXPECTED_REQUESTS.length) {
if (visibility[j]) {
- verifyRequestItemTarget(RequestsMenu, items.get(j), method, url, data);
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(i),
+ method,
+ url,
+ data
+ );
}
}
}
}
});
--- a/devtools/client/netmonitor/test/browser_net_filter-03.js
+++ b/devtools/client/netmonitor/test/browser_net_filter-03.js
@@ -22,39 +22,44 @@ const REQUESTS_WITH_MEDIA = BASIC_REQUES
add_task(function* () {
let { monitor } = yield initNetMonitor(FILTERING_URL);
info("Starting test... ");
// It seems that this test may be slow on Ubuntu builds running on ec2.
requestLongerTimeout(2);
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSelectedRequest,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
// The test assumes that the first HTML request here has a longer response
// body than the other HTML requests performed later during the test.
let requests = Cu.cloneInto(REQUESTS_WITH_MEDIA, {});
let newres = "res=<p>" + new Array(10).join(Math.random(10)) + "</p>";
requests[0].url = requests[0].url.replace("res=undefined", newres);
loadCommonFrameScript();
let wait = waitForNetworkEvents(monitor, 7);
yield performRequestsInContent(requests);
yield wait;
EventUtils.sendMouseEvent({ type: "mousedown" },
- document.querySelector(".network-details-panel-toggle"));
+ document.querySelectorAll(".request-list-item")[0]);
- isnot(RequestsMenu.selectedItem, null,
+ isnot(getSelectedRequest(gStore.getState()), null,
"There should be a selected item in the requests menu.");
- is(RequestsMenu.selectedIndex, 0,
+ is(getSelectedIndex(gStore.getState()), 0,
"The first item should be selected in the requests menu.");
is(!!document.querySelector(".network-details-panel"), true,
"The network details panel should be visible after toggle button was pressed.");
testFilterButtons(monitor, "all");
testContents([0, 1, 2, 3, 4, 5, 6], 7, 0);
info("Sorting by size, ascending.");
@@ -93,22 +98,29 @@ add_task(function* () {
function resetSorting() {
EventUtils.sendMouseEvent({ type: "click" },
document.querySelector("#requests-menu-waterfall-button"));
EventUtils.sendMouseEvent({ type: "click" },
document.querySelector("#requests-menu-size-button"));
}
+ function getSelectedIndex(state) {
+ if (!state.requests.selectedId) {
+ return -1;
+ }
+ return getSortedRequests(state).findIndex(r => r.id === state.requests.selectedId);
+ }
+
function testContents(order, visible, selection) {
- isnot(RequestsMenu.selectedItem, null,
+ isnot(getSelectedRequest(gStore.getState()), null,
"There should still be a selected item after filtering.");
- is(RequestsMenu.selectedIndex, selection,
+ is(getSelectedIndex(gStore.getState()), selection,
"The first item should be still selected after filtering.");
is(!!document.querySelector(".network-details-panel"), true,
"The network details panel should still be visible after filtering.");
- is(RequestsMenu.items.length, order.length,
+ is(getSortedRequests(gStore.getState()).length, order.length,
"There should be a specific amount of items in the requests menu.");
- is(RequestsMenu.visibleItems.length, visible,
+ is(getDisplayedRequests(gStore.getState()).length, visible,
"There should be a specific amount of visible items in the requests menu.");
}
});
--- a/devtools/client/netmonitor/test/browser_net_filter-04.js
+++ b/devtools/client/netmonitor/test/browser_net_filter-04.js
@@ -30,20 +30,21 @@ const REQUESTS_WITH_MEDIA_AND_FLASH_AND_
]);
add_task(function* () {
Services.prefs.setCharPref("devtools.netmonitor.filters", '["js", "bogus"]');
let { monitor } = yield initNetMonitor(FILTERING_URL);
info("Starting test... ");
- let { Prefs, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let { Prefs } = windowRequire("devtools/client/netmonitor/prefs");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
is(Prefs.filters.length, 2,
"All filter types were loaded as an array from the preferences.");
is(Prefs.filters[0], "js",
"The first filter type is correct.");
is(Prefs.filters[1], "bogus",
"The second filter type is invalid, but loaded anyway.");
--- a/devtools/client/netmonitor/test/browser_net_footer-summary.js
+++ b/devtools/client/netmonitor/test/browser_net_footer-summary.js
@@ -8,49 +8,48 @@
*/
add_task(function* () {
requestLongerTimeout(2);
let { tab, monitor } = yield initNetMonitor(FILTERING_URL);
info("Starting test... ");
- let { $, NetMonitorView, gStore, windowRequire } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
-
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
let { getDisplayedRequestsSummary } =
windowRequire("devtools/client/netmonitor/selectors/index");
let { L10N } = windowRequire("devtools/client/netmonitor/l10n");
let { PluralForm } = windowRequire("devtools/shared/plural-form");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
testStatus();
for (let i = 0; i < 2; i++) {
info(`Performing requests in batch #${i}`);
let wait = waitForNetworkEvents(monitor, 8);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests('{ "getMedia": true, "getFlash": true }');
});
yield wait;
testStatus();
let buttons = ["html", "css", "js", "xhr", "fonts", "images", "media", "flash"];
for (let button of buttons) {
- let buttonEl = $(`#requests-menu-filter-${button}-button`);
+ let buttonEl = document.querySelector(`#requests-menu-filter-${button}-button`);
EventUtils.sendMouseEvent({ type: "click" }, buttonEl);
testStatus();
}
}
yield teardown(monitor);
function testStatus() {
- let value = $("#requests-menu-network-summary-button").textContent;
+ let value = document.querySelector("#requests-menu-network-summary-button").textContent;
info("Current summary: " + value);
let state = gStore.getState();
let totalRequestsCount = state.requests.requests.size;
let requestsSummary = getDisplayedRequestsSummary(state);
info(`Current requests: ${requestsSummary.count} of ${totalRequestsCount}.`);
if (!totalRequestsCount || !requestsSummary.count) {
--- a/devtools/client/netmonitor/test/browser_net_frame.js
+++ b/devtools/client/netmonitor/test/browser_net_frame.js
@@ -152,47 +152,58 @@ add_task(function* () {
// the initNetMonitor function clears the network request list after the
// page is loaded. That's why we first load a bogus page from SIMPLE_URL,
// and only then load the real thing from TOP_URL - we want to catch
// all the requests the page is making, not only the XHRs.
// We can't use about:blank here, because initNetMonitor checks that the
// page has actually made at least one request.
let { tab, monitor } = yield initNetMonitor(SIMPLE_URL);
- let { NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
- RequestsMenu.lazyUpdate = false;
+
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
+
+ gStore.dispatch(Actions.batchEnable(false));
tab.linkedBrowser.loadURI(TOP_URL, null, null);
yield waitForNetworkEvents(monitor, REQUEST_COUNT);
- is(RequestsMenu.itemCount, REQUEST_COUNT,
+ is(gStore.getState().requests.requests.size, REQUEST_COUNT,
"All the page events should be recorded.");
// While there is a defined order for requests in each document separately, the requests
// from different documents may interleave in various ways that change per test run, so
// there is not a single order when considering all the requests together.
let currentTop = 0;
let currentSub = 0;
for (let i = 0; i < REQUEST_COUNT; i++) {
- let requestItem = RequestsMenu.getItemAtIndex(i);
+ let requestItem = getSortedRequests(gStore.getState()).get(i);
let itemUrl = requestItem.url;
let itemCauseUri = requestItem.cause.loadingDocumentUri;
let spec;
if (itemUrl == SUB_URL || itemCauseUri == SUB_URL) {
spec = EXPECTED_REQUESTS_SUB[currentSub++];
} else {
spec = EXPECTED_REQUESTS_TOP[currentTop++];
}
let { method, url, causeType, causeUri, stack } = spec;
- verifyRequestItemTarget(RequestsMenu, requestItem,
- method, url, { cause: { type: causeType, loadingDocumentUri: causeUri } }
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ requestItem,
+ method,
+ url,
+ { cause: { type: causeType, loadingDocumentUri: causeUri } }
);
let { stacktrace } = requestItem.cause;
let stackLen = stacktrace ? stacktrace.length : 0;
if (stack) {
ok(stacktrace, `Request #${i} has a stacktrace`);
ok(stackLen > 0,
--- a/devtools/client/netmonitor/test/browser_net_header-docs.js
+++ b/devtools/client/netmonitor/test/browser_net_header-docs.js
@@ -8,34 +8,35 @@ const HeadersMDN = require("devtools/cli
/**
* Tests if "Learn More" links are correctly displayed
* next to headers.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(POST_DATA_URL);
info("Starting test... ");
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, 0, 2);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
- let origItem = RequestsMenu.getItemAtIndex(0);
- RequestsMenu.selectedItem = origItem;
-
EventUtils.sendMouseEvent({ type: "click" },
document.querySelectorAll(".request-list-item")[0]);
- testShowLearnMore(origItem);
+ testShowLearnMore(getSortedRequests(gStore.getState()).get(0));
return teardown(monitor);
/*
* Tests that a "Learn More" button is only shown if
* and only if a header is documented in MDN.
*/
function testShowLearnMore(data) {
--- a/devtools/client/netmonitor/test/browser_net_html-preview.js
+++ b/devtools/client/netmonitor/test/browser_net_html-preview.js
@@ -6,28 +6,28 @@
/**
* Tests if html responses show and properly populate a "Preview" tab.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(CONTENT_TYPE_URL);
info("Starting test... ");
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, 6);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
- EventUtils.sendMouseEvent({ type: "mousedown" },
+ EventUtils.sendMouseEvent({ type: "click" },
document.querySelector(".network-details-panel-toggle"));
ok(document.querySelector("#headers-tab[aria-selected=true]"),
"The headers tab in the details panel should be selected.");
ok(!document.querySelector("#preview-tab"),
"The preview tab should be hidden for non html responses.");
ok(!document.querySelector("#preview-panel"),
"The preview panel is hidden for non html responses.");
@@ -37,19 +37,17 @@ add_task(function* () {
document.querySelector("#preview-tab").click();
ok(document.querySelector("#preview-tab[aria-selected=true]"),
"The preview tab in the details panel should be selected.");
ok(document.querySelector("#preview-panel"),
"The preview panel should be visible now.");
let iframe = document.querySelector("#preview-panel iframe");
- console.log(123)
yield once(iframe, "DOMContentLoaded");
- console.log(123)
ok(iframe,
"There should be a response preview iframe available.");
ok(iframe.contentDocument,
"The iframe's content document should be available.");
is(iframe.contentDocument.querySelector("blink").textContent, "Not Found",
"The iframe's content document should be loaded and correct.");
--- a/devtools/client/netmonitor/test/browser_net_icon-preview.js
+++ b/devtools/client/netmonitor/test/browser_net_icon-preview.js
@@ -3,26 +3,26 @@
"use strict";
/**
* Tests if image responses show a thumbnail in the requests menu.
*/
add_task(function* () {
- let Actions = require("devtools/client/netmonitor/actions/index");
-
let { tab, monitor } = yield initNetMonitor(CONTENT_TYPE_WITHOUT_CACHE_URL);
info("Starting test... ");
- let { $, $all, EVENTS, ACTIVITY_TYPE, NetMonitorView, NetMonitorController,
- gStore } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire, NetMonitorController } =
+ monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let { ACTIVITY_TYPE } = windowRequire("devtools/client/netmonitor/constants");
+ let { EVENTS } = windowRequire("devtools/client/netmonitor/events");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForEvents();
yield performRequests();
yield wait;
info("Checking the image thumbnail when all items are shown.");
checkImageThumbnail();
@@ -58,16 +58,16 @@ add_task(function* () {
}
function* reloadAndPerformRequests() {
yield NetMonitorController.triggerActivity(ACTIVITY_TYPE.RELOAD.WITH_CACHE_ENABLED);
yield performRequests();
}
function checkImageThumbnail() {
- is($all(".requests-menu-icon[data-type=thumbnail]").length, 1,
+ is(document.querySelectorAll(".requests-menu-icon[data-type=thumbnail]").length, 1,
"There should be only one image request with a thumbnail displayed.");
- is($(".requests-menu-icon[data-type=thumbnail]").src, TEST_IMAGE_DATA_URI,
+ is(document.querySelector(".requests-menu-icon[data-type=thumbnail]").src, TEST_IMAGE_DATA_URI,
"The image requests-menu-icon thumbnail is displayed correctly.");
- is($(".requests-menu-icon[data-type=thumbnail]").hidden, false,
+ is(document.querySelector(".requests-menu-icon[data-type=thumbnail]").hidden, false,
"The image requests-menu-icon thumbnail should not be hidden.");
}
});
--- a/devtools/client/netmonitor/test/browser_net_image-tooltip.js
+++ b/devtools/client/netmonitor/test/browser_net_image-tooltip.js
@@ -8,94 +8,99 @@ const IMAGE_TOOLTIP_REQUESTS = 1;
/**
* Tests if image responses show a popup in the requests menu when hovered.
*/
add_task(function* test() {
let { tab, monitor } = yield initNetMonitor(IMAGE_TOOLTIP_URL);
info("Starting test... ");
- let { $, EVENTS, ACTIVITY_TYPE, NetMonitorView, NetMonitorController } =
- monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
- RequestsMenu.lazyUpdate = true;
+ let { document, gStore, windowRequire, NetMonitorController } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let { ACTIVITY_TYPE } = windowRequire("devtools/client/netmonitor/constants");
+ let { EVENTS } = windowRequire("devtools/client/netmonitor/events");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
+ let toolboxDoc = monitor._toolbox.doc;
+
+ 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 onThumbnail;
info("Checking the image thumbnail after a few requests were made...");
- yield showTooltipAndVerify(RequestsMenu.tooltip, RequestsMenu.getItemAtIndex(0));
+ yield showTooltipAndVerify(toolboxDoc,
+ document.querySelectorAll(".request-list-item")[0]);
// Hide tooltip before next test, to avoid the situation that tooltip covers
// the icon for the request of the next test.
info("Checking the image thumbnail gets hidden...");
- yield hideTooltipAndVerify(RequestsMenu.tooltip, RequestsMenu.getItemAtIndex(0));
+ yield hideTooltipAndVerify(monitor._toolbox.doc,
+ document.querySelectorAll(".request-list-item")[0]);
// +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 onThumbnail;
info("Checking the image thumbnail after a reload.");
- yield showTooltipAndVerify(RequestsMenu.tooltip, RequestsMenu.getItemAtIndex(1));
+ yield showTooltipAndVerify(toolboxDoc,
+ document.querySelectorAll(".request-list-item")[1]);
info("Checking if the image thumbnail is hidden when mouse leaves the menu widget");
- let requestsMenuEl = $(".requests-menu-contents");
- let onHidden = RequestsMenu.tooltip.once("hidden");
- EventUtils.synthesizeMouse(requestsMenuEl, 0, 0, {type: "mouseout"}, monitor.panelWin);
- yield onHidden;
+ let requestsListContents = document.querySelector(".requests-menu-contents");
+ EventUtils.synthesizeMouse(requestsListContents, 0, 0, { type: "mouseout" }, monitor.panelWin);
+ yield waitUntil(() => !toolboxDoc.querySelector(".tooltip-container.tooltip-visible"));
yield teardown(monitor);
function performRequests() {
return ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
}
/**
- * Show a tooltip on the {requestItem} and verify that it was displayed
+ * Show a tooltip on the {target} and verify that it was displayed
* with the expected content.
*/
- function* showTooltipAndVerify(tooltip, requestItem) {
- let anchor = $(".requests-menu-file", getItemTarget(RequestsMenu, requestItem));
- yield showTooltipOn(tooltip, anchor);
+ function* showTooltipAndVerify(toolboxDoc, target) {
+ let anchor = target.querySelector(".requests-menu-file");
+ yield showTooltipOn(toolboxDoc, anchor);
info("Tooltip was successfully opened for the image request.");
- is(tooltip.panel.querySelector("img").src, TEST_IMAGE_DATA_URI,
+ is(toolboxDoc.querySelector(".tooltip-panel img").src, TEST_IMAGE_DATA_URI,
"The tooltip's image content is displayed correctly.");
}
/**
* Trigger a tooltip over an element by sending mousemove event.
* @return a promise that resolves when the tooltip is shown
*/
- function showTooltipOn(tooltip, element) {
- let onShown = tooltip.once("shown");
+ function* showTooltipOn(toolboxDoc, element) {
let win = element.ownerDocument.defaultView;
- EventUtils.synthesizeMouseAtCenter(element, {type: "mousemove"}, win);
- return onShown;
+ EventUtils.synthesizeMouseAtCenter(element, { type: "mousemove" }, win);
+ yield waitUntil(() => toolboxDoc.querySelector(".tooltip-panel img"));
}
/**
- * Hide a tooltip on the {requestItem} and verify that it was closed.
+ * Hide a tooltip on the {target} and verify that it was closed.
*/
- function* hideTooltipAndVerify(tooltip, requestItem) {
+ function* hideTooltipAndVerify(toolboxDoc, target) {
// Hovering over the "method" column hides the tooltip.
- let anchor = $(".requests-menu-method", getItemTarget(RequestsMenu, requestItem));
+ let anchor = target.querySelector(".requests-menu-method");
+ let win = anchor.ownerDocument.defaultView;
+ EventUtils.synthesizeMouseAtCenter(anchor, { type: "mousemove" }, win);
- let onTooltipHidden = tooltip.once("hidden");
- let win = anchor.ownerDocument.defaultView;
- EventUtils.synthesizeMouseAtCenter(anchor, {type: "mousemove"}, win);
- yield onTooltipHidden;
-
+ yield waitUntil(() => !toolboxDoc.querySelector(".tooltip-container.tooltip-visible"));
info("Tooltip was successfully closed.");
}
});
--- a/devtools/client/netmonitor/test/browser_net_json-b64.js
+++ b/devtools/client/netmonitor/test/browser_net_json-b64.js
@@ -7,31 +7,32 @@
* Tests if JSON responses encoded in base64 are handled correctly.
*/
add_task(function* () {
let { L10N } = require("devtools/client/netmonitor/l10n");
let { tab, monitor } = yield initNetMonitor(JSON_B64_URL);
info("Starting test... ");
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, 1);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
wait = waitForDOM(document, "#response-panel");
- EventUtils.sendMouseEvent({ type: "mousedown" },
+ EventUtils.sendMouseEvent({ type: "click" },
document.querySelector(".network-details-panel-toggle"));
- document.querySelector("#response-tab").click();
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#response-tab"));
yield wait;
let tabpanel = document.querySelector("#response-panel");
is(tabpanel.querySelector(".response-error-header") === null, true,
"The response error header doesn't have the intended visibility.");
let jsonView = tabpanel.querySelector(".tree-section .treeLabel") || {};
is(jsonView.textContent === L10N.getStr("jsonScopeName"), true,
--- a/devtools/client/netmonitor/test/browser_net_json-long.js
+++ b/devtools/client/netmonitor/test/browser_net_json-long.js
@@ -12,42 +12,52 @@ add_task(function* () {
let { tab, monitor } = yield initNetMonitor(JSON_LONG_URL);
info("Starting test... ");
// This is receiving over 80 KB of json and will populate over 6000 items
// in a variables view instance. Debug builds are slow.
requestLongerTimeout(4);
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, 1);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(0),
- "GET", CONTENT_TYPE_SJS + "?fmt=json-long", {
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(0),
+ "GET",
+ CONTENT_TYPE_SJS + "?fmt=json-long",
+ {
status: 200,
statusText: "OK",
type: "json",
fullMimeType: "text/json; charset=utf-8",
size: L10N.getFormatStr("networkMenu.sizeKB",
L10N.numberWithDecimals(85975 / 1024, 2)),
time: true
});
wait = waitForDOM(document, "#response-panel");
- EventUtils.sendMouseEvent({ type: "mousedown" },
+ EventUtils.sendMouseEvent({ type: "click" },
document.querySelector(".network-details-panel-toggle"));
- document.querySelector("#response-tab").click();
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#response-tab"));
yield wait;
testResponseTab();
yield teardown(monitor);
function testResponseTab() {
let tabpanel = document.querySelector("#response-panel");
--- a/devtools/client/netmonitor/test/browser_net_json-malformed.js
+++ b/devtools/client/netmonitor/test/browser_net_json-malformed.js
@@ -7,39 +7,49 @@
* Tests if malformed JSON responses are handled correctly.
*/
add_task(function* () {
let { L10N } = require("devtools/client/netmonitor/l10n");
let { tab, monitor } = yield initNetMonitor(JSON_MALFORMED_URL);
info("Starting test... ");
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, 1);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(0),
- "GET", CONTENT_TYPE_SJS + "?fmt=json-malformed", {
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(0),
+ "GET",
+ CONTENT_TYPE_SJS + "?fmt=json-malformed",
+ {
status: 200,
statusText: "OK",
type: "json",
fullMimeType: "text/json; charset=utf-8"
});
wait = waitForDOM(document, "#response-panel .editor-mount iframe");
- EventUtils.sendMouseEvent({ type: "mousedown" },
+ EventUtils.sendMouseEvent({ type: "click" },
document.querySelector(".network-details-panel-toggle"));
- document.querySelector("#response-tab").click();
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#response-tab"));
let [editor] = yield wait;
yield once(editor, "DOMContentLoaded");
yield waitForDOM(editor.contentDocument, ".CodeMirror-code");
let tabpanel = document.querySelector("#response-panel");
is(tabpanel.querySelector(".response-error-header") === null, false,
"The response error header doesn't have the intended visibility.");
is(tabpanel.querySelector(".response-error-header").textContent,
--- a/devtools/client/netmonitor/test/browser_net_json-null.js
+++ b/devtools/client/netmonitor/test/browser_net_json-null.js
@@ -8,20 +8,24 @@ const { L10N } = require("devtools/clien
/**
* Tests if JSON responses containing null values are properly displayed.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(JSON_BASIC_URL + "?name=null");
info("Starting test... ");
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, 1);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
yield openResponsePanel(document);
@@ -64,15 +68,14 @@ function checkResponsePanelDisplaysJSON(
}
/**
* Open the netmonitor details panel and switch to the response tab.
* Returns a promise that will resolve when the response panel DOM element is available.
*/
function openResponsePanel(document) {
let onReponsePanelReady = waitForDOM(document, "#response-panel");
- EventUtils.sendMouseEvent(
- { type: "mousedown" },
- document.querySelector(".network-details-panel-toggle")
- );
- document.querySelector("#response-tab").click();
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector(".network-details-panel-toggle"));
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#response-tab"));
return onReponsePanelReady;
}
--- a/devtools/client/netmonitor/test/browser_net_json_custom_mime.js
+++ b/devtools/client/netmonitor/test/browser_net_json_custom_mime.js
@@ -8,41 +8,51 @@
*/
add_task(function* () {
let { L10N } = require("devtools/client/netmonitor/l10n");
let { tab, monitor } = yield initNetMonitor(JSON_CUSTOM_MIME_URL);
info("Starting test... ");
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, 1);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(0),
- "GET", CONTENT_TYPE_SJS + "?fmt=json-custom-mime", {
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(0),
+ "GET",
+ CONTENT_TYPE_SJS + "?fmt=json-custom-mime",
+ {
status: 200,
statusText: "OK",
type: "x-bigcorp-json",
fullMimeType: "text/x-bigcorp-json; charset=utf-8",
size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 41),
time: true
});
wait = waitForDOM(document, "#response-panel");
- EventUtils.sendMouseEvent({ type: "mousedown" },
+ EventUtils.sendMouseEvent({ type: "click" },
document.querySelector(".network-details-panel-toggle"));
- document.querySelector("#response-tab").click();
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#response-tab"));
yield wait;
testResponseTab();
yield teardown(monitor);
function testResponseTab() {
let tabpanel = document.querySelector("#response-panel");
--- a/devtools/client/netmonitor/test/browser_net_json_text_mime.js
+++ b/devtools/client/netmonitor/test/browser_net_json_text_mime.js
@@ -8,41 +8,51 @@
*/
add_task(function* () {
let { L10N } = require("devtools/client/netmonitor/l10n");
let { tab, monitor } = yield initNetMonitor(JSON_TEXT_MIME_URL);
info("Starting test... ");
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, 1);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(0),
- "GET", CONTENT_TYPE_SJS + "?fmt=json-text-mime", {
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(0),
+ "GET",
+ CONTENT_TYPE_SJS + "?fmt=json-text-mime",
+ {
status: 200,
statusText: "OK",
type: "plain",
fullMimeType: "text/plain; charset=utf-8",
size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 41),
time: true
});
wait = waitForDOM(document, "#response-panel");
- EventUtils.sendMouseEvent({ type: "mousedown" },
+ EventUtils.sendMouseEvent({ type: "click" },
document.querySelector(".network-details-panel-toggle"));
- document.querySelector("#response-tab").click();
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#response-tab"));
yield wait;
testResponseTab();
yield teardown(monitor);
function testResponseTab() {
let tabpanel = document.querySelector("#response-panel");
--- a/devtools/client/netmonitor/test/browser_net_jsonp.js
+++ b/devtools/client/netmonitor/test/browser_net_jsonp.js
@@ -8,56 +8,72 @@
*/
add_task(function* () {
let { L10N } = require("devtools/client/netmonitor/l10n");
let { tab, monitor } = yield initNetMonitor(JSONP_URL);
info("Starting test... ");
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, 2);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(0),
- "GET", CONTENT_TYPE_SJS + "?fmt=jsonp&jsonp=$_0123Fun", {
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(0),
+ "GET",
+ CONTENT_TYPE_SJS + "?fmt=jsonp&jsonp=$_0123Fun",
+ {
status: 200,
statusText: "OK",
type: "json",
fullMimeType: "text/json; charset=utf-8",
size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 41),
time: true
});
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(1),
- "GET", CONTENT_TYPE_SJS + "?fmt=jsonp2&jsonp=$_4567Sad", {
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(1),
+ "GET",
+ CONTENT_TYPE_SJS + "?fmt=jsonp2&jsonp=$_4567Sad",
+ {
status: 200,
statusText: "OK",
type: "json",
fullMimeType: "text/json; charset=utf-8",
size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 54),
time: true
});
wait = waitForDOM(document, "#response-panel");
- EventUtils.sendMouseEvent({ type: "mousedown" },
+ EventUtils.sendMouseEvent({ type: "click" },
document.querySelector(".network-details-panel-toggle"));
- document.querySelector("#response-tab").click();
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#response-tab"));
yield wait;
testResponseTab("$_0123Fun", "\"Hello JSONP!\"");
wait = waitForDOM(document, "#response-panel .tree-section");
- RequestsMenu.selectedIndex = 1;
+ EventUtils.sendMouseEvent({ type: "mousedown" },
+ document.querySelectorAll(".request-list-item")[1]);
yield wait;
testResponseTab("$_4567Sad", "\"Hello weird JSONP!\"");
yield teardown(monitor);
function testResponseTab(func, greeting) {
let tabpanel = document.querySelector("#response-panel");
--- a/devtools/client/netmonitor/test/browser_net_large-response.js
+++ b/devtools/client/netmonitor/test/browser_net_large-response.js
@@ -12,37 +12,47 @@ const HTML_LONG_URL = CONTENT_TYPE_SJS +
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(CUSTOM_GET_URL);
info("Starting test... ");
// This test could potentially be slow because over 100 KB of stuff
// is going to be requested and displayed in the source editor.
requestLongerTimeout(2);
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, 1);
yield ContentTask.spawn(tab.linkedBrowser, HTML_LONG_URL, function* (url) {
content.wrappedJSObject.performRequests(1, url);
});
yield wait;
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(0),
- "GET", CONTENT_TYPE_SJS + "?fmt=html-long", {
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(0),
+ "GET",
+ CONTENT_TYPE_SJS + "?fmt=html-long",
+ {
status: 200,
statusText: "OK"
});
let waitDOM = waitForDOM(document, "#response-panel .editor-mount iframe");
- EventUtils.sendMouseEvent({ type: "mousedown" },
+ EventUtils.sendMouseEvent({ type: "click" },
document.querySelector(".network-details-panel-toggle"));
- document.querySelector("#response-tab").click();
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#response-tab"));
let [editor] = yield waitDOM;
yield once(editor, "DOMContentLoaded");
yield waitForDOM(editor.contentDocument, ".CodeMirror-code");
let text = editor.contentDocument
.querySelector(".CodeMirror-line").textContent;
ok(text.match(/^<p>/), "The text shown in the source editor is incorrect.");
--- a/devtools/client/netmonitor/test/browser_net_open_request_in_tab.js
+++ b/devtools/client/netmonitor/test/browser_net_open_request_in_tab.js
@@ -6,32 +6,41 @@
/**
* Tests if Open in new tab works.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(CUSTOM_GET_URL);
info("Starting test...");
- let { NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, 1);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests(1);
});
yield wait;
- let requestItem = RequestsMenu.getItemAtIndex(0);
- RequestsMenu.selectedItem = requestItem;
+ EventUtils.sendMouseEvent({ type: "mousedown" },
+ document.querySelectorAll(".request-list-item")[0]);
+ EventUtils.sendMouseEvent({ type: "contextmenu" },
+ document.querySelectorAll(".request-list-item")[0]);
let onTabOpen = once(gBrowser.tabContainer, "TabOpen", false);
- RequestsMenu.contextMenu.openRequestInTab();
+ // Context menu is appending in XUL document, we must select it from
+ // _toolbox.doc
+ monitor._toolbox.doc
+ .querySelector("#request-menu-context-newtab").click();
yield onTabOpen;
ok(true, "A new tab has been opened");
yield teardown(monitor);
gBrowser.removeCurrentTab();
});
--- a/devtools/client/netmonitor/test/browser_net_page-nav.js
+++ b/devtools/client/netmonitor/test/browser_net_page-nav.js
@@ -7,17 +7,18 @@
* Tests if page navigation ("close", "navigate", etc.) triggers an appropriate
* action in the network monitor.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(SIMPLE_URL);
info("Starting test... ");
- let { EVENTS } = monitor.panelWin;
+ let { windowRequire } = monitor.panelWin;
+ let { EVENTS } = windowRequire("devtools/client/netmonitor/events");
yield testNavigate();
yield testNavigateBack();
yield testClose();
function* testNavigate() {
info("Navigating forward...");
--- a/devtools/client/netmonitor/test/browser_net_pane-collapse.js
+++ b/devtools/client/netmonitor/test/browser_net_pane-collapse.js
@@ -6,43 +6,44 @@
/**
* Tests if the network monitor panes collapse properly.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(SIMPLE_URL);
info("Starting test... ");
- let { document, Prefs } = monitor.panelWin;
+ let { document, windowRequire } = monitor.panelWin;
+ let { Prefs } = windowRequire("devtools/client/netmonitor/prefs");
let detailsPaneToggleButton = document.querySelector(".network-details-panel-toggle");
let wait = waitForNetworkEvents(monitor, 1);
tab.linkedBrowser.reload();
yield wait;
ok(!document.querySelector(".network-details-panel") &&
detailsPaneToggleButton.classList.contains("pane-collapsed"),
"The details panel should initially be hidden.");
- EventUtils.sendMouseEvent({ type: "mousedown" }, detailsPaneToggleButton);
+ EventUtils.sendMouseEvent({ type: "click" }, detailsPaneToggleButton);
is(~~(document.querySelector(".network-details-panel").clientWidth),
Prefs.networkDetailsWidth,
"The details panel has an incorrect width.");
ok(document.querySelector(".network-details-panel") &&
!detailsPaneToggleButton.classList.contains("pane-collapsed"),
"The details panel should at this point be visible.");
- EventUtils.sendMouseEvent({ type: "mousedown" }, detailsPaneToggleButton);
+ EventUtils.sendMouseEvent({ type: "click" }, detailsPaneToggleButton);
ok(!document.querySelector(".network-details-panel") &&
detailsPaneToggleButton.classList.contains("pane-collapsed"),
"The details panel should not be visible after collapsing.");
- EventUtils.sendMouseEvent({ type: "mousedown" }, detailsPaneToggleButton);
+ EventUtils.sendMouseEvent({ type: "click" }, detailsPaneToggleButton);
is(~~(document.querySelector(".network-details-panel").clientWidth),
Prefs.networkDetailsWidth,
"The details panel has an incorrect width after uncollapsing.");
ok(document.querySelector(".network-details-panel") &&
!detailsPaneToggleButton.classList.contains("pane-collapsed"),
"The details panel should be visible again after uncollapsing.");
--- a/devtools/client/netmonitor/test/browser_net_pane-toggle.js
+++ b/devtools/client/netmonitor/test/browser_net_pane-toggle.js
@@ -6,67 +6,79 @@
/**
* Tests if toggling the details pane works as expected.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(SIMPLE_URL);
info("Starting test... ");
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
- let { NETWORK_EVENT } = monitor.panelWin.EVENTS;
- RequestsMenu.lazyUpdate = false;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let { EVENTS } = windowRequire("devtools/client/netmonitor/events");
+ let {
+ getSelectedRequest,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
+
+ gStore.dispatch(Actions.batchEnable(false));
let toggleButton = document.querySelector(".network-details-panel-toggle");
is(toggleButton.hasAttribute("disabled"), true,
"The pane toggle button should be disabled when the frontend is opened.");
is(toggleButton.classList.contains("pane-collapsed"), true,
"The pane toggle button should indicate that the details pane is " +
"collapsed when the frontend is opened.");
is(!!document.querySelector(".network-details-panel"), false,
"The details pane should be hidden when the frontend is opened.");
- is(RequestsMenu.selectedItem, null,
+ is(getSelectedRequest(gStore.getState()), null,
"There should be no selected item in the requests menu.");
- let networkEvent = monitor.panelWin.once(NETWORK_EVENT);
+ let networkEvent = monitor.panelWin.once(EVENTS.NETWORK_EVENT);
tab.linkedBrowser.reload();
yield networkEvent;
is(toggleButton.hasAttribute("disabled"), false,
"The pane toggle button should be enabled after the first request.");
is(toggleButton.classList.contains("pane-collapsed"), true,
"The pane toggle button should still indicate that the details pane is " +
"collapsed after the first request.");
is(!!document.querySelector(".network-details-panel"), false,
"The details pane should still be hidden after the first request.");
- is(RequestsMenu.selectedItem, null,
+ is(getSelectedRequest(gStore.getState()), null,
"There should still be no selected item in the requests menu.");
- EventUtils.sendMouseEvent({ type: "mousedown" }, toggleButton);
+ EventUtils.sendMouseEvent({ type: "click" }, toggleButton);
is(toggleButton.hasAttribute("disabled"), false,
"The pane toggle button should still be enabled after being pressed.");
is(toggleButton.classList.contains("pane-collapsed"), false,
"The pane toggle button should now indicate that the details pane is " +
"not collapsed anymore after being pressed.");
is(!!document.querySelector(".network-details-panel"), true,
"The details pane should not be hidden after toggle button was pressed.");
- isnot(RequestsMenu.selectedItem, null,
+ isnot(getSelectedRequest(gStore.getState()), null,
"There should be a selected item in the requests menu.");
- is(RequestsMenu.selectedIndex, 0,
+ is(getSelectedIndex(gStore.getState()), 0,
"The first item should be selected in the requests menu.");
- EventUtils.sendMouseEvent({ type: "mousedown" }, toggleButton);
+ EventUtils.sendMouseEvent({ type: "click" }, toggleButton);
is(toggleButton.hasAttribute("disabled"), false,
"The pane toggle button should still be enabled after being pressed again.");
is(toggleButton.classList.contains("pane-collapsed"), true,
"The pane toggle button should now indicate that the details pane is " +
"collapsed after being pressed again.");
is(!!document.querySelector(".network-details-panel"), false,
"The details pane should now be hidden after the toggle button was pressed again.");
- is(RequestsMenu.selectedItem, null,
+ is(getSelectedRequest(gStore.getState()), null,
"There should now be no selected item in the requests menu.");
yield teardown(monitor);
+
+ function getSelectedIndex(state) {
+ if (!state.requests.selectedId) {
+ return -1;
+ }
+ return getSortedRequests(state).findIndex(r => r.id === state.requests.selectedId);
+ }
});
--- a/devtools/client/netmonitor/test/browser_net_persistent_logs.js
+++ b/devtools/client/netmonitor/test/browser_net_persistent_logs.js
@@ -7,40 +7,39 @@
* Tests if the network monitor leaks on initialization and sudden destruction.
* You can also use this initialization format as a template for other tests.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(SINGLE_GET_URL);
info("Starting test... ");
- let { NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, windowRequire } = monitor.panelWin;
Services.prefs.setBoolPref("devtools.webconsole.persistlog", false);
yield reloadAndWait();
- is(RequestsMenu.itemCount, 2,
- "The request menu should have two items at this point.");
+ is(document.querySelectorAll(".request-list-item").length, 2,
+ "The request list should have two items at this point.");
yield reloadAndWait();
// Since the reload clears the log, we still expect two requests in the log
- is(RequestsMenu.itemCount, 2,
- "The request menu should still have two items at this point.");
+ is(document.querySelectorAll(".request-list-item").length, 2,
+ "The request list should still have two items at this point.");
// Now we toggle the persistence logs on
Services.prefs.setBoolPref("devtools.webconsole.persistlog", true);
yield reloadAndWait();
// Since we togged the persistence logs, we expect four items after the reload
- is(RequestsMenu.itemCount, 4,
- "The request menu should now have four items at this point.");
+ is(document.querySelectorAll(".request-list-item").length, 4,
+ "The request list should now have four items at this point.");
Services.prefs.setBoolPref("devtools.webconsole.persistlog", false);
return teardown(monitor);
/**
* Reload the page and wait for 2 GET requests. Race-free.
*/
function reloadAndWait() {
--- a/devtools/client/netmonitor/test/browser_net_post-data-01.js
+++ b/devtools/client/netmonitor/test/browser_net_post-data-01.js
@@ -11,58 +11,74 @@ add_task(function* () {
let { L10N } = require("devtools/client/netmonitor/l10n");
// Set a higher panel height in order to get full CodeMirror content
Services.prefs.setIntPref("devtools.toolbox.footer.height", 400);
let { tab, monitor } = yield initNetMonitor(POST_DATA_URL);
info("Starting test... ");
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, 0, 2);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(0),
- "POST", SIMPLE_SJS + "?foo=bar&baz=42&type=urlencoded", {
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(0),
+ "POST",
+ SIMPLE_SJS + "?foo=bar&baz=42&type=urlencoded",
+ {
status: 200,
statusText: "Och Aye",
type: "plain",
fullMimeType: "text/plain; charset=utf-8",
size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 12),
time: true
});
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(1),
- "POST", SIMPLE_SJS + "?foo=bar&baz=42&type=multipart", {
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(1),
+ "POST",
+ SIMPLE_SJS + "?foo=bar&baz=42&type=multipart",
+ {
status: 200,
statusText: "Och Aye",
type: "plain",
fullMimeType: "text/plain; charset=utf-8",
size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 12),
time: true
});
// Wait for all tree sections updated by react
wait = waitForDOM(document, "#params-panel .tree-section", 2);
EventUtils.sendMouseEvent({ type: "mousedown" },
- document.querySelector(".network-details-panel-toggle"));
- document.querySelector("#params-tab").click();
+ document.querySelectorAll(".request-list-item")[0]);
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#params-tab"));
yield wait;
yield testParamsTab("urlencoded");
// Wait for all tree sections and editor updated by react
let waitForSections = waitForDOM(document, "#params-panel .tree-section", 2);
let waitForEditor = waitForDOM(document, "#params-panel .editor-mount iframe");
- RequestsMenu.selectedIndex = 1;
+ EventUtils.sendMouseEvent({ type: "mousedown" },
+ document.querySelectorAll(".request-list-item")[1]);
let [, editorFrames] = yield Promise.all([waitForSections, waitForEditor]);
yield once(editorFrames[0], "DOMContentLoaded");
yield waitForDOM(editorFrames[0].contentDocument, ".CodeMirror-code");
yield testParamsTab("multipart");
return teardown(monitor);
function* testParamsTab(type) {
--- a/devtools/client/netmonitor/test/browser_net_post-data-02.js
+++ b/devtools/client/netmonitor/test/browser_net_post-data-02.js
@@ -9,32 +9,37 @@
*/
add_task(function* () {
let { L10N } = require("devtools/client/netmonitor/l10n");
let { tab, monitor } = yield initNetMonitor(POST_RAW_URL);
info("Starting test... ");
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, 0, 1);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
// Wait for all tree view updated by react
wait = waitForDOM(document, "#params-panel .tree-section");
EventUtils.sendMouseEvent({ type: "mousedown" },
- document.querySelector(".network-details-panel-toggle"));
- document.querySelector("#params-tab").click();
+ document.querySelectorAll(".request-list-item")[0]);
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#params-tab"));
yield wait;
let tabpanel = document.querySelector("#params-panel");
ok(tabpanel.querySelector(".treeTable"),
"The request params doesn't have the indended visibility.");
ok(tabpanel.querySelector(".editor-mount") === null,
"The request post data doesn't have the indended visibility.");
--- a/devtools/client/netmonitor/test/browser_net_post-data-03.js
+++ b/devtools/client/netmonitor/test/browser_net_post-data-03.js
@@ -9,32 +9,33 @@
*/
add_task(function* () {
let { L10N } = require("devtools/client/netmonitor/l10n");
let { tab, monitor } = yield initNetMonitor(POST_RAW_WITH_HEADERS_URL);
info("Starting test... ");
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, 0, 1);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
// Wait for all tree view updated by react
wait = waitForDOM(document, "#headers-panel");
- EventUtils.sendMouseEvent({ type: "mousedown" },
+ EventUtils.sendMouseEvent({ type: "click" },
document.querySelector(".network-details-panel-toggle"));
- document.querySelector("#headers-tab").click();
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#headers-tab"));
yield wait;
let tabpanel = document.querySelector("#headers-panel");
is(tabpanel.querySelectorAll(".tree-section .treeLabel").length, 3,
"There should be 3 header sections displayed in this tabpanel.");
is(tabpanel.querySelectorAll(".tree-section .treeLabel")[2].textContent,
@@ -53,17 +54,18 @@ add_task(function* () {
"The first request header value was incorrect.");
is(labels[labels.length - 1].textContent, "custom-header",
"The second request header name was incorrect.");
is(values[values.length - 1].textContent, "\"hello world!\"",
"The second request header value was incorrect.");
// Wait for all tree sections updated by react
wait = waitForDOM(document, "#params-panel .tree-section");
- document.querySelector("#params-tab").click();
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#params-tab"));
yield wait;
tabpanel = document.querySelector("#params-panel");
ok(tabpanel.querySelector(".treeTable"),
"The params tree view should be displayed.");
ok(tabpanel.querySelector(".editor-mount") === null,
"The post data shouldn't be displayed.");
--- a/devtools/client/netmonitor/test/browser_net_post-data-04.js
+++ b/devtools/client/netmonitor/test/browser_net_post-data-04.js
@@ -9,32 +9,33 @@
*/
add_task(function* () {
let { L10N } = require("devtools/client/netmonitor/l10n");
let { tab, monitor } = yield initNetMonitor(POST_JSON_URL);
info("Starting test... ");
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, 0, 1);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
// Wait for all tree view updated by react
wait = waitForDOM(document, "#params-panel .tree-section");
- EventUtils.sendMouseEvent({ type: "mousedown" },
+ EventUtils.sendMouseEvent({ type: "click" },
document.querySelector(".network-details-panel-toggle"));
- document.querySelector("#params-tab").click();
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#params-tab"));
yield wait;
let tabpanel = document.querySelector("#params-panel");
ok(tabpanel.querySelector(".treeTable"),
"The request params doesn't have the indended visibility.");
ok(tabpanel.querySelector(".editor-mount") === null,
"The request post data doesn't have the indended visibility.");
--- a/devtools/client/netmonitor/test/browser_net_prefs-and-l10n.js
+++ b/devtools/client/netmonitor/test/browser_net_prefs-and-l10n.js
@@ -8,34 +8,32 @@
*/
add_task(function* () {
let { L10N } = require("devtools/client/netmonitor/l10n");
let { monitor } = yield initNetMonitor(SIMPLE_URL);
info("Starting test... ");
- ok(monitor.panelWin.Prefs,
- "Should have a preferences object available on the panel window.");
+ let { windowRequire } = monitor.panelWin;
+ let { Prefs } = windowRequire("devtools/client/netmonitor/prefs");
testL10N();
testPrefs();
return teardown(monitor);
function testL10N() {
is(typeof L10N.getStr("netmonitor.security.enabled"), "string",
"The getStr() method didn't return a valid string.");
is(typeof L10N.getFormatStr("networkMenu.totalMS", "foo"), "string",
"The getFormatStr() method didn't return a valid string.");
}
function testPrefs() {
- let { Prefs } = monitor.panelWin;
-
is(Prefs.networkDetailsWidth,
Services.prefs.getIntPref("devtools.netmonitor.panes-network-details-width"),
"Getting a pref should work correctly.");
let previousValue = Prefs.networkDetailsWidth;
let bogusValue = ~~(Math.random() * 100);
Prefs.networkDetailsWidth = bogusValue;
is(Prefs.networkDetailsWidth,
--- a/devtools/client/netmonitor/test/browser_net_raw_headers.js
+++ b/devtools/client/netmonitor/test/browser_net_raw_headers.js
@@ -6,39 +6,39 @@
/**
* Tests if showing raw headers works.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(POST_DATA_URL);
info("Starting test... ");
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let { getSortedRequests } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, 0, 2);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
- let origItem = RequestsMenu.getItemAtIndex(0);
-
wait = waitForDOM(document, ".headers-overview");
- RequestsMenu.selectedItem = origItem;
+ EventUtils.sendMouseEvent({ type: "mousedown" },
+ document.querySelectorAll(".request-list-item")[0]);
yield wait;
wait = waitForDOM(document, ".raw-headers-container textarea", 2);
EventUtils.sendMouseEvent({ type: "click" },
document.querySelectorAll(".headers-summary .tool-button")[1]);
yield wait;
- testShowRawHeaders(origItem);
+ testShowRawHeaders(getSortedRequests(gStore.getState()).get(0));
EventUtils.sendMouseEvent({ type: "click" },
document.querySelectorAll(".headers-summary .tool-button")[1]);
testHideRawHeaders(document);
return teardown(monitor);
--- a/devtools/client/netmonitor/test/browser_net_reload-button.js
+++ b/devtools/client/netmonitor/test/browser_net_reload-button.js
@@ -6,20 +6,20 @@
/**
* Tests if the empty-requests reload button works.
*/
add_task(function* () {
let { monitor } = yield initNetMonitor(SIMPLE_URL);
info("Starting test... ");
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document } = monitor.panelWin;
let wait = waitForNetworkEvents(monitor, 1);
- let button = document.querySelector("#requests-menu-reload-notice-button");
- button.click();
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#requests-menu-reload-notice-button"));
yield wait;
- is(RequestsMenu.itemCount, 1, "The request menu should have one item after reloading");
+ is(document.querySelectorAll(".request-list-item").length, 1,
+ "The request list should have one item after reloading");
return teardown(monitor);
});
--- a/devtools/client/netmonitor/test/browser_net_reload-markers.js
+++ b/devtools/client/netmonitor/test/browser_net_reload-markers.js
@@ -6,17 +6,18 @@
/**
* Tests if the empty-requests reload button works.
*/
add_task(function* () {
let { monitor } = yield initNetMonitor(SIMPLE_URL);
info("Starting test... ");
- let { document, EVENTS } = monitor.panelWin;
+ let { document, windowRequire } = monitor.panelWin;
+ let { EVENTS } = windowRequire("devtools/client/netmonitor/events");
let button = document.querySelector("#requests-menu-reload-notice-button");
button.click();
let markers = [];
monitor.panelWin.on(EVENTS.TIMELINE_EVENT, (_, marker) => {
markers.push(marker);
});
--- a/devtools/client/netmonitor/test/browser_net_req-resp-bodies.js
+++ b/devtools/client/netmonitor/test/browser_net_req-resp-bodies.js
@@ -8,20 +8,24 @@
*/
add_task(function* () {
let { L10N } = require("devtools/client/netmonitor/l10n");
let { tab, monitor } = yield initNetMonitor(JSON_LONG_URL);
info("Starting test... ");
- let { NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
// Perform first batch of requests.
let wait = waitForNetworkEvents(monitor, 1);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
@@ -48,19 +52,24 @@ add_task(function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
verifyRequest(1);
return teardown(monitor);
- function verifyRequest(offset) {
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(offset),
- "GET", CONTENT_TYPE_SJS + "?fmt=json-long", {
+ function verifyRequest(index) {
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(index),
+ "GET",
+ CONTENT_TYPE_SJS + "?fmt=json-long",
+ {
status: 200,
statusText: "OK",
type: "json",
fullMimeType: "text/json; charset=utf-8",
size: L10N.getFormatStr("networkMenu.sizeKB",
L10N.numberWithDecimals(85975 / 1024, 2)),
time: true
});
--- a/devtools/client/netmonitor/test/browser_net_resend.js
+++ b/devtools/client/netmonitor/test/browser_net_resend.js
@@ -11,53 +11,55 @@ const ADD_QUERY = "t1=t2";
const ADD_HEADER = "Test-header: true";
const ADD_UA_HEADER = "User-Agent: Custom-Agent";
const ADD_POSTDATA = "&t3=t4";
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(POST_DATA_URL);
info("Starting test... ");
- let { panelWin } = monitor;
- let { document, gStore, NetMonitorView, windowRequire } = panelWin;
+ let { document, gStore, windowRequire } = monitor.panelWin;
let Actions = windowRequire("devtools/client/netmonitor/actions/index");
- let { RequestsMenu } = NetMonitorView;
+ let {
+ getSelectedRequest,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, 0, 2);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
- let origItem = RequestsMenu.getItemAtIndex(0);
+ let origItem = getSortedRequests(gStore.getState()).get(0);
- RequestsMenu.selectedItem = origItem;
+ gStore.dispatch(Actions.selectRequest(origItem.id));
// add a new custom request cloned from selected request
gStore.dispatch(Actions.cloneSelectedRequest());
testCustomForm(origItem);
- let customItem = RequestsMenu.selectedItem;
+ let customItem = getSelectedRequest(gStore.getState());
testCustomItem(customItem, origItem);
// edit the custom request
yield editCustomForm();
// FIXME: reread the customItem, it's been replaced by a new object (immutable!)
- customItem = RequestsMenu.selectedItem;
+ customItem = getSelectedRequest(gStore.getState());
testCustomItemChanged(customItem, origItem);
// send the new request
wait = waitForNetworkEvents(monitor, 0, 1);
gStore.dispatch(Actions.sendCustomRequest());
yield wait;
- let sentItem = RequestsMenu.selectedItem;
+ let sentItem = getSelectedRequest(gStore.getState());
testSentRequest(sentItem, origItem);
return teardown(monitor);
function testCustomItem(item, orig) {
is(item.method, orig.method, "item is showing the same method as original request");
is(item.url, orig.url, "item is showing the same URL as original request");
}
@@ -68,16 +70,17 @@ add_task(function* () {
is(url, expectedUrl, "menu item is updated to reflect url entered in form");
}
/*
* Test that the New Request form was populated correctly
*/
function testCustomForm(data) {
+ yield waitUntil(() => document.querySelector(".custom-request-panel"));
is(document.getElementById("custom-method-value").value, data.method,
"new request form showing correct method");
is(document.getElementById("custom-url-value").value, data.url,
"new request form showing correct url");
let query = document.getElementById("custom-query-value");
is(query.value, "foo=bar\nbaz=42\ntype=urlencoded",
@@ -92,17 +95,17 @@ add_task(function* () {
is(postData.value, data.requestPostData.postData.text,
"new request form showing correct post data");
}
/*
* Add some params and headers to the request form
*/
function* editCustomForm() {
- panelWin.focus();
+ monitor.panelWin.focus();
let query = document.getElementById("custom-query-value");
let queryFocus = once(query, "focus", false);
// Bug 1195825: Due to some unexplained dark-matter with promise,
// focus only works if delayed by one tick.
executeSoon(() => query.focus());
yield queryFocus;
@@ -149,12 +152,12 @@ add_task(function* () {
is(data.requestPostData.postData.text,
origData.requestPostData.postData.text + ADD_POSTDATA,
"post data added to sent request");
}
function type(string) {
for (let ch of string) {
- EventUtils.synthesizeKey(ch, {}, panelWin);
+ EventUtils.synthesizeKey(ch, {}, monitor.panelWin);
}
}
});
--- a/devtools/client/netmonitor/test/browser_net_resend_cors.js
+++ b/devtools/client/netmonitor/test/browser_net_resend_cors.js
@@ -7,46 +7,49 @@
* Tests if resending a CORS request avoids the security checks and doesn't send
* a preflight OPTIONS request (bug 1270096 and friends)
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(CORS_URL);
info("Starting test... ");
- let { gStore, NetMonitorView, windowRequire } = monitor.panelWin;
+ let { document, gStore, windowRequire } = monitor.panelWin;
let Actions = windowRequire("devtools/client/netmonitor/actions/index");
- let { RequestsMenu } = NetMonitorView;
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let requestUrl = "http://test1.example.com" + CORS_SJS_PATH;
info("Waiting for OPTIONS, then POST");
let wait = waitForNetworkEvents(monitor, 1, 1);
yield ContentTask.spawn(tab.linkedBrowser, requestUrl, function* (url) {
content.wrappedJSObject.performRequests(url, "triggering/preflight", "post-data");
});
yield wait;
const METHODS = ["OPTIONS", "POST"];
- const ITEMS = METHODS.map((val, i) => RequestsMenu.getItemAtIndex(i));
+ const ITEMS = METHODS.map((val, i) => getSortedRequests(gStore.getState()).get(i));
// Check the requests that were sent
ITEMS.forEach((item, i) => {
is(item.method, METHODS[i], `The ${item.method} request has the right method`);
is(item.url, requestUrl, `The ${item.method} request has the right URL`);
});
// Resend both requests without modification. Wait for resent OPTIONS, then POST.
// POST is supposed to have no preflight OPTIONS request this time (CORS is disabled)
let onRequests = waitForNetworkEvents(monitor, 1, 0);
ITEMS.forEach((item) => {
info(`Selecting the ${item.method} request`);
- RequestsMenu.selectedItem = item;
+ gStore.dispatch(Actions.selectRequest(item.id))
info("Cloning the selected request into a custom clone");
gStore.dispatch(Actions.cloneSelectedRequest());
info("Sending the cloned request (without change)");
gStore.dispatch(Actions.sendCustomRequest());
});
--- a/devtools/client/netmonitor/test/browser_net_resend_headers.js
+++ b/devtools/client/netmonitor/test/browser_net_resend_headers.js
@@ -6,20 +6,24 @@
/**
* Test if custom request headers are not ignored (bug 1270096 and friends)
*/
add_task(function* () {
let { monitor } = yield initNetMonitor(SIMPLE_SJS);
info("Starting test... ");
- let { NetMonitorView, NetMonitorController } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire, NetMonitorController } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let requestUrl = SIMPLE_SJS;
let requestHeaders = [
{ name: "Host", value: "fakehost.example.com" },
{ name: "User-Agent", value: "Testzilla" },
{ name: "Referer", value: "http://example.com/referrer" },
{ name: "Accept", value: "application/jarda"},
{ name: "Accept-Encoding", value: "compress, identity, funcoding" },
@@ -30,17 +34,17 @@ add_task(function* () {
NetMonitorController.webConsoleClient.sendHTTPRequest({
url: requestUrl,
method: "POST",
headers: requestHeaders,
body: "Hello"
});
yield wait;
- let item = RequestsMenu.getItemAtIndex(0);
+ let item = getSortedRequests(gStore.getState()).get(0);
is(item.method, "POST", "The request has the right method");
is(item.url, requestUrl, "The request has the right URL");
for (let { name, value } of item.requestHeaders.headers) {
info(`Request header: ${name}: ${value}`);
}
function hasRequestHeader(name, value) {
--- a/devtools/client/netmonitor/test/browser_net_security-details.js
+++ b/devtools/client/netmonitor/test/browser_net_security-details.js
@@ -4,33 +4,34 @@
"use strict";
/**
* Test that Security details tab contains the expected data.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(CUSTOM_GET_URL);
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
info("Performing a secure request.");
const REQUESTS_URL = "https://example.com" + CORS_SJS_PATH;
let wait = waitForNetworkEvents(monitor, 1);
yield ContentTask.spawn(tab.linkedBrowser, REQUESTS_URL, function* (url) {
content.wrappedJSObject.performRequests(1, url);
});
yield wait;
wait = waitForDOM(document, "#security-panel");
- EventUtils.sendMouseEvent({ type: "mousedown" },
+ EventUtils.sendMouseEvent({ type: "click" },
document.querySelector(".network-details-panel-toggle"));
- document.querySelector("#security-tab").click();
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#security-tab"));
yield wait;
let tabpanel = document.querySelector("#security-panel");
let textboxes = tabpanel.querySelectorAll(".textbox-input");
// Connection
// The protocol will be TLS but the exact version depends on which protocol
// the test server example.com supports.
--- a/devtools/client/netmonitor/test/browser_net_security-error.js
+++ b/devtools/client/netmonitor/test/browser_net_security-error.js
@@ -4,32 +4,35 @@
"use strict";
/**
* Test that Security details tab shows an error message with broken connections.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(CUSTOM_GET_URL);
- let { document, EVENTS, NetMonitorView } = monitor.panelWin;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let { EVENTS } = windowRequire("devtools/client/netmonitor/events");
- NetMonitorView.RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
info("Requesting a resource that has a certificate problem.");
let wait = waitForSecurityBrokenNetworkEvent();
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests(1, "https://nocert.example.com");
});
yield wait;
wait = waitForDOM(document, "#security-panel");
- EventUtils.sendMouseEvent({ type: "mousedown" },
+ EventUtils.sendMouseEvent({ type: "click" },
document.querySelector(".network-details-panel-toggle"));
- document.querySelector("#security-tab").click();
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#security-tab"));
yield wait;
let errormsg = document.querySelector(".security-info-value");
isnot(errormsg.textContent, "", "Error message is not empty.");
return teardown(monitor);
/**
--- a/devtools/client/netmonitor/test/browser_net_security-icon-click.js
+++ b/devtools/client/netmonitor/test/browser_net_security-icon-click.js
@@ -4,55 +4,56 @@
"use strict";
/**
* Test that clicking on the security indicator opens the security details tab.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(CUSTOM_GET_URL);
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
info("Requesting a resource over HTTPS.");
yield performRequestAndWait("https://example.com" + CORS_SJS_PATH + "?request_2");
yield performRequestAndWait("https://example.com" + CORS_SJS_PATH + "?request_1");
- is(RequestsMenu.itemCount, 2, "Two events event logged.");
-console.log(123)
+ is(gStore.getState().requests.requests.size, 2, "Two events event logged.");
+
yield clickAndTestSecurityIcon();
-console.log(123)
info("Selecting headers panel again.");
- EventUtils.sendMouseEvent({ type: "mousedown" },
+ EventUtils.sendMouseEvent({ type: "click" },
document.querySelector("#headers-tab"));
info("Sorting the items by filename.");
EventUtils.sendMouseEvent({ type: "click" },
document.querySelector("#requests-menu-file-button"));
info("Testing that security icon can be clicked after the items were sorted.");
-console.log(123)
+
yield clickAndTestSecurityIcon();
-console.log(123)
return teardown(monitor);
function* performRequestAndWait(url) {
let wait = waitForNetworkEvents(monitor, 1);
yield ContentTask.spawn(tab.linkedBrowser, { url }, function* (args) {
content.wrappedJSObject.performRequests(1, args.url);
});
return wait;
}
function* clickAndTestSecurityIcon() {
- let item = RequestsMenu.getItemAtIndex(0);
let icon = document.querySelector(".requests-security-state-icon");
info("Clicking security icon of the first request and waiting for panel update.");
EventUtils.synthesizeMouseAtCenter(icon, {}, monitor.panelWin);
ok(document.querySelector("#security-tab[aria-selected=true]"), "Security tab is selected.");
}
});
--- a/devtools/client/netmonitor/test/browser_net_security-redirect.js
+++ b/devtools/client/netmonitor/test/browser_net_security-redirect.js
@@ -5,35 +5,38 @@
/**
* Test a http -> https redirect shows secure icon only for redirected https
* request.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(CUSTOM_GET_URL);
- let { $, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
- RequestsMenu.lazyUpdate = false;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
+
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, 2);
yield ContentTask.spawn(tab.linkedBrowser, HTTPS_REDIRECT_SJS, function* (url) {
content.wrappedJSObject.performRequests(1, url);
});
yield wait;
- is(RequestsMenu.itemCount, 2, "There were two requests due to redirect.");
-
- let initial = RequestsMenu.getItemAtIndex(0);
- let redirect = RequestsMenu.getItemAtIndex(1);
+ is(gStore.getState().requests.requests.size, 2, "There were two requests due to redirect.");
- let initialSecurityIcon =
- $(".requests-security-state-icon", getItemTarget(RequestsMenu, initial));
- let redirectSecurityIcon =
- $(".requests-security-state-icon", getItemTarget(RequestsMenu, redirect));
+ let initial = getSortedRequests(gStore.getState()).get(0);
+ let redirect = getSortedRequests(gStore.getState()).get(1);
+
+ let initialSecurityIcon = document.querySelectorAll(".requests-security-state-icon")[0];
+ let redirectSecurityIcon = document.querySelectorAll(".requests-security-state-icon")[1];
ok(initialSecurityIcon.classList.contains("security-state-insecure"),
"Initial request was marked insecure.");
ok(redirectSecurityIcon.classList.contains("security-state-secure"),
"Redirected request was marked secure.");
yield teardown(monitor);
--- a/devtools/client/netmonitor/test/browser_net_security-state.js
+++ b/devtools/client/netmonitor/test/browser_net_security-state.js
@@ -12,30 +12,35 @@ add_task(function* () {
const EXPECTED_SECURITY_STATES = {
"test1.example.com": "security-state-insecure",
"example.com": "security-state-secure",
"nocert.example.com": "security-state-broken",
"localhost": "security-state-local",
};
let { tab, monitor } = yield initNetMonitor(CUSTOM_GET_URL);
- let { $, EVENTS, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
- RequestsMenu.lazyUpdate = false;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
+
+ gStore.dispatch(Actions.batchEnable(false));
yield performRequests();
- for (let item of RequestsMenu.items) {
- let target = getItemTarget(RequestsMenu, item);
- let domain = $(".requests-menu-domain", target).textContent;
+ for (let subitemNode of Array.from(document.querySelectorAll(
+ "requests-menu-subitem.requests-menu-security-and-domain"))) {
+ let domain = subitemNode.querySelector(".requests-menu-domain").textContent;
info("Found a request to " + domain);
ok(domain in EXPECTED_SECURITY_STATES, "Domain " + domain + " was expected.");
- let classes = $(".requests-security-state-icon", target).classList;
+ let classes = subitemNode.querySelector(".requests-security-state-icon").classList;
let expectedClass = EXPECTED_SECURITY_STATES[domain];
info("Classes of security state icon are: " + classes);
info("Security state icon is expected to contain class: " + expectedClass);
ok(classes.contains(expectedClass), "Icon contained the correct class name.");
}
return teardown(monitor);
@@ -80,17 +85,19 @@ add_task(function* () {
yield done;
done = waitForSecurityBrokenNetworkEvent(true);
info("Requesting a resource over HTTP to localhost.");
yield executeRequests(1, "http://localhost" + CORS_SJS_PATH);
yield done;
const expectedCount = Object.keys(EXPECTED_SECURITY_STATES).length;
- is(RequestsMenu.itemCount, expectedCount, expectedCount + " events logged.");
+ is(gStore.getState().requests.requests.size,
+ expectedCount,
+ expectedCount + " events logged.");
}
/**
* Returns a promise that's resolved once a request with security issues is
* completed.
*/
function waitForSecurityBrokenNetworkEvent(networkError) {
let awaitedEvents = [
--- a/devtools/client/netmonitor/test/browser_net_security-tab-deselect.js
+++ b/devtools/client/netmonitor/test/browser_net_security-tab-deselect.js
@@ -5,20 +5,20 @@
/**
* Test that security details tab is no longer selected if an insecure request
* is selected.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(CUSTOM_GET_URL);
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
info("Performing requests.");
let wait = waitForNetworkEvents(monitor, 2);
const REQUEST_URLS = [
"https://example.com" + CORS_SJS_PATH,
"http://example.com" + CORS_SJS_PATH,
];
yield ContentTask.spawn(tab.linkedBrowser, REQUEST_URLS, function* (urls) {
--- a/devtools/client/netmonitor/test/browser_net_security-tab-visibility.js
+++ b/devtools/client/netmonitor/test/browser_net_security-tab-visibility.js
@@ -27,20 +27,21 @@ add_task(function* () {
isBroken: true,
visibleOnNewEvent: false,
visibleOnSecurityInfo: true,
visibleOnceComplete: true,
}
];
let { tab, monitor } = yield initNetMonitor(CUSTOM_GET_URL);
- let { document, EVENTS, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let { getSelectedRequest } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
for (let testcase of TEST_DATA) {
info("Testing Security tab visibility for " + testcase.desc);
let onNewItem = monitor.panelWin.once(EVENTS.NETWORK_EVENT);
let onSecurityInfo = monitor.panelWin.once(EVENTS.RECEIVED_SECURITY_INFO);
let onComplete = testcase.isBroken ?
waitForSecurityBrokenNetworkEvent() :
waitForNetworkEvents(monitor, 1);
@@ -49,42 +50,43 @@ add_task(function* () {
yield ContentTask.spawn(tab.linkedBrowser, testcase.uri, function* (url) {
content.wrappedJSObject.performRequests(1, url);
});
info("Waiting for new network event.");
yield onNewItem;
info("Selecting the request.");
- RequestsMenu.selectedIndex = 0;
+ EventUtils.sendMouseEvent({ type: "mousedown" },
+ document.querySelectorAll(".request-list-item")[0]);
- is(RequestsMenu.selectedItem.securityState, undefined,
+ is(getSelectedRequest(gStore.getState()).securityState, undefined,
"Security state has not yet arrived.");
is(!!document.querySelector("#security-tab"), testcase.visibleOnNewEvent,
"Security tab is " + (testcase.visibleOnNewEvent ? "visible" : "hidden") +
" after new request was added to the menu.");
info("Waiting for security information to arrive.");
yield onSecurityInfo;
- ok(RequestsMenu.selectedItem.securityState,
+ ok(getSelectedRequest(gStore.getState()).securityState,
"Security state arrived.");
is(!!document.querySelector("#security-tab"), testcase.visibleOnSecurityInfo,
"Security tab is " + (testcase.visibleOnSecurityInfo ? "visible" : "hidden") +
" after security information arrived.");
info("Waiting for request to complete.");
yield onComplete;
is(!!document.querySelector("#security-tab"), testcase.visibleOnceComplete,
"Security tab is " + (testcase.visibleOnceComplete ? "visible" : "hidden") +
" after request has been completed.");
info("Clearing requests.");
- RequestsMenu.clear();
+ gStore.dispatch(Actions.clearRequests());
}
return teardown(monitor);
/**
* Returns a promise that's resolved once a request with security issues is
* completed.
*/
--- a/devtools/client/netmonitor/test/browser_net_security-warnings.js
+++ b/devtools/client/netmonitor/test/browser_net_security-warnings.js
@@ -12,20 +12,20 @@ const TEST_CASES = [
desc: "no warnings",
uri: "https://example.com" + CORS_SJS_PATH,
warnCipher: null,
},
];
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(CUSTOM_GET_URL);
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
for (let test of TEST_CASES) {
info("Testing site with " + test.desc);
info("Performing request to " + test.uri);
let wait = waitForNetworkEvents(monitor, 1);
yield ContentTask.spawn(tab.linkedBrowser, test.uri, function* (url) {
content.wrappedJSObject.performRequests(1, url);
@@ -36,21 +36,22 @@ add_task(function* () {
wait = waitForDOM(document, ".tabs");
EventUtils.sendMouseEvent({ type: "mousedown" },
document.querySelectorAll(".request-list-item")[0]);
yield wait;
if (!document.querySelector("#security-tab[aria-selected=true]")) {
info("Selecting security tab.");
wait = waitForDOM(document, "#security-panel .properties-view");
- document.querySelector("#security-tab").click();
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#security-tab"));
yield wait;
}
is(document.querySelector("#security-warning-cipher"),
test.warnCipher,
"Cipher suite warning is hidden.");
- RequestsMenu.clear();
+ gStore.dispatch(Actions.clearRequests());
}
return teardown(monitor);
});
--- a/devtools/client/netmonitor/test/browser_net_send-beacon-other-tab.js
+++ b/devtools/client/netmonitor/test/browser_net_send-beacon-other-tab.js
@@ -4,31 +4,34 @@
"use strict";
/**
* Tests if beacons from other tabs are properly ignored.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(SIMPLE_URL);
- let { RequestsMenu } = monitor.panelWin.NetMonitorView;
- RequestsMenu.lazyUpdate = false;
+ let { gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let { getSortedRequests } = windowRequire("devtools/client/netmonitor/selectors/index");
+
+ gStore.dispatch(Actions.batchEnable(false));
let beaconTab = yield addTab(SEND_BEACON_URL);
info("Beacon tab added successfully.");
- is(RequestsMenu.itemCount, 0, "The requests menu should be empty.");
+ is(gStore.getState().requests.requests.size, 0, "The requests menu should be empty.");
let wait = waitForNetworkEvents(monitor, 1);
yield ContentTask.spawn(beaconTab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequest();
});
tab.linkedBrowser.reload();
yield wait;
- is(RequestsMenu.itemCount, 1, "Only the reload should be recorded.");
- let request = RequestsMenu.getItemAtIndex(0);
+ is(gStore.getState().requests.requests.size, 1, "Only the reload should be recorded.");
+ let request = getSortedRequests(gStore.getState()).get(0);
is(request.method, "GET", "The method is correct.");
is(request.status, "200", "The status is correct.");
yield removeTab(beaconTab);
return teardown(monitor);
});
--- a/devtools/client/netmonitor/test/browser_net_send-beacon.js
+++ b/devtools/client/netmonitor/test/browser_net_send-beacon.js
@@ -4,28 +4,30 @@
"use strict";
/**
* Tests if beacons are handled correctly.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(SEND_BEACON_URL);
- let { RequestsMenu } = monitor.panelWin.NetMonitorView;
+ let { gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let { getSortedRequests } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
- is(RequestsMenu.itemCount, 0, "The requests menu should be empty.");
+ is(gStore.getState().requests.requests.size, 0, "The requests menu should be empty.");
let wait = waitForNetworkEvents(monitor, 1);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequest();
});
yield wait;
- is(RequestsMenu.itemCount, 1, "The beacon should be recorded.");
- let request = RequestsMenu.getItemAtIndex(0);
+ is(gStore.getState().requests.requests.size, 1, "The beacon should be recorded.");
+ let request = getSortedRequests(gStore.getState()).get(0);
is(request.method, "POST", "The method is correct.");
ok(request.url.endsWith("beacon_request"), "The URL is correct.");
is(request.status, "404", "The status is correct.");
return teardown(monitor);
});
--- a/devtools/client/netmonitor/test/browser_net_service-worker-status.js
+++ b/devtools/client/netmonitor/test/browser_net_service-worker-status.js
@@ -11,18 +11,24 @@
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);
info("Starting test... ");
- let { NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
+
+ gStore.dispatch(Actions.batchEnable(false));
const REQUEST_DATA = [
{
method: "GET",
uri: URL + "service-workers/test/200",
details: {
status: 200,
statusText: "OK (service worker)",
@@ -43,21 +49,27 @@ add_task(function* () {
let wait = waitForNetworkEvents(monitor, REQUEST_DATA.length);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
let index = 0;
for (let request of REQUEST_DATA) {
- let item = RequestsMenu.getItemAtIndex(index);
+ let item = getSortedRequests(gStore.getState()).get(index);
info(`Verifying request #${index}`);
- yield verifyRequestItemTarget(RequestsMenu, item,
- request.method, request.uri, request.details);
+ yield verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ item,
+ request.method,
+ request.uri,
+ request.details
+ );
let { stacktrace } = item.cause;
let stackLen = stacktrace ? stacktrace.length : 0;
ok(stacktrace, `Request #${index} has a stacktrace`);
ok(stackLen >= request.stackFunctions.length,
`Request #${index} has a stacktrace with enough (${stackLen}) items`);
--- a/devtools/client/netmonitor/test/browser_net_simple-request-data.js
+++ b/devtools/client/netmonitor/test/browser_net_simple-request-data.js
@@ -8,34 +8,40 @@
*/
function test() {
let { L10N } = require("devtools/client/netmonitor/l10n");
initNetMonitor(SIMPLE_SJS).then(({ tab, monitor }) => {
info("Starting test... ");
- let { NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let { EVENTS } = windowRequire("devtools/client/netmonitor/events");
+ let {
+ getDisplayedRequests,
+ getSelectedRequest,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
waitForNetworkEvents(monitor, 1)
.then(() => teardown(monitor))
.then(finish);
- monitor.panelWin.once(monitor.panelWin.EVENTS.NETWORK_EVENT, () => {
- is(RequestsMenu.selectedItem, null,
+ monitor.panelWin.once(EVENTS.NETWORK_EVENT, () => {
+ is(getSelectedRequest(gStore.getState()), null,
"There shouldn't be any selected item in the requests menu.");
- is(RequestsMenu.itemCount, 1,
+ is(gStore.getState().requests.requests.size, 1,
"The requests menu should not be empty after the first request.");
is(!!document.querySelector(".network-details-panel"), false,
"The network details panel should still be hidden after first request.");
- let requestItem = RequestsMenu.getItemAtIndex(0);
+ let requestItem = getSortedRequests(gStore.getState()).get(0);
is(typeof requestItem.id, "string",
"The attached request id is incorrect.");
isnot(requestItem.id, "",
"The attached request id should not be empty.");
is(typeof requestItem.startedMillis, "number",
"The attached startedMillis is incorrect.");
@@ -63,156 +69,212 @@ function test() {
is(requestItem.headersSize, undefined,
"The headersSize should not yet be set.");
is(requestItem.transferredSize, undefined,
"The transferredSize should not yet be set.");
is(requestItem.contentSize, undefined,
"The contentSize should not yet be set.");
- is(requestItem.mimeType, undefined,
- "The mimeType should not yet be set.");
is(requestItem.responseContent, undefined,
"The responseContent should not yet be set.");
is(requestItem.totalTime, undefined,
"The totalTime should not yet be set.");
is(requestItem.eventTimings, undefined,
"The eventTimings should not yet be set.");
- verifyRequestItemTarget(RequestsMenu, requestItem, "GET", SIMPLE_SJS);
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ requestItem,
+ "GET",
+ SIMPLE_SJS
+ );
});
- monitor.panelWin.once(monitor.panelWin.EVENTS.RECEIVED_REQUEST_HEADERS, () => {
- let requestItem = RequestsMenu.getItemAtIndex(0);
+ monitor.panelWin.once(EVENTS.RECEIVED_REQUEST_HEADERS, () => {
+ let requestItem = getSortedRequests(gStore.getState()).get(0);
ok(requestItem.requestHeaders,
"There should be a requestHeaders data available.");
is(requestItem.requestHeaders.headers.length, 10,
"The requestHeaders data has an incorrect |headers| property.");
isnot(requestItem.requestHeaders.headersSize, 0,
"The requestHeaders data has an incorrect |headersSize| property.");
// Can't test for the exact request headers size because the value may
// vary across platforms ("User-Agent" header differs).
- verifyRequestItemTarget(requestItem, "GET", SIMPLE_SJS);
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ requestItem,
+ "GET",
+ SIMPLE_SJS
+ );
});
- monitor.panelWin.once(monitor.panelWin.EVENTS.RECEIVED_REQUEST_COOKIES, () => {
- let requestItem = RequestsMenu.getItemAtIndex(0);
+ monitor.panelWin.once(EVENTS.RECEIVED_REQUEST_COOKIES, () => {
+ let requestItem = getSortedRequests(gStore.getState()).get(0);
ok(requestItem.requestCookies,
"There should be a requestCookies data available.");
is(requestItem.requestCookies.cookies.length, 2,
"The requestCookies data has an incorrect |cookies| property.");
- verifyRequestItemTarget(RequestsMenu, requestItem, "GET", SIMPLE_SJS);
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ requestItem,
+ "GET",
+ SIMPLE_SJS
+ );
});
- monitor.panelWin.once(monitor.panelWin.EVENTS.RECEIVED_REQUEST_POST_DATA, () => {
+ monitor.panelWin.once(EVENTS.RECEIVED_REQUEST_POST_DATA, () => {
ok(false, "Trap listener: this request doesn't have any post data.");
});
- monitor.panelWin.once(monitor.panelWin.EVENTS.RECEIVED_RESPONSE_HEADERS, () => {
- let requestItem = RequestsMenu.getItemAtIndex(0);
+ monitor.panelWin.once(EVENTS.RECEIVED_RESPONSE_HEADERS, () => {
+ let requestItem = getSortedRequests(gStore.getState()).get(0);
ok(requestItem.responseHeaders,
"There should be a responseHeaders data available.");
is(requestItem.responseHeaders.headers.length, 10,
"The responseHeaders data has an incorrect |headers| property.");
is(requestItem.responseHeaders.headersSize, 330,
"The responseHeaders data has an incorrect |headersSize| property.");
- verifyRequestItemTarget(RequestsMenu, requestItem, "GET", SIMPLE_SJS);
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ requestItem,
+ "GET",
+ SIMPLE_SJS
+ );
});
- monitor.panelWin.once(monitor.panelWin.EVENTS.RECEIVED_RESPONSE_COOKIES, () => {
- let requestItem = RequestsMenu.getItemAtIndex(0);
+ monitor.panelWin.once(EVENTS.RECEIVED_RESPONSE_COOKIES, () => {
+ let requestItem = getSortedRequests(gStore.getState()).get(0);
ok(requestItem.responseCookies,
"There should be a responseCookies data available.");
is(requestItem.responseCookies.cookies.length, 2,
"The responseCookies data has an incorrect |cookies| property.");
- verifyRequestItemTarget(RequestsMenu, requestItem, "GET", SIMPLE_SJS);
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ requestItem,
+ "GET",
+ SIMPLE_SJS
+ );
});
- monitor.panelWin.once(monitor.panelWin.EVENTS.STARTED_RECEIVING_RESPONSE, () => {
- let requestItem = RequestsMenu.getItemAtIndex(0);
+ monitor.panelWin.once(EVENTS.STARTED_RECEIVING_RESPONSE, () => {
+ let requestItem = getSortedRequests(gStore.getState()).get(0);
is(requestItem.httpVersion, "HTTP/1.1",
"The httpVersion data has an incorrect value.");
is(requestItem.status, "200",
"The status data has an incorrect value.");
is(requestItem.statusText, "Och Aye",
"The statusText data has an incorrect value.");
is(requestItem.headersSize, 330,
"The headersSize data has an incorrect value.");
- verifyRequestItemTarget(RequestsMenu, requestItem, "GET", SIMPLE_SJS, {
- status: "200",
- statusText: "Och Aye"
- });
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ requestItem,
+ "GET",
+ SIMPLE_SJS,
+ {
+ status: "200",
+ statusText: "Och Aye"
+ }
+ );
});
- monitor.panelWin.once(monitor.panelWin.EVENTS.UPDATING_RESPONSE_CONTENT, () => {
- let requestItem = RequestsMenu.getItemAtIndex(0);
+ monitor.panelWin.once(EVENTS.UPDATING_RESPONSE_CONTENT, () => {
+ let requestItem = getSortedRequests(gStore.getState()).get(0);
is(requestItem.transferredSize, "12",
"The transferredSize data has an incorrect value.");
is(requestItem.contentSize, "12",
"The contentSize data has an incorrect value.");
is(requestItem.mimeType, "text/plain; charset=utf-8",
"The mimeType data has an incorrect value.");
- verifyRequestItemTarget(RequestsMenu, requestItem, "GET", SIMPLE_SJS, {
- type: "plain",
- fullMimeType: "text/plain; charset=utf-8",
- transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 12),
- size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 12),
- });
+ 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(monitor.panelWin.EVENTS.RECEIVED_RESPONSE_CONTENT, () => {
- let requestItem = RequestsMenu.getItemAtIndex(0);
+ monitor.panelWin.once(EVENTS.RECEIVED_RESPONSE_CONTENT, () => {
+ let requestItem = getSortedRequests(gStore.getState()).get(0);
ok(requestItem.responseContent,
"There should be a responseContent data available.");
is(requestItem.responseContent.content.mimeType,
"text/plain; charset=utf-8",
"The responseContent data has an incorrect |content.mimeType| property.");
is(requestItem.responseContent.content.text,
"Hello world!",
"The responseContent data has an incorrect |content.text| property.");
is(requestItem.responseContent.content.size,
12,
"The responseContent data has an incorrect |content.size| property.");
- verifyRequestItemTarget(RequestsMenu, requestItem, "GET", SIMPLE_SJS, {
- type: "plain",
- fullMimeType: "text/plain; charset=utf-8",
- transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 12),
- size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 12),
- });
+ 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(monitor.panelWin.EVENTS.UPDATING_EVENT_TIMINGS, () => {
- let requestItem = RequestsMenu.getItemAtIndex(0);
+ monitor.panelWin.once(EVENTS.UPDATING_EVENT_TIMINGS, () => {
+ let requestItem = getSortedRequests(gStore.getState()).get(0);
is(typeof requestItem.totalTime, "number",
"The attached totalTime is incorrect.");
ok(requestItem.totalTime >= 0,
"The attached totalTime should be positive.");
- verifyRequestItemTarget(RequestsMenu, requestItem, "GET", SIMPLE_SJS, {
- time: true
- });
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ requestItem,
+ "GET",
+ SIMPLE_SJS,
+ {
+ time: true
+ }
+ );
});
- monitor.panelWin.once(monitor.panelWin.EVENTS.RECEIVED_EVENT_TIMINGS, () => {
- let requestItem = RequestsMenu.getItemAtIndex(0);
+ monitor.panelWin.once(EVENTS.RECEIVED_EVENT_TIMINGS, () => {
+ let requestItem = getSortedRequests(gStore.getState()).get(0);
ok(requestItem.eventTimings,
"There should be a eventTimings data available.");
is(typeof requestItem.eventTimings.timings.blocked, "number",
"The eventTimings data has an incorrect |timings.blocked| property.");
is(typeof requestItem.eventTimings.timings.dns, "number",
"The eventTimings data has an incorrect |timings.dns| property.");
is(typeof requestItem.eventTimings.timings.connect, "number",
@@ -221,16 +283,23 @@ function test() {
"The eventTimings data has an incorrect |timings.send| property.");
is(typeof requestItem.eventTimings.timings.wait, "number",
"The eventTimings data has an incorrect |timings.wait| property.");
is(typeof requestItem.eventTimings.timings.receive, "number",
"The eventTimings data has an incorrect |timings.receive| property.");
is(typeof requestItem.eventTimings.totalTime, "number",
"The eventTimings data has an incorrect |totalTime| property.");
- verifyRequestItemTarget(RequestsMenu, requestItem, "GET", SIMPLE_SJS, {
- time: true
- });
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ requestItem,
+ "GET",
+ SIMPLE_SJS,
+ {
+ time: true
+ }
+ );
});
tab.linkedBrowser.reload();
});
}
--- a/devtools/client/netmonitor/test/browser_net_simple-request-details.js
+++ b/devtools/client/netmonitor/test/browser_net_simple-request-details.js
@@ -8,50 +8,61 @@
*/
add_task(function* () {
let { L10N } = require("devtools/client/netmonitor/l10n");
let { tab, monitor } = yield initNetMonitor(SIMPLE_SJS);
info("Starting test... ");
- let { document, EVENTS, Editor, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
- RequestsMenu.lazyUpdate = false;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let { EVENTS } = windowRequire("devtools/client/netmonitor/events");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
+
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, 1);
tab.linkedBrowser.reload();
yield wait;
- is(RequestsMenu.selectedItem, null,
+ is(getSelectedRequest(gStore.getState()), undefined,
"There shouldn't be any selected item in the requests menu.");
- is(RequestsMenu.itemCount, 1,
+ is(gStore.getState().requests.requests.size, 1,
"The requests menu should not be empty after the first request.");
is(!!document.querySelector(".network-details-panel"), false,
"The network details panel should still be hidden after first request.");
- let onTabUpdated = monitor.panelWin.once(EVENTS.TAB_UPDATED);
- EventUtils.sendMouseEvent({ type: "mousedown" },
+ EventUtils.sendMouseEvent({ type: "click" },
document.querySelector(".network-details-panel-toggle"));
- yield onTabUpdated;
- isnot(RequestsMenu.selectedItem, null,
+ isnot(getSelectedRequest(gStore.getState()), undefined,
"There should be a selected item in the requests menu.");
- is(RequestsMenu.selectedIndex, 0,
+ is(getSelectedIndex(gStore.getState()), 0,
"The first item should be selected in the requests menu.");
is(!!document.querySelector(".network-details-panel"), true,
"The network details panel should not be hidden after toggle button was pressed.");
testHeadersTab();
yield testCookiesTab();
testParamsTab();
yield testResponseTab();
testTimingsTab();
return teardown(monitor);
+ function getSelectedIndex(state) {
+ if (!state.requests.selectedId) {
+ return -1;
+ }
+ return getSortedRequests(state).findIndex(r => r.id === state.requests.selectedId);
+ }
+
function testHeadersTab() {
let tabEl = document.querySelectorAll("#details-pane tab")[0];
let tabpanel = document.querySelectorAll("#details-pane tabpanel")[0];
is(tabEl.getAttribute("selected"), "true",
"The headers tab in the network details pane should be selected.");
is(tabpanel.querySelector("#headers-summary-url-value").getAttribute("value"),
--- a/devtools/client/netmonitor/test/browser_net_simple-request.js
+++ b/devtools/client/netmonitor/test/browser_net_simple-request.js
@@ -11,63 +11,68 @@
* 2) Side panel toggle button
* 3) Empty user message visibility
* 4) Number of requests displayed
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(SIMPLE_URL);
info("Starting test... ");
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let { EVENTS } = windowRequire("devtools/client/netmonitor/events");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
is(document.querySelector(".network-details-panel-toggle").hasAttribute("disabled"),
true,
"The pane toggle button should be disabled when the frontend is opened.");
ok(document.querySelector("#requests-menu-empty-notice"),
"An empty notice should be displayed when the frontend is opened.");
- is(RequestsMenu.itemCount, 0,
+ is(gStore.getState().requests.requests.size, 0,
"The requests menu should be empty when the frontend is opened.");
is(!!document.querySelector(".network-details-panel"), false,
"The network details panel should be hidden when the frontend is opened.");
yield reloadAndWait();
is(document.querySelector(".network-details-panel-toggle").hasAttribute("disabled"),
false,
"The pane toggle button should be enabled after the first request.");
ok(!document.querySelector("#requests-menu-empty-notice"),
"The empty notice should be hidden after the first request.");
- is(RequestsMenu.itemCount, 1,
+ is(gStore.getState().requests.requests.size, 1,
"The requests menu should not be empty after the first request.");
is(!!document.querySelector(".network-details-panel"), false,
"The network details panel should still be hidden after the first request.");
yield reloadAndWait();
is(document.querySelector(".network-details-panel-toggle").hasAttribute("disabled"),
false,
"The pane toggle button should be still be enabled after a reload.");
ok(!document.querySelector("#requests-menu-empty-notice"),
"The empty notice should be still hidden after a reload.");
- is(RequestsMenu.itemCount, 1,
+ is(gStore.getState().requests.requests.size, 1,
"The requests menu should not be empty after a reload.");
is(!!document.querySelector(".network-details-panel"), false,
"The network details panel should still be hidden after a reload.");
- RequestsMenu.clear();
+ gStore.dispatch(Actions.clearRequests());
is(document.querySelector(".network-details-panel-toggle").hasAttribute("disabled"),
true,
"The pane toggle button should be disabled when after clear.");
ok(document.querySelector("#requests-menu-empty-notice"),
"An empty notice should be displayed again after clear.");
- is(RequestsMenu.itemCount, 0,
+ is(gStore.getState().requests.requests.size, 0,
"The requests menu should be empty after clear.");
is(!!document.querySelector(".network-details-panel"), false,
"The network details panel should still be hidden after clear.");
return teardown(monitor);
function* reloadAndWait() {
let wait = waitForNetworkEvents(monitor, 1);
--- a/devtools/client/netmonitor/test/browser_net_sort-01.js
+++ b/devtools/client/netmonitor/test/browser_net_sort-01.js
@@ -1,219 +1,236 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
- * Test if the sorting mechanism works correctly.
+ * Test if sorting columns in the network table works correctly with new requests.
*/
add_task(function* () {
let { L10N } = require("devtools/client/netmonitor/l10n");
- let { tab, monitor } = yield initNetMonitor(STATUS_CODES_URL);
+ let { monitor } = yield initNetMonitor(SORTING_URL);
info("Starting test... ");
- let { $all, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ // It seems that this test may be slow on debug builds. This could be because
+ // of the heavy dom manipulation associated with sorting.
+ requestLongerTimeout(2);
+
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSelectedRequest,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
+
+ gStore.dispatch(Actions.batchEnable(false));
- RequestsMenu.lazyUpdate = false;
+ // Loading the frame script and preparing the xhr request URLs so we can
+ // generate some requests later.
+ loadCommonFrameScript();
+ let requests = [{
+ url: "sjs_sorting-test-server.sjs?index=1&" + Math.random(),
+ method: "GET1"
+ }, {
+ url: "sjs_sorting-test-server.sjs?index=5&" + Math.random(),
+ method: "GET5"
+ }, {
+ url: "sjs_sorting-test-server.sjs?index=2&" + Math.random(),
+ method: "GET2"
+ }, {
+ url: "sjs_sorting-test-server.sjs?index=4&" + Math.random(),
+ method: "GET4"
+ }, {
+ url: "sjs_sorting-test-server.sjs?index=3&" + Math.random(),
+ method: "GET3"
+ }];
let wait = waitForNetworkEvents(monitor, 5);
- yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
- content.wrappedJSObject.performRequests();
- });
+ yield performRequestsInContent(requests);
yield wait;
- testContents([0, 1, 2, 3, 4]);
-
- info("Testing swap(0, 0)");
- RequestsMenu.swapItemsAtIndices(0, 0);
- RequestsMenu.refreshZebra();
- testContents([0, 1, 2, 3, 4]);
-
- info("Testing swap(0, 1)");
- RequestsMenu.swapItemsAtIndices(0, 1);
- RequestsMenu.refreshZebra();
- testContents([1, 0, 2, 3, 4]);
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector(".network-details-panel-toggle"));
- info("Testing swap(0, 2)");
- RequestsMenu.swapItemsAtIndices(0, 2);
- RequestsMenu.refreshZebra();
- testContents([1, 2, 0, 3, 4]);
-
- info("Testing swap(0, 3)");
- RequestsMenu.swapItemsAtIndices(0, 3);
- RequestsMenu.refreshZebra();
- testContents([1, 2, 3, 0, 4]);
-
- info("Testing swap(0, 4)");
- RequestsMenu.swapItemsAtIndices(0, 4);
- RequestsMenu.refreshZebra();
- testContents([1, 2, 3, 4, 0]);
+ isnot(getSelectedRequest(gStore.getState()), undefined,
+ "There should be a selected item in the requests menu.");
+ is(getSelectedIndex(gStore.getState()), 0,
+ "The first item should be selected in the requests menu.");
+ is(!!document.querySelector(".network-details-panel"), true,
+ "The network details panel should be visible after toggle button was pressed.");
- info("Testing swap(1, 0)");
- RequestsMenu.swapItemsAtIndices(1, 0);
- RequestsMenu.refreshZebra();
- testContents([0, 2, 3, 4, 1]);
-
- info("Testing swap(1, 1)");
- RequestsMenu.swapItemsAtIndices(1, 1);
- RequestsMenu.refreshZebra();
- testContents([0, 2, 3, 4, 1]);
-
- info("Testing swap(1, 2)");
- RequestsMenu.swapItemsAtIndices(1, 2);
- RequestsMenu.refreshZebra();
- testContents([0, 1, 3, 4, 2]);
+ testHeaders();
+ testContents([0, 2, 4, 3, 1], 0);
- info("Testing swap(1, 3)");
- RequestsMenu.swapItemsAtIndices(1, 3);
- RequestsMenu.refreshZebra();
- testContents([0, 3, 1, 4, 2]);
-
- info("Testing swap(1, 4)");
- RequestsMenu.swapItemsAtIndices(1, 4);
- RequestsMenu.refreshZebra();
- testContents([0, 3, 4, 1, 2]);
+ info("Testing status sort, ascending.");
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#requests-menu-status-button"));
+ testHeaders("status", "ascending");
+ testContents([0, 1, 2, 3, 4], 0);
- info("Testing swap(2, 0)");
- RequestsMenu.swapItemsAtIndices(2, 0);
- RequestsMenu.refreshZebra();
- testContents([2, 3, 4, 1, 0]);
-
- info("Testing swap(2, 1)");
- RequestsMenu.swapItemsAtIndices(2, 1);
- RequestsMenu.refreshZebra();
- testContents([1, 3, 4, 2, 0]);
+ info("Performing more requests.");
+ wait = waitForNetworkEvents(monitor, 5);
+ yield performRequestsInContent(requests);
+ yield wait;
- info("Testing swap(2, 2)");
- RequestsMenu.swapItemsAtIndices(2, 2);
- RequestsMenu.refreshZebra();
- testContents([1, 3, 4, 2, 0]);
-
- info("Testing swap(2, 3)");
- RequestsMenu.swapItemsAtIndices(2, 3);
- RequestsMenu.refreshZebra();
- testContents([1, 2, 4, 3, 0]);
-
- info("Testing swap(2, 4)");
- RequestsMenu.swapItemsAtIndices(2, 4);
- RequestsMenu.refreshZebra();
- testContents([1, 4, 2, 3, 0]);
+ info("Testing status sort again, ascending.");
+ testHeaders("status", "ascending");
+ testContents([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 0);
- info("Testing swap(3, 0)");
- RequestsMenu.swapItemsAtIndices(3, 0);
- RequestsMenu.refreshZebra();
- testContents([1, 4, 2, 0, 3]);
+ info("Testing status sort, descending.");
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#requests-menu-status-button"));
+ testHeaders("status", "descending");
+ testContents([9, 8, 7, 6, 5, 4, 3, 2, 1, 0], 9);
- info("Testing swap(3, 1)");
- RequestsMenu.swapItemsAtIndices(3, 1);
- RequestsMenu.refreshZebra();
- testContents([3, 4, 2, 0, 1]);
-
- info("Testing swap(3, 2)");
- RequestsMenu.swapItemsAtIndices(3, 2);
- RequestsMenu.refreshZebra();
- testContents([2, 4, 3, 0, 1]);
+ info("Performing more requests.");
+ wait = waitForNetworkEvents(monitor, 5);
+ yield performRequestsInContent(requests);
+ yield wait;
- info("Testing swap(3, 3)");
- RequestsMenu.swapItemsAtIndices(3, 3);
- RequestsMenu.refreshZebra();
- testContents([2, 4, 3, 0, 1]);
-
- info("Testing swap(3, 4)");
- RequestsMenu.swapItemsAtIndices(3, 4);
- RequestsMenu.refreshZebra();
- testContents([2, 3, 4, 0, 1]);
-
- info("Testing swap(4, 0)");
- RequestsMenu.swapItemsAtIndices(4, 0);
- RequestsMenu.refreshZebra();
- testContents([2, 3, 0, 4, 1]);
+ info("Testing status sort again, descending.");
+ testHeaders("status", "descending");
+ testContents([14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0], 14);
- info("Testing swap(4, 1)");
- RequestsMenu.swapItemsAtIndices(4, 1);
- RequestsMenu.refreshZebra();
- testContents([2, 3, 0, 1, 4]);
-
- info("Testing swap(4, 2)");
- RequestsMenu.swapItemsAtIndices(4, 2);
- RequestsMenu.refreshZebra();
- testContents([4, 3, 0, 1, 2]);
+ info("Testing status sort yet again, ascending.");
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#requests-menu-status-button"));
+ testHeaders("status", "ascending");
+ testContents([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], 0);
- info("Testing swap(4, 3)");
- RequestsMenu.swapItemsAtIndices(4, 3);
- RequestsMenu.refreshZebra();
- testContents([3, 4, 0, 1, 2]);
-
- info("Testing swap(4, 4)");
- RequestsMenu.swapItemsAtIndices(4, 4);
- RequestsMenu.refreshZebra();
- testContents([3, 4, 0, 1, 2]);
-
- info("Clearing sort.");
- RequestsMenu.sortBy();
- testContents([0, 1, 2, 3, 4]);
+ info("Testing status sort yet again, descending.");
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#requests-menu-status-button"));
+ testHeaders("status", "descending");
+ testContents([14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0], 14);
return teardown(monitor);
- function testContents([a, b, c, d, e]) {
- is(RequestsMenu.items.length, 5,
- "There should be a total of 5 items in the requests menu.");
- is(RequestsMenu.visibleItems.length, 5,
- "There should be a total of 5 visbile items in the requests menu.");
- is($all(".request-list-item").length, 5,
+ function testHeaders(sortType, direction) {
+ let doc = monitor.panelWin.document;
+ let target = doc.querySelector("#requests-menu-" + sortType + "-button");
+ let headers = doc.querySelectorAll(".requests-menu-header-button");
+
+ for (let header of headers) {
+ if (header != target) {
+ ok(!header.hasAttribute("data-sorted"),
+ "The " + header.id + " header does not have a 'data-sorted' attribute.");
+ ok(!header.getAttribute("title"),
+ "The " + header.id + " header does not have a 'title' attribute.");
+ } else {
+ is(header.getAttribute("data-sorted"), direction,
+ "The " + header.id + " header has a correct 'data-sorted' attribute.");
+ is(header.getAttribute("title"), direction == "ascending"
+ ? L10N.getStr("networkMenu.sortedAsc")
+ : L10N.getStr("networkMenu.sortedDesc"),
+ "The " + header.id + " header has a correct 'title' attribute.");
+ }
+ }
+ }
+
+ function getSelectedIndex(state) {
+ if (!state.requests.selectedId) {
+ return -1;
+ }
+ return getSortedRequests(state).findIndex(r => r.id === state.requests.selectedId);
+ }
+
+ function testContents(order, selection) {
+ isnot(getSelectedRequest(gStore.getState()), undefined,
+ "There should still be a selected item after sorting.");
+ is(getSelectedIndex(gStore.getState()), selection,
+ "The first item should be still selected after sorting.");
+ is(!!document.querySelector(".network-details-panel"), true,
+ "The network details panel should still be visible after sorting.");
+
+ is(getSortedRequests(gStore.getState()).length, order.length,
+ "There should be a specific number of items in the requests menu.");
+ is(getDisplayedRequests(gStore.getState()).length, order.length,
+ "There should be a specific number of visbile items in the requests menu.");
+ is(document.querySelectorAll(".request-list-item").length, order.length,
"The visible items in the requests menu are, in fact, visible!");
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(a),
- "GET", STATUS_CODES_SJS + "?sts=100", {
- status: 101,
- statusText: "Switching Protocols",
- type: "plain",
- fullMimeType: "text/plain; charset=utf-8",
- transferred: L10N.getStr("networkMenu.sizeUnavailable"),
- size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 0),
- time: true
- });
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(b),
- "GET", STATUS_CODES_SJS + "?sts=200", {
- status: 202,
- statusText: "Created",
- type: "plain",
- fullMimeType: "text/plain; charset=utf-8",
- transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 22),
- size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 22),
- time: true
- });
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(c),
- "GET", STATUS_CODES_SJS + "?sts=300", {
- status: 303,
- statusText: "See Other",
- type: "plain",
- fullMimeType: "text/plain; charset=utf-8",
- transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 22),
- size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 0),
- time: true
- });
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(d),
- "GET", STATUS_CODES_SJS + "?sts=400", {
- status: 404,
- statusText: "Not Found",
- type: "plain",
- fullMimeType: "text/plain; charset=utf-8",
- transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 22),
- size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 22),
- time: true
- });
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(e),
- "GET", STATUS_CODES_SJS + "?sts=500", {
- status: 501,
- statusText: "Not Implemented",
- type: "plain",
- fullMimeType: "text/plain; charset=utf-8",
- transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 22),
- size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 22),
- time: true
- });
+ for (let i = 0, len = order.length / 5; i < len; i++) {
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(order[i]),
+ "GET1", SORTING_SJS + "?index=1", {
+ fuzzyUrl: true,
+ status: 101,
+ statusText: "Meh",
+ type: "1",
+ fullMimeType: "text/1",
+ transferred: L10N.getStr("networkMenu.sizeUnavailable"),
+ size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 0),
+ time: true
+ });
+ }
+ for (let i = 0, len = order.length / 5; i < len; i++) {
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(order[i + len]),
+ "GET2", SORTING_SJS + "?index=2", {
+ fuzzyUrl: true,
+ status: 200,
+ statusText: "Meh",
+ type: "2",
+ fullMimeType: "text/2",
+ transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 19),
+ size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 19),
+ time: true
+ });
+ }
+ for (let i = 0, len = order.length / 5; i < len; i++) {
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(order[i + len * 2]),
+ "GET3", SORTING_SJS + "?index=3", {
+ fuzzyUrl: true,
+ status: 300,
+ statusText: "Meh",
+ type: "3",
+ fullMimeType: "text/3",
+ transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 29),
+ size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 29),
+ time: true
+ });
+ }
+ for (let i = 0, len = order.length / 5; i < len; i++) {
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(order[i + len * 3]),
+ "GET4", SORTING_SJS + "?index=4", {
+ fuzzyUrl: true,
+ status: 400,
+ statusText: "Meh",
+ type: "4",
+ fullMimeType: "text/4",
+ transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 39),
+ size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 39),
+ time: true
+ });
+ }
+ for (let i = 0, len = order.length / 5; i < len; i++) {
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(order[i + len * 4]),
+ "GET5", SORTING_SJS + "?index=5", {
+ fuzzyUrl: true,
+ status: 500,
+ statusText: "Meh",
+ type: "5",
+ fullMimeType: "text/5",
+ transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 49),
+ size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 49),
+ time: true
+ });
+ }
}
});
--- a/devtools/client/netmonitor/test/browser_net_sort-02.js
+++ b/devtools/client/netmonitor/test/browser_net_sort-02.js
@@ -12,18 +12,25 @@ add_task(function* () {
let { monitor } = yield initNetMonitor(SORTING_URL);
info("Starting test... ");
// It seems that this test may be slow on debug builds. This could be because
// of the heavy dom manipulation associated with sorting.
requestLongerTimeout(2);
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSelectedRequest,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
+
+ gStore.dispatch(Actions.batchEnable(false));
// Loading the frame script and preparing the xhr request URLs so we can
// generate some requests later.
loadCommonFrameScript();
let requests = [{
url: "sjs_sorting-test-server.sjs?index=1&" + Math.random(),
method: "GET1"
}, {
@@ -35,28 +42,26 @@ add_task(function* () {
}, {
url: "sjs_sorting-test-server.sjs?index=4&" + Math.random(),
method: "GET4"
}, {
url: "sjs_sorting-test-server.sjs?index=3&" + Math.random(),
method: "GET3"
}];
- RequestsMenu.lazyUpdate = false;
-
let wait = waitForNetworkEvents(monitor, 5);
yield performRequestsInContent(requests);
yield wait;
- EventUtils.sendMouseEvent({ type: "mousedown" },
+ EventUtils.sendMouseEvent({ type: "click" },
document.querySelector(".network-details-panel-toggle"));
- isnot(RequestsMenu.selectedItem, null,
+ isnot(getSelectedRequest(gStore.getState()), undefined,
"There should be a selected item in the requests menu.");
- is(RequestsMenu.selectedIndex, 0,
+ is(getSelectedIndex(gStore.getState()), 0,
"The first item should be selected in the requests menu.");
is(!!document.querySelector(".network-details-panel"), true,
"The network details panel should be visible after toggle button was pressed.");
testHeaders();
testContents([0, 2, 4, 3, 1]);
info("Testing status sort, ascending.");
@@ -182,16 +187,23 @@ add_task(function* () {
info("Testing waterfall sort, ascending. Checking sort loops correctly.");
EventUtils.sendMouseEvent({ type: "click" },
document.querySelector("#requests-menu-waterfall-button"));
testHeaders("waterfall", "ascending");
testContents([0, 2, 4, 3, 1]);
return teardown(monitor);
+ function getSelectedIndex(state) {
+ if (!state.requests.selectedId) {
+ return -1;
+ }
+ return getSortedRequests(state).findIndex(r => r.id === state.requests.selectedId);
+ }
+
function testHeaders(sortType, direction) {
let doc = monitor.panelWin.document;
let target = doc.querySelector("#requests-menu-" + sortType + "-button");
let headers = doc.querySelectorAll(".requests-menu-header-button");
for (let header of headers) {
if (header != target) {
ok(!header.hasAttribute("data-sorted"),
@@ -205,75 +217,90 @@ add_task(function* () {
? L10N.getStr("networkMenu.sortedAsc")
: L10N.getStr("networkMenu.sortedDesc"),
"The " + header.id + " header has a correct 'title' attribute.");
}
}
}
function testContents([a, b, c, d, e]) {
- isnot(RequestsMenu.selectedItem, null,
+ isnot(getSelectedRequest(gStore.getState()), undefined,
"There should still be a selected item after sorting.");
- is(RequestsMenu.selectedIndex, a,
+ is(getSelectedIndex(gStore.getState()), a,
"The first item should be still selected after sorting.");
is(!!document.querySelector(".network-details-panel"), true,
"The network details panel should still be visible after sorting.");
- is(RequestsMenu.items.length, 5,
+ is(getSortedRequests(gStore.getState()).length, 5,
"There should be a total of 5 items in the requests menu.");
- is(RequestsMenu.visibleItems.length, 5,
+ is(getDisplayedRequests(gStore.getState()).length, 5,
"There should be a total of 5 visible items in the requests menu.");
is(document.querySelectorAll(".request-list-item").length, 5,
"The visible items in the requests menu are, in fact, visible!");
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(a),
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(a),
"GET1", SORTING_SJS + "?index=1", {
fuzzyUrl: true,
status: 101,
statusText: "Meh",
type: "1",
fullMimeType: "text/1",
transferred: L10N.getStr("networkMenu.sizeUnavailable"),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 0),
time: true
});
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(b),
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(b),
"GET2", SORTING_SJS + "?index=2", {
fuzzyUrl: true,
status: 200,
statusText: "Meh",
type: "2",
fullMimeType: "text/2",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 19),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 19),
time: true
});
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(c),
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(c),
"GET3", SORTING_SJS + "?index=3", {
fuzzyUrl: true,
status: 300,
statusText: "Meh",
type: "3",
fullMimeType: "text/3",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 29),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 29),
time: true
});
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(d),
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(d),
"GET4", SORTING_SJS + "?index=4", {
fuzzyUrl: true,
status: 400,
statusText: "Meh",
type: "4",
fullMimeType: "text/4",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 39),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 39),
time: true
});
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(e),
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(e),
"GET5", SORTING_SJS + "?index=5", {
fuzzyUrl: true,
status: 500,
statusText: "Meh",
type: "5",
fullMimeType: "text/5",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 49),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 49),
deleted file mode 100644
--- a/devtools/client/netmonitor/test/browser_net_sort-03.js
+++ /dev/null
@@ -1,214 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-/**
- * Test if sorting columns in the network table works correctly with new requests.
- */
-
-add_task(function* () {
- let { L10N } = require("devtools/client/netmonitor/l10n");
-
- let { monitor } = yield initNetMonitor(SORTING_URL);
- info("Starting test... ");
-
- // It seems that this test may be slow on debug builds. This could be because
- // of the heavy dom manipulation associated with sorting.
- requestLongerTimeout(2);
-
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
-
- // Loading the frame script and preparing the xhr request URLs so we can
- // generate some requests later.
- loadCommonFrameScript();
- let requests = [{
- url: "sjs_sorting-test-server.sjs?index=1&" + Math.random(),
- method: "GET1"
- }, {
- url: "sjs_sorting-test-server.sjs?index=5&" + Math.random(),
- method: "GET5"
- }, {
- url: "sjs_sorting-test-server.sjs?index=2&" + Math.random(),
- method: "GET2"
- }, {
- url: "sjs_sorting-test-server.sjs?index=4&" + Math.random(),
- method: "GET4"
- }, {
- url: "sjs_sorting-test-server.sjs?index=3&" + Math.random(),
- method: "GET3"
- }];
-
- RequestsMenu.lazyUpdate = false;
-
- let wait = waitForNetworkEvents(monitor, 5);
- yield performRequestsInContent(requests);
- yield wait;
-
- EventUtils.sendMouseEvent({ type: "mousedown" },
- document.querySelector(".network-details-panel-toggle"));
-
- isnot(RequestsMenu.selectedItem, null,
- "There should be a selected item in the requests menu.");
- is(RequestsMenu.selectedIndex, 0,
- "The first item should be selected in the requests menu.");
- is(!!document.querySelector(".network-details-panel"), true,
- "The network details panel should be visible after toggle button was pressed.");
-
- testHeaders();
- testContents([0, 2, 4, 3, 1], 0);
-
- info("Testing status sort, ascending.");
- EventUtils.sendMouseEvent({ type: "click" },
- document.querySelector("#requests-menu-status-button"));
- testHeaders("status", "ascending");
- testContents([0, 1, 2, 3, 4], 0);
-
- info("Performing more requests.");
- wait = waitForNetworkEvents(monitor, 5);
- yield performRequestsInContent(requests);
- yield wait;
-
- info("Testing status sort again, ascending.");
- testHeaders("status", "ascending");
- testContents([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 0);
-
- info("Testing status sort, descending.");
- EventUtils.sendMouseEvent({ type: "click" },
- document.querySelector("#requests-menu-status-button"));
- testHeaders("status", "descending");
- testContents([9, 8, 7, 6, 5, 4, 3, 2, 1, 0], 9);
-
- info("Performing more requests.");
- wait = waitForNetworkEvents(monitor, 5);
- yield performRequestsInContent(requests);
- yield wait;
-
- info("Testing status sort again, descending.");
- testHeaders("status", "descending");
- testContents([14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0], 14);
-
- info("Testing status sort yet again, ascending.");
- EventUtils.sendMouseEvent({ type: "click" },
- document.querySelector("#requests-menu-status-button"));
- testHeaders("status", "ascending");
- testContents([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], 0);
-
- info("Testing status sort yet again, descending.");
- EventUtils.sendMouseEvent({ type: "click" },
- document.querySelector("#requests-menu-status-button"));
- testHeaders("status", "descending");
- testContents([14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0], 14);
-
- return teardown(monitor);
-
- function testHeaders(sortType, direction) {
- let doc = monitor.panelWin.document;
- let target = doc.querySelector("#requests-menu-" + sortType + "-button");
- let headers = doc.querySelectorAll(".requests-menu-header-button");
-
- for (let header of headers) {
- if (header != target) {
- ok(!header.hasAttribute("data-sorted"),
- "The " + header.id + " header does not have a 'data-sorted' attribute.");
- ok(!header.getAttribute("title"),
- "The " + header.id + " header does not have a 'title' attribute.");
- } else {
- is(header.getAttribute("data-sorted"), direction,
- "The " + header.id + " header has a correct 'data-sorted' attribute.");
- is(header.getAttribute("title"), direction == "ascending"
- ? L10N.getStr("networkMenu.sortedAsc")
- : L10N.getStr("networkMenu.sortedDesc"),
- "The " + header.id + " header has a correct 'title' attribute.");
- }
- }
- }
-
- function testContents(order, selection) {
- isnot(RequestsMenu.selectedItem, null,
- "There should still be a selected item after sorting.");
- is(RequestsMenu.selectedIndex, selection,
- "The first item should be still selected after sorting.");
- is(!!document.querySelector(".network-details-panel"), true,
- "The network details panel should still be visible after sorting.");
-
- is(RequestsMenu.items.length, order.length,
- "There should be a specific number of items in the requests menu.");
- is(RequestsMenu.visibleItems.length, order.length,
- "There should be a specific number of visbile items in the requests menu.");
- is(document.querySelectorAll(".request-list-item").length, order.length,
- "The visible items in the requests menu are, in fact, visible!");
-
- for (let i = 0, len = order.length / 5; i < len; i++) {
- verifyRequestItemTarget(RequestsMenu,
- RequestsMenu.getItemAtIndex(order[i]),
- "GET1", SORTING_SJS + "?index=1", {
- fuzzyUrl: true,
- status: 101,
- statusText: "Meh",
- type: "1",
- fullMimeType: "text/1",
- transferred: L10N.getStr("networkMenu.sizeUnavailable"),
- size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 0),
- time: true
- });
- }
- for (let i = 0, len = order.length / 5; i < len; i++) {
- verifyRequestItemTarget(RequestsMenu,
- RequestsMenu.getItemAtIndex(order[i + len]),
- "GET2", SORTING_SJS + "?index=2", {
- fuzzyUrl: true,
- status: 200,
- statusText: "Meh",
- type: "2",
- fullMimeType: "text/2",
- transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 19),
- size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 19),
- time: true
- });
- }
- for (let i = 0, len = order.length / 5; i < len; i++) {
- verifyRequestItemTarget(RequestsMenu,
- RequestsMenu.getItemAtIndex(order[i + len * 2]),
- "GET3", SORTING_SJS + "?index=3", {
- fuzzyUrl: true,
- status: 300,
- statusText: "Meh",
- type: "3",
- fullMimeType: "text/3",
- transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 29),
- size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 29),
- time: true
- });
- }
- for (let i = 0, len = order.length / 5; i < len; i++) {
- verifyRequestItemTarget(RequestsMenu,
- RequestsMenu.getItemAtIndex(order[i + len * 3]),
- "GET4", SORTING_SJS + "?index=4", {
- fuzzyUrl: true,
- status: 400,
- statusText: "Meh",
- type: "4",
- fullMimeType: "text/4",
- transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 39),
- size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 39),
- time: true
- });
- }
- for (let i = 0, len = order.length / 5; i < len; i++) {
- verifyRequestItemTarget(RequestsMenu,
- RequestsMenu.getItemAtIndex(order[i + len * 4]),
- "GET5", SORTING_SJS + "?index=5", {
- fuzzyUrl: true,
- status: 500,
- statusText: "Meh",
- type: "5",
- fullMimeType: "text/5",
- transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 49),
- size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 49),
- time: true
- });
- }
- }
-});
--- a/devtools/client/netmonitor/test/browser_net_status-codes.js
+++ b/devtools/client/netmonitor/test/browser_net_status-codes.js
@@ -9,22 +9,27 @@
add_task(function* () {
let { L10N } = require("devtools/client/netmonitor/l10n");
let { tab, monitor } = yield initNetMonitor(STATUS_CODES_URL);
info("Starting test... ");
- let { document, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
+
+ gStore.dispatch(Actions.batchEnable(false));
+
let requestItems = [];
- RequestsMenu.lazyUpdate = false;
-
const REQUEST_DATA = [
{
// request #0
method: "GET",
uri: STATUS_CODES_SJS + "?sts=100",
details: {
status: 101,
statusText: "Switching Protocols",
@@ -98,28 +103,34 @@ add_task(function* () {
yield verifyRequests();
yield testTab(0, testHeaders);
yield testTab(2, testParams);
return teardown(monitor);
/**
* A helper that verifies all requests show the correct information and caches
- * RequestsMenu items to requestItems array.
+ * request list items to requestItems array.
*/
function* verifyRequests() {
info("Verifying requests contain correct information.");
let index = 0;
for (let request of REQUEST_DATA) {
- let item = RequestsMenu.getItemAtIndex(index);
+ let item = getSortedRequests(gStore.getState()).get(index);
requestItems[index] = item;
info("Verifying request #" + index);
- yield verifyRequestItemTarget(RequestsMenu, item,
- request.method, request.uri, request.details);
+ yield verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ item,
+ request.method,
+ request.uri,
+ request.details
+ );
index++;
}
}
/**
* A helper that opens a given tab of request details pane, selects and passes
* all requests to the given test function.
@@ -161,17 +172,18 @@ add_task(function* () {
}
/**
* A function that tests "Params" panel contains correct information.
*/
function* testParams(data, index) {
EventUtils.sendMouseEvent({ type: "mousedown" },
document.querySelectorAll(".request-list-item")[index]);
- document.querySelector("#params-tab").click();
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#params-tab"));
let panel = document.querySelector("#params-panel");
let statusParamValue = data.uri.split("=").pop();
let statusParamShownValue = "\"" + statusParamValue + "\"";
let treeSections = panel.querySelectorAll(".tree-section");
is(treeSections.length, 1,
"There should be 1 param section displayed in this panel.");
--- a/devtools/client/netmonitor/test/browser_net_streaming-response.js
+++ b/devtools/client/netmonitor/test/browser_net_streaming-response.js
@@ -7,72 +7,83 @@
* Tests if reponses from streaming content types (MPEG-DASH, HLS) are
* displayed as XML or plain text
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(CUSTOM_GET_URL);
info("Starting test... ");
- let { panelWin } = monitor;
- let { document, NetMonitorView } = panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
+
+ gStore.dispatch(Actions.batchEnable(false));
const REQUESTS = [
[ "hls-m3u8", /^#EXTM3U/ ],
[ "mpeg-dash", /^<\?xml/ ]
];
- RequestsMenu.lazyUpdate = false;
-
let wait = waitForNetworkEvents(monitor, REQUESTS.length);
for (let [fmt] of REQUESTS) {
let url = CONTENT_TYPE_SJS + "?fmt=" + fmt;
yield ContentTask.spawn(tab.linkedBrowser, { url }, function* (args) {
content.wrappedJSObject.performRequests(1, args.url);
});
}
yield wait;
REQUESTS.forEach(([ fmt ], i) => {
- verifyRequestItemTarget(RequestsMenu, RequestsMenu.getItemAtIndex(i),
- "GET", CONTENT_TYPE_SJS + "?fmt=" + fmt, {
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(i),
+ "GET",
+ CONTENT_TYPE_SJS + "?fmt=" + fmt,
+ {
status: 200,
statusText: "OK"
});
});
wait = waitForDOM(document, "#response-panel");
- EventUtils.sendMouseEvent({ type: "mousedown" },
+ EventUtils.sendMouseEvent({ type: "click" },
document.querySelector(".network-details-panel-toggle"));
- document.querySelector("#response-tab").click();
+ EventUtils.sendMouseEvent({ type: "click" },
+ document.querySelector("#response-tab"));
yield wait;
- RequestsMenu.selectedIndex = -1;
+ gStore.dispatch(Actions.selectRequest(null));
yield selectIndexAndWaitForEditor(0);
// the hls-m3u8 part
testEditorContent(REQUESTS[0]);
yield selectIndexAndWaitForEditor(1);
// the mpeg-dash part
testEditorContent(REQUESTS[1]);
return teardown(monitor);
function* selectIndexAndWaitForEditor(index) {
let editor = document.querySelector("#response-panel .editor-mount iframe");
if (!editor) {
let waitDOM = waitForDOM(document, "#response-panel .editor-mount iframe");
- RequestsMenu.selectedIndex = index;
+ EventUtils.sendMouseEvent({ type: "mousedown" },
+ document.querySelectorAll(".request-list-item")[index]);
document.querySelector("#response-tab").click();
[editor] = yield waitDOM;
yield once(editor, "DOMContentLoaded");
} else {
- RequestsMenu.selectedIndex = index;
+ EventUtils.sendMouseEvent({ type: "mousedown" },
+ document.querySelectorAll(".request-list-item")[index]);
}
yield waitForDOM(editor.contentDocument, ".CodeMirror-code");
}
function testEditorContent([ fmt, textRe ]) {
let editor = document.querySelector("#response-panel .editor-mount iframe");
let text = editor.contentDocument
--- a/devtools/client/netmonitor/test/browser_net_throttle.js
+++ b/devtools/client/netmonitor/test/browser_net_throttle.js
@@ -9,17 +9,23 @@ add_task(function* () {
yield throttleTest(true);
yield throttleTest(false);
});
function* throttleTest(actuallyThrottle) {
requestLongerTimeout(2);
let { monitor } = yield initNetMonitor(SIMPLE_URL);
- const {ACTIVITY_TYPE, EVENTS, NetMonitorController, NetMonitorView} = monitor.panelWin;
+ let { document, gStore, windowRequire, NetMonitorController } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let { ACTIVITY_TYPE } = windowRequire("devtools/client/netmonitor/constants");
+ let { EVENTS } = windowRequire("devtools/client/netmonitor/events");
+ let {
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
info("Starting test... (actuallyThrottle = " + actuallyThrottle + ")");
// When throttling, must be smaller than the length of the content
// of SIMPLE_URL in bytes.
const size = actuallyThrottle ? 200 : 0;
const request = {
@@ -40,17 +46,17 @@ function* throttleTest(actuallyThrottle)
deferred.resolve(response);
});
yield deferred.promise;
let eventPromise = monitor.panelWin.once(EVENTS.RECEIVED_EVENT_TIMINGS);
yield NetMonitorController.triggerActivity(ACTIVITY_TYPE.RELOAD.WITH_CACHE_DISABLED);
yield eventPromise;
- let requestItem = NetMonitorView.RequestsMenu.getItemAtIndex(0);
+ let requestItem = getSortedRequests(gStore.getState()).get(0);
const reportedOneSecond = requestItem.eventTimings.timings.receive > 1000;
if (actuallyThrottle) {
ok(reportedOneSecond, "download reported as taking more than one second");
} else {
ok(!reportedOneSecond, "download reported as taking less than one second");
}
yield teardown(monitor);
--- a/devtools/client/netmonitor/test/browser_net_timing-division.js
+++ b/devtools/client/netmonitor/test/browser_net_timing-division.js
@@ -6,44 +6,48 @@
/**
* Tests if timing intervals are divided againts seconds when appropriate.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(CUSTOM_GET_URL);
info("Starting test... ");
- let { $all, NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let { getSortedRequests } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, 2);
// Timeout needed for having enough divisions on the time scale.
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests(2, null, 3000);
});
yield wait;
- let milDivs = $all(".requests-menu-timings-division[data-division-scale=millisecond]");
- let secDivs = $all(".requests-menu-timings-division[data-division-scale=second]");
- let minDivs = $all(".requests-menu-timings-division[data-division-scale=minute]");
+ let milDivs = document.querySelectorAll(
+ ".requests-menu-timings-division[data-division-scale=millisecond]");
+ let secDivs = document.querySelectorAll(
+ ".requests-menu-timings-division[data-division-scale=second]");
+ let minDivs = document.querySelectorAll(
+ ".requests-menu-timings-division[data-division-scale=minute]");
info("Number of millisecond divisions: " + milDivs.length);
info("Number of second divisions: " + secDivs.length);
info("Number of minute divisions: " + minDivs.length);
milDivs.forEach(div => info(`Millisecond division: ${div.textContent}`));
secDivs.forEach(div => info(`Second division: ${div.textContent}`));
minDivs.forEach(div => info(`Minute division: ${div.textContent}`));
- is(RequestsMenu.itemCount, 2, "There should be only two requests made.");
+ is(gStore.getState().requests.requests.size, 2, "There should be only two requests made.");
- let firstRequest = RequestsMenu.getItemAtIndex(0);
- let lastRequest = RequestsMenu.getItemAtIndex(1);
+ let firstRequest = getSortedRequests(gStore.getState()).get(0);
+ let lastRequest = getSortedRequests(gStore.getState()).get(1);
info("First request happened at: " +
firstRequest.responseHeaders.headers.find(e => e.name == "Date").value);
info("Last request happened at: " +
lastRequest.responseHeaders.headers.find(e => e.name == "Date").value);
ok(secDivs.length,
"There should be at least one division on the seconds time scale.");
--- a/devtools/client/netmonitor/test/browser_net_truncate.js
+++ b/devtools/client/netmonitor/test/browser_net_truncate.js
@@ -14,31 +14,40 @@ function test() {
const URL = EXAMPLE_URL + "sjs_truncate-test-server.sjs?limit=" + RESPONSE_BODY_LIMIT;
// Another slow test on Linux debug.
requestLongerTimeout(2);
initNetMonitor(URL).then(({ tab, monitor }) => {
info("Starting test... ");
- let { NetMonitorView } = monitor.panelWin;
- let { RequestsMenu } = NetMonitorView;
+ let { document, gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let { EVENTS } = windowRequire("devtools/client/netmonitor/events");
+ let {
+ getDisplayedRequests,
+ getSortedRequests,
+ } = windowRequire("devtools/client/netmonitor/selectors/index");
- RequestsMenu.lazyUpdate = false;
+ gStore.dispatch(Actions.batchEnable(false));
waitForNetworkEvents(monitor, 1)
.then(() => teardown(monitor))
.then(finish);
- monitor.panelWin.once(monitor.panelWin.EVENTS.RECEIVED_RESPONSE_CONTENT, () => {
- let requestItem = RequestsMenu.getItemAtIndex(0);
-
- verifyRequestItemTarget(RequestsMenu, requestItem, "GET", URL, {
- type: "plain",
- fullMimeType: "text/plain; charset=utf-8",
- transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeMB", 2),
- size: L10N.getFormatStrWithNumbers("networkMenu.sizeMB", 2),
- });
+ monitor.panelWin.once(EVENTS.RECEIVED_RESPONSE_CONTENT, () => {
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(gStore.getState()),
+ getSortedRequests(gStore.getState()).get(0),
+ "GET", URL,
+ {
+ type: "plain",
+ fullMimeType: "text/plain; charset=utf-8",
+ transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeMB", 2),
+ size: L10N.getFormatStrWithNumbers("networkMenu.sizeMB", 2),
+ }
+ );
});
tab.linkedBrowser.reload();
});
}
--- a/devtools/client/netmonitor/test/head.js
+++ b/devtools/client/netmonitor/test/head.js
@@ -5,16 +5,17 @@
"use strict";
// shared-head.js handles imports, constants, and utility functions
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/framework/test/shared-head.js",
this);
+const { EVENTS } = require("devtools/client/netmonitor/events");
var { Toolbox } = require("devtools/client/framework/toolbox");
const {
decodeUnicodeUrl,
getUrlBaseName,
getUrlQuery,
getUrlHost,
} = require("devtools/client/netmonitor/request-utils");
@@ -171,24 +172,20 @@ function teardown(monitor) {
let onDestroyed = monitor.once("destroyed");
yield removeTab(tab);
yield onDestroyed;
});
}
function waitForNetworkEvents(aMonitor, aGetRequests, aPostRequests = 0) {
let deferred = promise.defer();
-
let panel = aMonitor.panelWin;
- let events = panel.EVENTS;
-
let progress = {};
let genericEvents = 0;
let postEvents = 0;
-
let awaitedEventsToListeners = [
["UPDATING_REQUEST_HEADERS", onGenericEvent],
["RECEIVED_REQUEST_HEADERS", onGenericEvent],
["UPDATING_REQUEST_COOKIES", onGenericEvent],
["RECEIVED_REQUEST_COOKIES", onGenericEvent],
["UPDATING_REQUEST_POST_DATA", onPostEvent],
["RECEIVED_REQUEST_POST_DATA", onPostEvent],
["UPDATING_RESPONSE_HEADERS", onGenericEvent],
@@ -205,17 +202,17 @@ function waitForNetworkEvents(aMonitor,
function initProgressForURL(url) {
if (progress[url]) return;
progress[url] = {};
awaitedEventsToListeners.forEach(([e]) => progress[url][e] = 0);
}
function updateProgressForURL(url, event) {
initProgressForURL(url);
- progress[url][Object.keys(events).find(e => events[e] == event)] = 1;
+ progress[url][Object.keys(EVENTS).find(e => EVENTS[e] == event)] = 1;
}
function onGenericEvent(event, actor) {
genericEvents++;
maybeResolve(event, actor);
}
function onPostEvent(event, actor) {
@@ -238,49 +235,47 @@ function waitForNetworkEvents(aMonitor,
// 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 >= (aGetRequests + aPostRequests) * 13 &&
postEvents >= aPostRequests * 2) {
- awaitedEventsToListeners.forEach(([e, l]) => panel.off(events[e], l));
+ awaitedEventsToListeners.forEach(([e, l]) => panel.off(EVENTS[e], l));
executeSoon(deferred.resolve);
}
}
- awaitedEventsToListeners.forEach(([e, l]) => panel.on(events[e], l));
+ awaitedEventsToListeners.forEach(([e, l]) => panel.on(EVENTS[e], l));
return deferred.promise;
}
/**
* Convert a store record (model) to the rendered element. Tests that need to use
* this should be rewritten - test the rendered markup at unit level, integration
* mochitest should check only the store state.
*/
function getItemTarget(requestList, requestItem) {
const items = requestList.mountPoint.querySelectorAll(".request-list-item");
return [...items].find(el => el.dataset.id == requestItem.id);
}
-function verifyRequestItemTarget(requestList, requestItem, aMethod, aUrl, aData = {}) {
+function verifyRequestItemTarget(document, requestList, requestItem, aMethod,
+ aUrl, aData = {}) {
info("> Verifying: " + aMethod + " " + aUrl + " " + aData.toSource());
- // This bloats log sizes significantly in automation (bug 992485)
- // info("> Request: " + requestItem.toSource());
- let visibleIndex = requestList.visibleItems.indexOf(requestItem);
+ let visibleIndex = requestList.indexOf(requestItem);
info("Visible index of item: " + visibleIndex);
let { fuzzyUrl, status, statusText, cause, type, fullMimeType,
transferred, size, time, displayedStatus } = aData;
- let target = getItemTarget(requestList, requestItem);
-
+ let target = document.querySelectorAll(".request-list-item")[visibleIndex];
let unicodeUrl = decodeUnicodeUrl(aUrl);
let name = getUrlBaseName(aUrl);
let query = getUrlQuery(aUrl);
let hostPort = getUrlHost(aUrl);
let remoteAddress = requestItem.remoteAddress;
if (fuzzyUrl) {
ok(requestItem.method.startsWith(aMethod), "The attached method is correct.");
@@ -359,30 +354,30 @@ function verifyRequestItemTarget(request
let value = target.querySelector(".requests-menu-timings-total").textContent;
let tooltip = target.querySelector(".requests-menu-timings-total").getAttribute("title");
info("Displayed time: " + value);
info("Tooltip time: " + tooltip);
ok(~~(value.match(/[0-9]+/)) >= 0, "The displayed time is correct.");
ok(~~(tooltip.match(/[0-9]+/)) >= 0, "The tooltip time is correct.");
}
- if (visibleIndex != -1) {
- if (visibleIndex % 2 == 0) {
+ if (visibleIndex !== -1) {
+ if (visibleIndex % 2 === 0) {
ok(target.classList.contains("even"), "Item should have 'even' class.");
ok(!target.classList.contains("odd"), "Item shouldn't have 'odd' class.");
} else {
ok(!target.classList.contains("even"), "Item shouldn't have 'even' class.");
ok(target.classList.contains("odd"), "Item should have 'odd' class.");
}
}
}
/**
* Helper function for waiting for an event to fire before resolving a promise.
- * Example: waitFor(aMonitor.panelWin, aMonitor.panelWin.EVENTS.TAB_UPDATED);
+ * Example: waitFor(aMonitor.panelWin, EVENT_NAME);
*
* @param object subject
* The event emitter object that is being listened to.
* @param string eventName
* The name of the event to listen to.
* @return object
* Returns a promise that resolves upon firing of the event.
*/
@@ -505,28 +500,8 @@ function waitForContentMessage(name) {
let def = promise.defer();
mm.addMessageListener(name, function onMessage(msg) {
mm.removeMessageListener(name, onMessage);
def.resolve(msg);
});
return def.promise;
}
-
-/**
- * Open the requestMenu menu and return all of it's items in a flat array
- * @param {netmonitorPanel} netmonitor
- * @param {Event} event mouse event with screenX and screenX coordinates
- * @return An array of MenuItems
- */
-function openContextMenuAndGetAllItems(netmonitor, event) {
- let menu = netmonitor.RequestsMenu.contextMenu.open(event);
-
- // Flatten all menu items into a single array to make searching through it easier
- let allItems = [].concat.apply([], menu.items.map(function addItem(item) {
- if (item.submenu) {
- return addItem(item.submenu.items);
- }
- return item;
- }));
-
- return allItems;
-}
--- a/devtools/client/styleeditor/test/browser_styleeditor_fetch-from-cache.js
+++ b/devtools/client/styleeditor/test/browser_styleeditor_fetch-from-cache.js
@@ -8,32 +8,35 @@
const TEST_URL = TEST_BASE_HTTP + "doc_uncached.html";
add_task(function* () {
info("Opening netmonitor");
let tab = yield addTab("about:blank");
let target = TargetFactory.forTab(tab);
let toolbox = yield gDevTools.showToolbox(target, "netmonitor");
- let netmonitor = toolbox.getPanel("netmonitor");
- let { RequestsMenu } = netmonitor.panelWin.NetMonitorView;
- RequestsMenu.lazyUpdate = false;
+ let monitor = toolbox.getPanel("netmonitor");
+ let { gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let { getSortedRequests } = windowRequire("devtools/client/netmonitor/selectors/index");
+
+ gStore.dispatch(Actions.batchEnable(false));
info("Navigating to test page");
yield navigateTo(TEST_URL);
info("Opening Style Editor");
let styleeditor = yield toolbox.selectTool("styleeditor");
info("Waiting for the source to be loaded.");
yield styleeditor.UI.editors[0].getSourceEditor();
info("Checking Netmonitor contents.");
let items = [];
- for (let item of RequestsMenu.items) {
+ for (let item of getSortedRequests(gStore.getState())) {
if (item.url.endsWith("doc_uncached.css")) {
items.push(item);
}
}
is(items.length, 2,
"Got two requests for doc_uncached.css after Style Editor was loaded.");
ok(items[1].fromCache,
--- a/devtools/client/themes/netmonitor.css
+++ b/devtools/client/themes/netmonitor.css
@@ -78,19 +78,18 @@
--timing-wait-color: rgba(94, 136, 176, 0.8); /* blue grey */
--timing-receive-color: rgba(112, 191, 83, 0.8); /* green */
--sort-ascending-image: url(chrome://devtools/skin/images/firebug/arrow-up.svg);
--sort-descending-image: url(chrome://devtools/skin/images/firebug/arrow-down.svg);
}
.request-list-container {
- display: -moz-box;
- -moz-box-orient: vertical;
- -moz-box-flex: 1;
+ display: flex;
+ flex-direction: column;
}
.request-list-empty-notice {
margin: 0;
padding: 12px;
font-size: 120%;
}
@@ -130,24 +129,26 @@
flex-wrap: nowrap;
}
.theme-firebug #requests-menu-toolbar {
height: 19px !important;
}
.requests-menu-contents {
- display: -moz-box;
- -moz-box-orient: vertical;
- -moz-box-flex: 1;
+ display: flex;
+ flex-direction: column;
overflow-x: hidden;
overflow-y: auto;
--timings-scale: 1;
--timings-rev-scale: 1;
+
+ /* Devtools panel view height - tabbar height - toolbar height */
+ height: calc(100vh - 48px);
}
.requests-menu-subitem {
display: flex;
flex: none;
box-sizing: border-box;
align-items: center;
padding: 3px;
@@ -1326,13 +1327,17 @@
height: 100%;
overflow: hidden;
}
#splitter-adjustable-box[hidden=true] {
display: none;
}
+#react-request-list-hook {
+ -moz-box-flex: 1;
+}
+
#primed-cache-chart,
#empty-cache-chart {
display: -moz-box;
-moz-box-flex: 1;
}
--- a/devtools/client/webconsole/test/browser_netmonitor_shows_reqs_in_webconsole.js
+++ b/devtools/client/webconsole/test/browser_netmonitor_shows_reqs_in_webconsole.js
@@ -57,17 +57,21 @@ function loadDocument(browser) {
}, {capture: true, once: true});
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, TEST_PATH);
return deferred.promise;
}
function testNetmonitor(toolbox) {
let monitor = toolbox.getCurrentPanel();
- let { RequestsMenu } = monitor.panelWin.NetMonitorView;
- RequestsMenu.lazyUpdate = false;
+
+ let { gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let { getSortedRequests } = windowRequire("devtools/client/netmonitor/selectors/index");
- is(RequestsMenu.itemCount, 1, "Network request appears in the network panel");
+ gStore.dispatch(Actions.batchEnable(false));
- let item = RequestsMenu.getItemAtIndex(0);
+ is(gStore.getState().requests.requests.size, 1, "Network request appears in the network panel");
+
+ let item = getSortedRequests(gStore.getState()).get(0);
is(item.method, "GET", "The attached method is correct.");
is(item.url, TEST_PATH, "The attached url is correct.");
}
--- a/devtools/client/webconsole/test/browser_webconsole_netlogging_panel.js
+++ b/devtools/client/webconsole/test/browser_webconsole_netlogging_panel.js
@@ -17,14 +17,19 @@ add_task(function* () {
const hud = yield loadPageAndGetHud(TEST_NETWORK_REQUEST_URI);
let request = yield finishedRequest;
yield hud.ui.openNetworkPanel(request.actor);
let toolbox = gDevTools.getToolbox(hud.target);
is(toolbox.currentToolId, "netmonitor", "Network panel was opened");
let panel = toolbox.getCurrentPanel();
- let selected = panel.panelWin.NetMonitorView.RequestsMenu.selectedItem;
+
+ let { gStore, windowRequire } = panel.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let { getSelectedRequest } = windowRequire("devtools/client/netmonitor/selectors/index");
+
+ let selected = getSelectedRequest(gStore.getState());
is(selected.method, request.request.method,
"The correct request is selected");
is(selected.url, request.request.url,
"The correct request is definitely selected");
});
--- a/devtools/client/webconsole/test/browser_webconsole_netlogging_reset_filter.js
+++ b/devtools/client/webconsole/test/browser_webconsole_netlogging_reset_filter.js
@@ -11,18 +11,16 @@
const TEST_FILE_URI =
"http://example.com/browser/devtools/client/webconsole/test/" +
"test-network.html";
const TEST_URI = "data:text/html;charset=utf8,<p>test file URI";
var hud;
add_task(function* () {
- let Actions = require("devtools/client/netmonitor/actions/index");
-
let requests = [];
let { browser } = yield loadTab(TEST_URI);
yield pushPrefEnv();
hud = yield openConsole();
hud.jsterm.clearOutput();
HUDService.lastFinishedRequest.callback = request => requests.push(request);
@@ -35,30 +33,34 @@ add_task(function* () {
let htmlRequest = requests.find(e => e.request.url.endsWith("html"));
ok(htmlRequest, "htmlRequest was a html");
yield hud.ui.openNetworkPanel(htmlRequest.actor);
let toolbox = gDevTools.getToolbox(hud.target);
is(toolbox.currentToolId, "netmonitor", "Network panel was opened");
let panel = toolbox.getCurrentPanel();
- let selected = panel.panelWin.NetMonitorView.RequestsMenu.selectedItem;
+ let { gStore, windowRequire } = panel.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let { getSelectedRequest } = windowRequire("devtools/client/netmonitor/selectors/index");
+
+ let selected = getSelectedRequest(gStore.getState());
is(selected.method, htmlRequest.request.method,
"The correct request is selected");
is(selected.url, htmlRequest.request.url,
"The correct request is definitely selected");
// Filter out the HTML request.
- panel.panelWin.gStore.dispatch(Actions.toggleRequestFilterType("js"));
+ gStore.dispatch(Actions.toggleRequestFilterType("js"));
yield toolbox.selectTool("webconsole");
is(toolbox.currentToolId, "webconsole", "Web console was selected");
yield hud.ui.openNetworkPanel(htmlRequest.actor);
- panel.panelWin.NetMonitorView.RequestsMenu.selectedItem;
+ selected = getSelectedRequest(gStore.getState());
is(selected.method, htmlRequest.request.method,
"The correct request is selected");
is(selected.url, htmlRequest.request.url,
"The correct request is definitely selected");
// All tests are done. Shutdown.
HUDService.lastFinishedRequest.callback = null;
htmlRequest = browser = requests = hud = null;
--- a/devtools/client/webconsole/test/browser_webconsole_shows_reqs_in_netmonitor.js
+++ b/devtools/client/webconsole/test/browser_webconsole_shows_reqs_in_netmonitor.js
@@ -57,16 +57,21 @@ function loadDocument(browser) {
}, {capture: true, once: true});
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, TEST_PATH);
return deferred.promise;
}
function testNetmonitor(toolbox) {
let monitor = toolbox.getCurrentPanel();
- let { RequestsMenu } = monitor.panelWin.NetMonitorView;
- RequestsMenu.lazyUpdate = false;
- is(RequestsMenu.itemCount, 1, "Network request appears in the network panel");
+
+ let { gStore, windowRequire } = monitor.panelWin;
+ let Actions = windowRequire("devtools/client/netmonitor/actions/index");
+ let { getSortedRequests } = windowRequire("devtools/client/netmonitor/selectors/index");
- let item = RequestsMenu.getItemAtIndex(0);
+ gStore.dispatch(Actions.batchEnable(false));
+
+ is(gStore.getState().requests.requests.size, 1, "Network request appears in the network panel");
+
+ let item = getSortedRequests(gStore.getState()).get(0);
is(item.method, "GET", "The request method is correct.");
is(item.url, TEST_PATH, "The request url is correct.");
}