Backed out 3 changesets (bug 1404917)for failing clipboard in devtools/client/netmonitor/src/har/test/browser_net_har_copy_all_as_har.js r=backout on a CLOSED TREE

Backed out changeset 3e7a6e920c6b (bug 1404917)
Backed out changeset 7dcfe8d12d6f (bug 1404917)
Backed out changeset 3d8a6d24cec9 (bug 1404917)
This commit is contained in:
Noemi Erli 2017-11-10 16:56:35 +02:00
Родитель d2bfb199ac
Коммит bfebc90a29
44 изменённых файлов: 383 добавлений и 435 удалений

Просмотреть файл

@ -301,6 +301,15 @@
text-align: start;
}
.requests-list-icon {
background: transparent;
width: 15px;
height: 15px;
margin: 0 4px;
outline: 1px solid var(--table-splitter-color);
vertical-align: top;
}
/* Protocol column */
.requests-list-protocol {

Просмотреть файл

@ -11,9 +11,10 @@ const {
} = require("devtools/client/shared/vendor/react");
const { propertiesEqual } = require("../utils/request-utils");
const { div } = DOM;
const { div, img } = DOM;
const UPDATED_FILE_PROPS = [
"responseContentDataUri",
"urlDetails",
];
@ -21,6 +22,7 @@ class RequestListColumnFile extends Component {
static get propTypes() {
return {
item: PropTypes.object.isRequired,
onThumbnailMouseDown: PropTypes.func.isRequired,
};
}
@ -30,7 +32,8 @@ class RequestListColumnFile extends Component {
render() {
let {
item: { urlDetails },
item: { responseContentDataUri, urlDetails },
onThumbnailMouseDown
} = this.props;
return (
@ -38,6 +41,11 @@ class RequestListColumnFile extends Component {
className: "requests-list-column requests-list-file",
title: urlDetails.unicodeUrl,
},
img({
className: "requests-list-icon",
src: responseContentDataUri,
onMouseDown: onThumbnailMouseDown,
}),
urlDetails.baseNameWithQuery
)
);

Просмотреть файл

@ -47,6 +47,7 @@ class RequestListContent extends Component {
onItemMouseDown: PropTypes.func.isRequired,
onSecurityIconMouseDown: PropTypes.func.isRequired,
onSelectDelta: PropTypes.func.isRequired,
onThumbnailMouseDown: PropTypes.func.isRequired,
onWaterfallMouseDown: PropTypes.func.isRequired,
scale: PropTypes.number,
selectedRequestId: PropTypes.string,
@ -70,7 +71,6 @@ class RequestListContent extends Component {
getTabTarget: connector.getTabTarget,
getLongString: connector.getLongString,
openStatistics: (open) => dispatch(Actions.openStatistics(connector, open)),
requestData: connector.requestData,
});
this.tooltip = new HTMLTooltip(window.parent.document, { type: "arrow" });
}
@ -148,7 +148,7 @@ class RequestListContent extends Component {
}
let { connector } = this.props;
if (target.closest(".requests-list-file")) {
if (requestItem.responseContent && target.closest(".requests-list-icon")) {
return setTooltipImageContent(connector, tooltip, itemEl, requestItem);
}
@ -221,6 +221,7 @@ class RequestListContent extends Component {
onCauseBadgeMouseDown,
onItemMouseDown,
onSecurityIconMouseDown,
onThumbnailMouseDown,
onWaterfallMouseDown,
scale,
selectedRequestId,
@ -250,6 +251,7 @@ class RequestListContent extends Component {
onMouseDown: () => onItemMouseDown(item.id),
onCauseBadgeMouseDown: () => onCauseBadgeMouseDown(item.cause),
onSecurityIconMouseDown: () => onSecurityIconMouseDown(item.securityState),
onThumbnailMouseDown: () => onThumbnailMouseDown(),
onWaterfallMouseDown: () => onWaterfallMouseDown(),
}))
)
@ -288,6 +290,13 @@ module.exports = connect(
}
},
onSelectDelta: (delta) => dispatch(Actions.selectDelta(delta)),
/**
* A handler that opens the response tab in the details view if
* the thumbnail is clicked.
*/
onThumbnailMouseDown: () => {
dispatch(Actions.selectDetailsPanelTab("response"));
},
/**
* A handler that opens the timing sidebar panel if the waterfall is clicked.
*/

Просмотреть файл

@ -87,6 +87,7 @@ class RequestListItem extends Component {
onFocusedNodeChange: PropTypes.func,
onMouseDown: PropTypes.func.isRequired,
onSecurityIconMouseDown: PropTypes.func.isRequired,
onThumbnailMouseDown: PropTypes.func.isRequired,
onWaterfallMouseDown: PropTypes.func.isRequired,
waterfallWidth: PropTypes.number,
};
@ -125,6 +126,7 @@ class RequestListItem extends Component {
onMouseDown,
onCauseBadgeMouseDown,
onSecurityIconMouseDown,
onThumbnailMouseDown,
onWaterfallMouseDown,
} = this.props;
@ -143,7 +145,7 @@ class RequestListItem extends Component {
},
columns.get("status") && RequestListColumnStatus({ item }),
columns.get("method") && RequestListColumnMethod({ item }),
columns.get("file") && RequestListColumnFile({ item }),
columns.get("file") && RequestListColumnFile({ item, onThumbnailMouseDown }),
columns.get("protocol") && RequestListColumnProtocol({ item }),
columns.get("scheme") && RequestListColumnScheme({ item }),
columns.get("domain") && RequestListColumnDomain({ item,

Просмотреть файл

@ -39,7 +39,6 @@ class ResponsePanel extends Component {
return {
request: PropTypes.object.isRequired,
openLink: PropTypes.func,
connector: PropTypes.object.isRequired,
};
}
@ -57,36 +56,6 @@ class ResponsePanel extends Component {
this.isJSON = this.isJSON.bind(this);
}
/**
* `componentDidMount` is called when opening the ResponsePanel for the first time
*/
componentDidMount() {
this.maybeFetchResponseContent(this.props);
}
/**
* `componentWillReceiveProps` is the only method called when switching between two
* requests while the response panel is displayed.
*/
componentWillReceiveProps(nextProps) {
this.maybeFetchResponseContent(nextProps);
}
/**
* When switching to another request, lazily fetch response content
* from the backend. The Response Panel will first be empty and then
* display the content.
*/
maybeFetchResponseContent(props) {
if (props.request.responseContentAvailable &&
(!props.request.responseContent ||
!props.request.responseContent.content)) {
// This method will set `props.request.responseContent.content`
// asynchronously and force another render.
props.connector.requestData(props.request.id, "responseContent");
}
}
updateImageDimemsions({ target }) {
this.setState({
imageDimensions: {

Просмотреть файл

@ -78,7 +78,7 @@ function TabboxPanel({
id: PANELS.RESPONSE,
title: RESPONSE_TITLE,
},
ResponsePanel({ request, openLink, connector }),
ResponsePanel({ request, openLink }),
),
TabPanel({
id: PANELS.TIMINGS,

Просмотреть файл

@ -4,6 +4,8 @@
"use strict";
const { formDataURI } = require("../../utils/request-utils");
function ResponseInfo(id, response, content) {
let {
mimeType
@ -21,7 +23,7 @@ function ResponseInfo(id, response, content) {
}
function ResponseContent(id, response, content) {
const {body} = content;
const {body, base64Encoded} = content;
let {mimeType, encodedDataLength} = response;
let responseContent = ResponseInfo(id, response, content);
let payload = Object.assign(
@ -31,6 +33,9 @@ function ResponseContent(id, response, content) {
transferredSize: encodedDataLength, // TODO: verify
mimeType: mimeType
}, body);
if (mimeType.includes("image/")) {
payload.responseContentDataUri = formDataURI(mimeType, base64Encoded, response);
}
return payload;
}

Просмотреть файл

@ -22,7 +22,6 @@ class FirefoxConnector {
this.triggerActivity = this.triggerActivity.bind(this);
this.getTabTarget = this.getTabTarget.bind(this);
this.viewSourceInDebugger = this.viewSourceInDebugger.bind(this);
this.requestData = this.requestData.bind(this);
// Internals
this.getLongString = this.getLongString.bind(this);
@ -286,10 +285,6 @@ class FirefoxConnector {
this.toolbox.viewSourceInDebugger(sourceURL, sourceLine);
}
}
requestData(request, type) {
return this.dataProvider.requestData(request, type);
}
}
module.exports = new FirefoxConnector();

Просмотреть файл

@ -9,6 +9,7 @@ const { EVENTS } = require("../constants");
const { CurlUtils } = require("devtools/client/shared/curl");
const {
fetchHeaders,
formDataURI,
} = require("../utils/request-utils");
/**
@ -29,10 +30,6 @@ class FirefoxDataProvider {
this.payloadQueue = [];
this.rdpRequestMap = new Map();
// Map[key string => Promise] used by `requestData` to prevent requesting the same
// request data twice.
this.lazyRequestData = new Map();
// Fetching data from the backend
this.getLongString = this.getLongString.bind(this);
@ -120,15 +117,18 @@ class FirefoxDataProvider {
);
this.pushRequestToQueue(id, payload);
return payload;
}
async fetchResponseContent(mimeType, responseContent) {
let payload = {};
if (mimeType && responseContent && responseContent.content) {
let { text } = responseContent.content;
let { encoding, text } = responseContent.content;
let response = await this.getLongString(text);
if (mimeType.includes("image/")) {
payload.responseContentDataUri = formDataURI(mimeType, encoding, response);
}
responseContent.content.text = response;
payload.responseContent = responseContent;
}
@ -243,24 +243,10 @@ class FirefoxDataProvider {
return false;
}
let { payload } = this.getRequestFromQueue(id);
// The payload is ready when all values in the record are true. (i.e. all data
// received, but the lazy one. responseContent is the only one for now).
// Note that we never fetch response header/cookies for request with security issues.
// (Be careful, securityState can be undefined, for example for WebSocket requests)
// Also note that service worker don't have security info set.
// Bug 1404917 should simplify this heuristic by making all these field be lazily
// fetched, only on-demand.
return record.requestHeaders &&
record.requestCookies &&
record.eventTimings &&
(record.securityInfo || record.fromServiceWorker) &&
(
(record.responseHeaders && record.responseCookies) ||
payload.securityState == "broken" ||
(payload.responseContentAvailable && !payload.status)
);
// The payload is ready when all values in the record are true.
// (i.e. all data received).
let props = Object.getOwnPropertyNames(record);
return props.every(prop => record[prop] === true);
}
/**
@ -333,14 +319,8 @@ class FirefoxDataProvider {
this.rdpRequestMap.set(actor, {
requestHeaders: false,
requestCookies: false,
responseHeaders: false,
responseCookies: false,
securityInfo: false,
eventTimings: false,
// This isn't a request data, but we need to know about request being served from
// service worker later, from isRequestPayloadReady.
fromServiceWorker,
responseContent: false,
});
this.addRequest(actor, {
@ -368,25 +348,51 @@ class FirefoxDataProvider {
let { actor } = networkInfo;
let { updateType } = packet;
// When we pause and resume, we may receive `networkEventUpdate` for a request
// that started during the pause and we missed its `networkEvent`.
if (!this.rdpRequestMap.has(actor)) {
return;
}
switch (updateType) {
case "requestHeaders":
this.requestData(actor, updateType).then(response => {
this.onRequestHeaders(response)
.then(() => this.onDataReceived(actor, updateType));
emit(EVENTS.UPDATING_REQUEST_HEADERS, actor);
});
break;
case "requestCookies":
this.requestData(actor, updateType).then(response => {
this.onRequestCookies(response)
.then(() => this.onDataReceived(actor, updateType));
emit(EVENTS.UPDATING_REQUEST_COOKIES, actor);
});
break;
case "requestPostData":
case "responseHeaders":
case "responseCookies":
this.requestPayloadData(actor, updateType);
this.requestData(actor, updateType).then(response => {
this.onRequestPostData(response)
.then(() => this.onDataReceived(actor, updateType));
emit(EVENTS.UPDATING_REQUEST_POST_DATA, actor);
});
break;
case "securityInfo":
this.updateRequest(actor, {
securityState: networkInfo.securityInfo,
}).then(() => {
this.requestPayloadData(actor, updateType);
this.requestData(actor, updateType).then(response => {
this.onSecurityInfo(response)
.then(() => this.onDataReceived(actor, updateType));
emit(EVENTS.UPDATING_SECURITY_INFO, actor);
});
});
break;
case "responseHeaders":
this.requestData(actor, updateType).then(response => {
this.onResponseHeaders(response)
.then(() => this.onDataReceived(actor, updateType));
emit(EVENTS.UPDATING_RESPONSE_HEADERS, actor);
});
break;
case "responseCookies":
this.requestData(actor, updateType).then(response => {
this.onResponseCookies(response)
.then(() => this.onDataReceived(actor, updateType));
emit(EVENTS.UPDATING_RESPONSE_COOKIES, actor);
});
break;
case "responseStart":
@ -402,20 +408,23 @@ class FirefoxDataProvider {
});
break;
case "responseContent":
this.updateRequest(actor, {
contentSize: networkInfo.response.bodySize,
transferredSize: networkInfo.response.transferredSize,
mimeType: networkInfo.response.content.mimeType,
// This field helps knowing when/if responseContent property is available
// and can be requested via `requestData`
responseContentAvailable: true,
this.requestData(actor, updateType).then(response => {
this.onResponseContent({
contentSize: networkInfo.response.bodySize,
transferredSize: networkInfo.response.transferredSize,
mimeType: networkInfo.response.content.mimeType
}, response).then(() => this.onDataReceived(actor, updateType));
emit(EVENTS.UPDATING_RESPONSE_CONTENT, actor);
});
break;
case "eventTimings":
this.updateRequest(actor, { totalTime: networkInfo.totalTime })
.then(() => {
this.requestPayloadData(actor, updateType);
this.requestData(actor, updateType).then(response => {
this.onEventTimings(response)
.then(() => this.onDataReceived(actor, updateType));
emit(EVENTS.UPDATING_EVENT_TIMINGS, actor);
});
});
break;
}
@ -424,43 +433,65 @@ class FirefoxDataProvider {
}
/**
* Wrapper method for requesting HTTP details data for the payload.
* Wrapper method for requesting HTTP details data from the backend.
*
* It is specific to all requests done from `onNetworkEventUpdate`, for data that are
* immediately fetched whenever the data is available.
* It collects all RDP requests and monitors responses, so it's
* possible to determine whether (and when) all requested data
* has been fetched from the backend.
*
* All these requests are cached into `rdpRequestMap`. All requests related to a given
* actor will be collected in the same record.
*
* Once bug 1404917 is completed, we should no longer use this method.
* All request fields should be loaded only on-demand, via `requestData` method.
* It also nicely returns a promise.
*
* @param {string} actor actor id (used as request id)
* @param {string} method identifier of the data we want to fetch
*
* @return {Promise} return a promise resolved when data are received.
*/
requestPayloadData(actor, method) {
requestData(actor, method) {
let record = this.rdpRequestMap.get(actor);
// If data has been already requested, do nothing.
if (record[method]) {
return;
// All RDP requests related to the given actor will be collected
// in the same record.
if (!record) {
record = {};
}
let promise = this._requestData(actor, method);
promise.then(() => {
// Once we got the data toggle the Map item to `true` in order to
// make isRequestPayloadReady return `true` once all the data is fetched.
record[method] = true;
this.onPayloadDataReceived(actor, method, !record);
// If data has been already requested return the same promise.
if (record.method) {
return record.method;
}
// Calculate real name of the client getter.
let realMethodName = "get" + method.charAt(0).toUpperCase() +
method.slice(1);
// Request data from the backend.
let promise = new Promise((resolve, reject) => {
if (typeof this.webConsoleClient[realMethodName] == "function") {
this.webConsoleClient[realMethodName](actor, response => {
// Resolve incoming HTTP details data-promise.
resolve(response);
});
} else {
reject(new Error("Error: No such client method!"));
}
});
// Store the promise in order to know about RDP requests
// in progress.
record[method] = promise;
return promise;
}
/**
* Executed when new data are received from the backend.
*/
async onPayloadDataReceived(actor, type) {
// Notify actions when all the sync request from onNetworkEventUpdate are done,
// or, everytime requestData is called for fetching data lazily.
async onDataReceived(actor, type) {
let record = this.rdpRequestMap.get(actor);
if (record) {
record[type] = true;
}
if (this.isRequestPayloadReady(actor)) {
let payloadFromQueue = this.getRequestFromQueue(actor).payload;
@ -473,88 +504,10 @@ class FirefoxDataProvider {
await updateRequest(actor, payloadFromQueue, true);
}
// This event is fired only once per request, once all the properties are fetched
// from `onNetworkEventUpdate`. There should be no more RDP requests after this.
emit(EVENTS.PAYLOAD_READY, actor);
}
}
/**
* Public connector API to lazily request HTTP details from the backend.
*
* This is internal method that focus on:
* - calling the right actor method,
* - emitting an event to tell we start fetching some request data,
* - call data processing method.
*
* @param {string} actor actor id (used as request id)
* @param {string} method identifier of the data we want to fetch
*
* @return {Promise} return a promise resolved when data is received.
*/
requestData(actor, method) {
// Key string used in `lazyRequestData`. We use this Map to prevent requesting
// the same data twice at the same time.
let key = actor + "-" + method;
let promise = this.lazyRequestData.get(key);
// If a request is pending, reuse it.
if (promise) {
return promise;
}
// Fetch the data
promise = this._requestData(actor, method);
this.lazyRequestData.set(key, promise);
promise.then(async () => {
// Remove the request from the cache, any new call to requestData will fetch the
// data again.
this.lazyRequestData.delete(key, promise);
let payloadFromQueue = this.getRequestFromQueue(actor).payload;
let { updateRequest } = this.actions;
if (updateRequest) {
await updateRequest(actor, payloadFromQueue, true);
}
});
return promise;
}
/**
* Internal helper used to request HTTP details from the backend.
*
* This is internal method that focus on:
* - calling the right actor method,
* - emitting an event to tell we start fetching some request data,
* - call data processing method.
*
* @param {string} actor actor id (used as request id)
* @param {string} method identifier of the data we want to fetch
*
* @return {Promise} return a promise resolved when data is received.
*/
async _requestData(actor, method) {
// Calculate real name of the client getter.
let clientMethodName = "get" + method.charAt(0).toUpperCase() +
method.slice(1);
// The name of the callback that processes request response
let callbackMethodName = "on" + method.charAt(0).toUpperCase() +
method.slice(1);
// And the event to fire before updating this data
let updatingEventName = "UPDATING_" + method.replace(/([A-Z])/g, "_$1").toUpperCase();
if (typeof this.webConsoleClient[clientMethodName] == "function") {
// Emit event that tell we just start fetching some data
emit(EVENTS[updatingEventName], actor);
// Do a RDP request to fetch data from the actor.
let response = await this.webConsoleClient[clientMethodName](actor);
// Call data processing method.
response = await this[callbackMethodName](response);
return response;
}
throw new Error("Error: No such client method '" + clientMethodName + "'!");
}
/**
* Handles additional information received for a "requestHeaders" packet.
*
@ -634,20 +587,16 @@ class FirefoxDataProvider {
}
/**
* Handles additional information received via "getResponseContent" request.
* Handles additional information received for a "responseContent" packet.
*
* @param {object} data the message received from the server event.
* @param {object} response the message received from the server.
*/
async onResponseContent(response) {
let payload = await this.updateRequest(response.from, {
// We have to ensure passing mimeType as fetchResponseContent needs it from
// updateRequest. It will convert the LongString in `response.content.text` to a
// string.
mimeType: response.content.mimeType,
responseContent: response,
onResponseContent(data, response) {
let payload = Object.assign({ responseContent: response }, data);
return this.updateRequest(response.from, payload).then(() => {
emit(EVENTS.RECEIVED_RESPONSE_CONTENT, response.from);
});
emit(EVENTS.RECEIVED_RESPONSE_CONTENT, response.from);
return payload.responseContent;
}
/**

Просмотреть файл

@ -25,7 +25,6 @@ class Connector {
this.setPreferences = this.setPreferences.bind(this);
this.triggerActivity = this.triggerActivity.bind(this);
this.viewSourceInDebugger = this.viewSourceInDebugger.bind(this);
this.requestData = this.requestData.bind(this);
}
// Connect/Disconnect API
@ -99,10 +98,6 @@ class Connector {
viewSourceInDebugger() {
return this.connector.viewSourceInDebugger(...arguments);
}
requestData() {
return this.connector.requestData(...arguments);
}
}
module.exports.Connector = Connector;

Просмотреть файл

@ -124,7 +124,6 @@ const UPDATE_PROPS = [
"responseHeaders",
"responseCookies",
"responseContent",
"responseContentAvailable",
"responseContentDataUri",
"formDataSections",
];

Просмотреть файл

@ -58,7 +58,7 @@ const Request = I.Record({
responseHeaders: undefined,
responseCookies: undefined,
responseContent: undefined,
responseContentAvailable: false,
responseContentDataUri: undefined,
formDataSections: undefined,
});

Просмотреть файл

@ -27,13 +27,11 @@ function RequestListContextMenu({
getLongString,
getTabTarget,
openStatistics,
requestData,
}) {
this.cloneSelectedRequest = cloneSelectedRequest;
this.getLongString = getLongString;
this.getTabTarget = getTabTarget;
this.openStatistics = openStatistics;
this.requestData = requestData;
}
RequestListContextMenu.prototype = {
@ -116,7 +114,10 @@ RequestListContextMenu.prototype = {
id: "request-list-context-copy-response",
label: L10N.getStr("netmonitor.context.copyResponse"),
accesskey: L10N.getStr("netmonitor.context.copyResponse.accesskey"),
visible: !!(selectedRequest && selectedRequest.responseContentAvailable),
visible: !!(selectedRequest &&
selectedRequest.responseContent &&
selectedRequest.responseContent.content.text &&
selectedRequest.responseContent.content.text.length !== 0),
click: () => this.copyResponse(),
});
@ -125,8 +126,8 @@ RequestListContextMenu.prototype = {
label: L10N.getStr("netmonitor.context.copyImageAsDataUri"),
accesskey: L10N.getStr("netmonitor.context.copyImageAsDataUri.accesskey"),
visible: !!(selectedRequest &&
selectedRequest.mimeType &&
selectedRequest.mimeType.includes("image/")),
selectedRequest.responseContent &&
selectedRequest.responseContent.content.mimeType.includes("image/")),
click: () => this.copyImageAsDataUri(),
});
@ -163,8 +164,8 @@ RequestListContextMenu.prototype = {
label: L10N.getStr("netmonitor.context.saveImageAs"),
accesskey: L10N.getStr("netmonitor.context.saveImageAs.accesskey"),
visible: !!(selectedRequest &&
selectedRequest.mimeType &&
selectedRequest.mimeType.includes("image/")),
selectedRequest.responseContent &&
selectedRequest.responseContent.content.mimeType.includes("image/")),
click: () => this.saveImageAs(),
});
@ -199,8 +200,8 @@ RequestListContextMenu.prototype = {
label: L10N.getStr("netmonitor.context.openInDebugger"),
accesskey: L10N.getStr("netmonitor.context.openInDebugger.accesskey"),
visible: !!(selectedRequest &&
selectedRequest.mimeType &&
selectedRequest.mimeType.includes("javascript")),
selectedRequest.responseContent &&
selectedRequest.responseContent.content.mimeType.includes("javascript")),
click: () => this.openInDebugger()
});
@ -209,9 +210,9 @@ RequestListContextMenu.prototype = {
label: L10N.getStr("netmonitor.context.openInStyleEditor"),
accesskey: L10N.getStr("netmonitor.context.openInStyleEditor.accesskey"),
visible: !!(selectedRequest &&
selectedRequest.responseContent &&
Services.prefs.getBoolPref("devtools.styleeditor.enabled") &&
selectedRequest.mimeType &&
selectedRequest.mimeType.includes("css")),
selectedRequest.responseContent.content.mimeType.includes("css")),
click: () => this.openInStyleEditor()
});
@ -337,18 +338,15 @@ RequestListContextMenu.prototype = {
/**
* Copy image as data uri.
*/
async copyImageAsDataUri() {
await this.requestData(this.selectedRequest.id, "responseContent");
copyImageAsDataUri() {
copyString(this.selectedRequest.responseContentDataUri);
},
/**
* Save image as.
*/
async saveImageAs() {
let responseContent = await this.requestData(this.selectedRequest.id,
"responseContent");
let { encoding, text } = responseContent.content;
saveImageAs() {
let { encoding, text } = this.selectedRequest.responseContent.content;
let fileName = getUrlBaseName(this.selectedRequest.url);
let data;
if (encoding === "base64") {
@ -366,10 +364,8 @@ RequestListContextMenu.prototype = {
/**
* Copy response data as a string.
*/
async copyResponse() {
let responseContent = await this.requestData(this.selectedRequest.id,
"responseContent");
copyString(responseContent.content.text);
copyResponse() {
copyString(this.selectedRequest.responseContent.content.text);
},
/**

Просмотреть файл

@ -13,21 +13,20 @@ const { formDataURI } = require("./utils/request-utils");
const REQUESTS_TOOLTIP_IMAGE_MAX_DIM = 400; // px
async function setTooltipImageContent(connector, tooltip, itemEl, requestItem) {
let { mimeType } = requestItem;
let { mimeType, text, encoding } = requestItem.responseContent.content;
if (!mimeType || !mimeType.includes("image/")) {
return false;
}
let responseContent = await connector.requestData(requestItem.id, "responseContent");
let { encoding, text } = responseContent.content;
let src = formDataURI(mimeType, encoding, text);
let string = await connector.getLongString(text);
let src = formDataURI(mimeType, encoding, string);
let maxDim = REQUESTS_TOOLTIP_IMAGE_MAX_DIM;
let { naturalWidth, naturalHeight } = await getImageDimensions(tooltip.doc, src);
let options = { maxDim, naturalWidth, naturalHeight };
setImageTooltip(tooltip, tooltip.doc, src, options);
return itemEl.querySelector(".requests-list-file");
return itemEl.querySelector(".requests-list-icon");
}
module.exports = {

Просмотреть файл

@ -4,7 +4,6 @@ subsuite = devtools
support-files =
dropmarker.svg
head.js
shared-head.js
html_cause-test-page.html
html_content-type-without-cache-test-page.html
html_brotli-test-page.html
@ -122,6 +121,7 @@ skip-if = (os == 'linux' && debug && bits == 32) # Bug 1303439
[browser_net_footer-summary.js]
[browser_net_headers-alignment.js]
[browser_net_headers_sorted.js]
[browser_net_icon-preview.js]
[browser_net_image-tooltip.js]
[browser_net_json-b64.js]
[browser_net_json-null.js]
@ -175,6 +175,7 @@ skip-if = true # Bug 1258809
[browser_net_status-codes.js]
[browser_net_streaming-response.js]
[browser_net_throttle.js]
[browser_net_thumbnail-click.js]
[browser_net_timeline_ticks.js]
skip-if = true # TODO: fix the test
[browser_net_timing-division.js]

Просмотреть файл

@ -10,7 +10,7 @@
add_task(function* () {
requestLongerTimeout(4);
let { tab, monitor } = yield initNetMonitor(INFINITE_GET_URL, true);
let { monitor } = yield initNetMonitor(INFINITE_GET_URL, true);
let { document, windowRequire, store } = monitor.panelWin;
let Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
@ -57,11 +57,6 @@ add_task(function* () {
let headersHeight = requestsContainerHeaders.offsetHeight;
is(requestsContainer.scrollTop, headersHeight, "Did not scroll.");
// Stop doing requests.
yield ContentTask.spawn(tab.linkedBrowser, {}, function () {
content.wrappedJSObject.stopRequests();
});
// Done: clean up.
return teardown(monitor);

Просмотреть файл

@ -51,13 +51,11 @@ add_task(function* () {
});
wait = waitForDOM(document, ".CodeMirror-code");
let onResponseContent = monitor.panelWin.once(EVENTS.RECEIVED_RESPONSE_CONTENT);
EventUtils.sendMouseEvent({ type: "click" },
document.querySelector(".network-details-panel-toggle"));
EventUtils.sendMouseEvent({ type: "click" },
document.querySelector("#response-tab"));
yield wait;
yield onResponseContent;
yield testResponse("br");
yield teardown(monitor);

Просмотреть файл

@ -13,6 +13,7 @@ add_task(function* () {
let { document, store, windowRequire } = monitor.panelWin;
let Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
let { EVENTS } = windowRequire("devtools/client/netmonitor/src/constants");
let detailsPanelToggleButton = document.querySelector(".network-details-panel-toggle");
let clearButton = document.querySelector(".requests-list-clear-button");
@ -22,9 +23,9 @@ add_task(function* () {
assertNoRequestState();
// Load one request and assert it shows up in the list
let onMonitorUpdated = waitForAllRequestsFinished(monitor);
let networkEvent = monitor.panelWin.once(EVENTS.NETWORK_EVENT);
tab.linkedBrowser.reload();
yield onMonitorUpdated;
yield networkEvent;
assertSingleRequestState();
@ -33,9 +34,9 @@ add_task(function* () {
assertNoRequestState();
// Load a second request and make sure they still show up
onMonitorUpdated = waitForAllRequestsFinished(monitor);
networkEvent = monitor.panelWin.once(EVENTS.NETWORK_EVENT);
tab.linkedBrowser.reload();
yield onMonitorUpdated;
yield networkEvent;
assertSingleRequestState();

Просмотреть файл

@ -22,7 +22,7 @@ add_task(function* () {
store.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, CONTENT_TYPE_WITHOUT_CACHE_REQUESTS);
yield ContentTask.spawn(tab.linkedBrowser, {}, function () {
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
@ -142,25 +142,25 @@ add_task(function* () {
}
);
yield selectIndexAndWaitForSourceEditor(monitor, 0);
yield selectIndexAndWaitForSourceEditor(0);
yield testResponseTab("xml");
yield selectIndexAndWaitForSourceEditor(monitor, 1);
yield selectIndexAndWaitForSourceEditor(1);
yield testResponseTab("css");
yield selectIndexAndWaitForSourceEditor(monitor, 2);
yield selectIndexAndWaitForSourceEditor(2);
yield testResponseTab("js");
yield selectIndexAndWaitForJSONView(3);
yield testResponseTab("json");
yield selectIndexAndWaitForSourceEditor(monitor, 4);
yield selectIndexAndWaitForSourceEditor(4);
yield testResponseTab("html");
yield selectIndexAndWaitForImageView(5);
yield testResponseTab("png");
yield selectIndexAndWaitForSourceEditor(monitor, 6);
yield selectIndexAndWaitForSourceEditor(6);
yield testResponseTab("gzip");
yield teardown(monitor);
@ -270,26 +270,32 @@ add_task(function* () {
}
}
function* selectIndexAndWaitForSourceEditor(index) {
let editor = document.querySelector("#response-panel .CodeMirror-code");
if (!editor) {
let waitDOM = waitForDOM(document, "#response-panel .CodeMirror-code");
EventUtils.sendMouseEvent({ type: "mousedown" },
document.querySelectorAll(".request-list-item")[index]);
document.querySelector("#response-tab").click();
yield waitDOM;
} else {
EventUtils.sendMouseEvent({ type: "mousedown" },
document.querySelectorAll(".request-list-item")[index]);
}
}
function* selectIndexAndWaitForJSONView(index) {
let onResponseContent = monitor.panelWin.once(EVENTS.RECEIVED_RESPONSE_CONTENT);
let tabpanel = document.querySelector("#response-panel");
let waitDOM = waitForDOM(tabpanel, ".treeTable");
store.dispatch(Actions.selectRequestByIndex(index));
yield waitDOM;
yield onResponseContent;
// Waiting for RECEIVED_RESPONSE_CONTENT isn't enough.
// DOM may not be fully updated yet and checkVisibility(json) may still fail.
yield waitForTick();
}
function* selectIndexAndWaitForImageView(index) {
let onResponseContent = monitor.panelWin.once(EVENTS.RECEIVED_RESPONSE_CONTENT);
let tabpanel = document.querySelector("#response-panel");
let waitDOM = waitForDOM(tabpanel, ".response-image");
store.dispatch(Actions.selectRequestByIndex(index));
let [imageNode] = yield waitDOM;
yield once(imageNode, "load");
yield onResponseContent;
}
});

Просмотреть файл

@ -10,7 +10,7 @@
add_task(function* () {
requestLongerTimeout(4);
let { tab, monitor } = yield initNetMonitor(INFINITE_GET_URL, true);
let { monitor } = yield initNetMonitor(INFINITE_GET_URL, true);
let { document, windowRequire, store } = monitor.panelWin;
let Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
@ -40,11 +40,6 @@ add_task(function* () {
);
}
// Stop doing requests.
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.stopRequests();
});
// Done: clean up.
return teardown(monitor);

Просмотреть файл

@ -0,0 +1,68 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests if image responses show a thumbnail in the requests menu.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(CONTENT_TYPE_WITHOUT_CACHE_URL);
const SELECTOR = ".requests-list-icon[src]";
info("Starting test... ");
let { document, store, windowRequire, connector } = monitor.panelWin;
let Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
let { triggerActivity } = connector;
let { ACTIVITY_TYPE } = windowRequire("devtools/client/netmonitor/src/constants");
store.dispatch(Actions.batchEnable(false));
let wait = waitForNetworkEvents(monitor, CONTENT_TYPE_WITHOUT_CACHE_REQUESTS);
yield performRequests();
yield wait;
yield waitUntil(() => !!document.querySelector(SELECTOR));
info("Checking the image thumbnail when all items are shown.");
checkImageThumbnail();
store.dispatch(Actions.sortBy("contentSize"));
info("Checking the image thumbnail when all items are sorted.");
checkImageThumbnail();
store.dispatch(Actions.toggleRequestFilterType("images"));
info("Checking the image thumbnail when only images are shown.");
checkImageThumbnail();
info("Reloading the debuggee and performing all requests again...");
wait = waitForNetworkEvents(monitor, CONTENT_TYPE_WITHOUT_CACHE_REQUESTS);
yield reloadAndPerformRequests();
yield wait;
yield waitUntil(() => !!document.querySelector(SELECTOR));
info("Checking the image thumbnail after a reload.");
checkImageThumbnail();
yield teardown(monitor);
function performRequests() {
return ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
}
function* reloadAndPerformRequests() {
yield triggerActivity(ACTIVITY_TYPE.RELOAD.WITH_CACHE_ENABLED);
yield performRequests();
}
function checkImageThumbnail() {
is(document.querySelectorAll(SELECTOR).length, 1,
"There should be only one image request with a thumbnail displayed.");
is(document.querySelector(SELECTOR).src, TEST_IMAGE_DATA_URI,
"The image requests-list-icon thumbnail is displayed correctly.");
is(document.querySelector(SELECTOR).hidden, false,
"The image requests-list-icon thumbnail should not be hidden.");
}
});

Просмотреть файл

@ -11,6 +11,7 @@ const IMAGE_TOOLTIP_REQUESTS = 1;
*/
add_task(function* test() {
let { tab, monitor } = yield initNetMonitor(IMAGE_TOOLTIP_URL);
const SELECTOR = ".requests-list-icon[src]";
info("Starting test... ");
let { document, store, windowRequire, connector } = monitor.panelWin;
@ -24,6 +25,7 @@ add_task(function* test() {
let onEvents = waitForNetworkEvents(monitor, IMAGE_TOOLTIP_REQUESTS);
yield performRequests();
yield onEvents;
yield waitUntil(() => !!document.querySelector(SELECTOR));
info("Checking the image thumbnail after a few requests were made...");
yield showTooltipAndVerify(document.querySelectorAll(".request-list-item")[0]);
@ -40,6 +42,7 @@ add_task(function* test() {
yield triggerActivity(ACTIVITY_TYPE.RELOAD.WITH_CACHE_ENABLED);
yield performRequests();
yield onEvents;
yield waitUntil(() => !!document.querySelector(SELECTOR));
info("Checking the image thumbnail after a reload.");
yield showTooltipAndVerify(document.querySelectorAll(".request-list-item")[1]);
@ -63,7 +66,7 @@ add_task(function* test() {
* with the expected content.
*/
function* showTooltipAndVerify(target) {
let anchor = target.querySelector(".requests-list-file");
let anchor = target.querySelector(".requests-list-icon");
yield showTooltipOn(anchor);
info("Tooltip was successfully opened for the image request.");

Просмотреть файл

@ -56,23 +56,19 @@ add_task(function* () {
yield onRequests;
// Check the resent requests
for (let i = 0; i < ITEMS.length; i++) {
let item = ITEMS[i];
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`);
is(item.status, 200, `The ${item.method} response has the right status`);
if (item.method === "POST") {
// Force fetching response content
let responseContent = yield connector.requestData(item.id, "responseContent");
is(item.requestPostData.postData.text, "post-data",
"The POST request has the right POST data");
// eslint-disable-next-line mozilla/no-cpows-in-tests
is(responseContent.content.text, "Access-Control-Allow-Origin: *",
is(item.responseContent.content.text, "Access-Control-Allow-Origin: *",
"The POST response has the right content");
}
}
});
info("Finishing the test");
return teardown(monitor);

Просмотреть файл

@ -47,6 +47,9 @@ add_task(function* () {
"RECEIVED_REQUEST_HEADERS",
"UPDATING_REQUEST_COOKIES",
"RECEIVED_REQUEST_COOKIES",
"STARTED_RECEIVING_RESPONSE",
"UPDATING_RESPONSE_CONTENT",
"RECEIVED_RESPONSE_CONTENT",
"UPDATING_EVENT_TIMINGS",
"RECEIVED_EVENT_TIMINGS",
"UPDATING_SECURITY_INFO",

Просмотреть файл

@ -80,7 +80,7 @@ add_task(function* () {
yield executeRequests(1, "https://example.com" + CORS_SJS_PATH);
yield done;
done = waitForSecurityBrokenNetworkEvent();
done = waitForSecurityBrokenNetworkEvent(true);
info("Requesting a resource over HTTP to localhost.");
yield executeRequests(1, "http://localhost" + CORS_SJS_PATH);
yield done;
@ -95,16 +95,25 @@ add_task(function* () {
* Returns a promise that's resolved once a request with security issues is
* completed.
*/
function waitForSecurityBrokenNetworkEvent() {
function waitForSecurityBrokenNetworkEvent(networkError) {
let awaitedEvents = [
"UPDATING_REQUEST_HEADERS",
"RECEIVED_REQUEST_HEADERS",
"UPDATING_REQUEST_COOKIES",
"RECEIVED_REQUEST_COOKIES",
"STARTED_RECEIVING_RESPONSE",
"UPDATING_RESPONSE_CONTENT",
"RECEIVED_RESPONSE_CONTENT",
"UPDATING_EVENT_TIMINGS",
"RECEIVED_EVENT_TIMINGS",
];
// If the reason for breakage is a network error, then the
// STARTED_RECEIVING_RESPONSE event does not fire.
if (networkError) {
awaitedEvents = awaitedEvents.filter(e => e !== "STARTED_RECEIVING_RESPONSE");
}
let promises = awaitedEvents.map((event) => {
return monitor.panelWin.once(EVENTS[event]);
});

Просмотреть файл

@ -98,6 +98,9 @@ add_task(function* () {
"RECEIVED_REQUEST_HEADERS",
"UPDATING_REQUEST_COOKIES",
"RECEIVED_REQUEST_COOKIES",
"STARTED_RECEIVING_RESPONSE",
"UPDATING_RESPONSE_CONTENT",
"RECEIVED_RESPONSE_CONTENT",
"UPDATING_EVENT_TIMINGS",
"RECEIVED_EVENT_TIMINGS",
];

Просмотреть файл

@ -250,13 +250,14 @@ function test() {
);
});
expectEvent(EVENTS.PAYLOAD_READY, async () => {
expectEvent(EVENTS.RECEIVED_RESPONSE_CONTENT, async () => {
await waitUntil(() => {
let requestItem = getSortedRequests(store.getState()).get(0);
return requestItem &&
requestItem.transferredSize &&
requestItem.contentSize &&
requestItem.mimeType;
requestItem.mimeType &&
requestItem.responseContent;
});
let requestItem = getSortedRequests(store.getState()).get(0);
@ -268,6 +269,21 @@ function test() {
is(requestItem.mimeType, "text/plain; charset=utf-8",
"The mimeType data has an incorrect value.");
ok(requestItem.responseContent,
"There should be a responseContent data available.");
// eslint-disable-next-line mozilla/no-cpows-in-tests
is(requestItem.responseContent.content.mimeType,
"text/plain; charset=utf-8",
"The responseContent data has an incorrect |content.mimeType| property.");
// eslint-disable-next-line mozilla/no-cpows-in-tests
is(requestItem.responseContent.content.text,
"Hello world!",
"The responseContent data has an incorrect |content.text| property.");
// eslint-disable-next-line mozilla/no-cpows-in-tests
is(requestItem.responseContent.content.size,
12,
"The responseContent data has an incorrect |content.size| property.");
verifyRequestItemTarget(
document,
getDisplayedRequests(store.getState()),

Просмотреть файл

@ -65,16 +65,30 @@ add_task(function* () {
store.dispatch(Actions.selectRequest(null));
yield selectIndexAndWaitForSourceEditor(monitor, 0);
yield selectIndexAndWaitForSourceEditor(0);
// the hls-m3u8 part
testEditorContent(REQUESTS[0]);
yield selectIndexAndWaitForSourceEditor(monitor, 1);
yield selectIndexAndWaitForSourceEditor(1);
// the mpeg-dash part
testEditorContent(REQUESTS[1]);
return teardown(monitor);
function* selectIndexAndWaitForSourceEditor(index) {
let editor = document.querySelector("#response-panel .CodeMirror-code");
if (!editor) {
let waitDOM = waitForDOM(document, "#response-panel .CodeMirror-code");
EventUtils.sendMouseEvent({ type: "mousedown" },
document.querySelectorAll(".request-list-item")[index]);
document.querySelector("#response-tab").click();
yield waitDOM;
} else {
EventUtils.sendMouseEvent({ type: "mousedown" },
document.querySelectorAll(".request-list-item")[index]);
}
}
function testEditorContent([ fmt, textRe ]) {
ok(document.querySelector(".CodeMirror-line").textContent.match(textRe),
"The text shown in the source editor for " + fmt + " is correct.");

Просмотреть файл

@ -0,0 +1,40 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Test that clicking on the file thumbnail opens the response details tab.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(CONTENT_TYPE_WITHOUT_CACHE_URL);
let { document } = monitor.panelWin;
yield performRequestsAndWait();
let wait = waitForDOM(document, "#response-panel");
let request = document.querySelectorAll(".request-list-item")[5];
let icon = request.querySelector(".requests-list-icon");
info("Clicking thumbnail of the sixth request.");
EventUtils.synthesizeMouseAtCenter(icon, {}, monitor.panelWin);
yield wait;
ok(document.querySelector("#response-tab[aria-selected=true]"),
"Response tab is selected.");
ok(document.querySelector(".response-image-box"),
"Response image preview is shown.");
yield teardown(monitor);
function* performRequestsAndWait() {
let onAllEvents = waitForNetworkEvents(monitor, CONTENT_TYPE_WITHOUT_CACHE_REQUESTS);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield onAllEvents;
}
});

Просмотреть файл

@ -2,10 +2,9 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
/* import-globals-from ../../framework/test/shared-head.js */
/* import-globals-from shared-head.js */
/* exported Toolbox, restartNetMonitor, teardown, waitForExplicitFinish,
verifyRequestItemTarget, waitFor, testFilterButtons, loadCommonFrameScript,
performRequestsInContent, waitForNetworkEvents, selectIndexAndWaitForSourceEditor */
performRequestsInContent, waitForNetworkEvents */
"use strict";
@ -14,10 +13,7 @@ Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/framework/test/shared-head.js",
this);
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/netmonitor/test/shared-head.js",
this);
const { EVENTS } = require("devtools/client/netmonitor/src/constants");
const {
getFormattedIPAndPort,
getFormattedTime,
@ -285,12 +281,6 @@ function teardown(monitor) {
return Task.spawn(function* () {
let tab = monitor.toolbox.target.tab;
// Ensure that there is no pending RDP requests related to payload request
// done from FirefoxDataProvider.
info("Wait for completion of all pending RDP requests...");
yield waitForExistingRequests(monitor);
info("All pending requests finished.");
let onDestroyed = monitor.once("destroyed");
yield removeTab(tab);
yield onDestroyed;
@ -316,14 +306,13 @@ function waitForNetworkEvents(monitor, getRequests, postRequests = 0) {
["RECEIVED_RESPONSE_HEADERS", onGenericEvent],
["UPDATING_RESPONSE_COOKIES", onGenericEvent],
["RECEIVED_RESPONSE_COOKIES", onGenericEvent],
["STARTED_RECEIVING_RESPONSE", onGenericEvent],
["UPDATING_RESPONSE_CONTENT", onGenericEvent],
["RECEIVED_RESPONSE_CONTENT", onGenericEvent],
["UPDATING_EVENT_TIMINGS", onGenericEvent],
["RECEIVED_EVENT_TIMINGS", onGenericEvent],
["PAYLOAD_READY", onPayloadReady]
];
let expectedGenericEvents = awaitedEventsToListeners
.filter(([, listener]) => listener == onGenericEvent).length;
let expectedPostEvents = awaitedEventsToListeners
.filter(([, listener]) => listener == onPostEvent).length;
function initProgressForURL(url) {
if (progress[url]) {
@ -376,10 +365,8 @@ function waitForNetworkEvents(monitor, getRequests, postRequests = 0) {
function maybeResolve(event, actor, networkInfo) {
info("> Network events progress: " +
"Payload: " + payloadReady + "/" + (getRequests + postRequests) + ", " +
"Generic: " + genericEvents + "/" +
((getRequests + postRequests) * expectedGenericEvents) + ", " +
"Post: " + postEvents + "/" + (postRequests * expectedPostEvents) + ", " +
genericEvents + "/" + ((getRequests + postRequests) * 13) + ", " +
postEvents + "/" + (postRequests * 2) + ", " +
"got " + event + " for " + actor);
let url = networkInfo.request.url;
@ -388,12 +375,12 @@ function waitForNetworkEvents(monitor, getRequests, postRequests = 0) {
// Uncomment this to get a detailed progress logging (when debugging a test)
// info("> Current state: " + JSON.stringify(progress, null, 2));
// There are `expectedGenericEvents` updates which need to be fired for a request
// to be considered finished. The "requestPostData" packet isn't fired for non-POST
// requests.
// 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 (payloadReady >= (getRequests + postRequests) &&
genericEvents >= (getRequests + postRequests) * expectedGenericEvents &&
postEvents >= postRequests * expectedPostEvents) {
genericEvents >= (getRequests + postRequests) * 13 &&
postEvents >= postRequests * 2) {
awaitedEventsToListeners.forEach(([e, l]) => panel.off(EVENTS[e], l));
executeSoon(resolve);
}
@ -697,25 +684,3 @@ function waitForContentMessage(name) {
});
});
}
/**
* Select a request and switch to its response panel.
*
* @param {Number} index The request index to be selected
*/
async function selectIndexAndWaitForSourceEditor(monitor, index) {
let document = monitor.panelWin.document;
let onResponseContent = monitor.panelWin.once(EVENTS.RECEIVED_RESPONSE_CONTENT);
// Select the request first, as it may try to fetch whatever is the current request's
// responseContent if we select the ResponseTab first.
EventUtils.sendMouseEvent({ type: "mousedown" },
document.querySelectorAll(".request-list-item")[index]);
// We may already be on the ResponseTab, so only select it if needed.
let editor = document.querySelector("#response-panel .CodeMirror-code");
if (!editor) {
let waitDOM = waitForDOM(document, "#response-panel .CodeMirror-code");
document.querySelector("#response-tab").click();
await waitDOM;
}
await onResponseContent;
}

Просмотреть файл

@ -31,16 +31,10 @@
// Use a count parameter to defeat caching.
let count = 0;
let doRequests = true;
function stopRequests() { // eslint-disable-line no-unused-vars
doRequests = false;
}
(function performRequests() {
get("request_" + (count++), function () {
if (doRequests) {
setTimeout(performRequests, 50);
}
setTimeout(performRequests, 50);
});
})();
</script>

Просмотреть файл

@ -1,43 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/* exported EVENTS, waitForExistingRequests */
"use strict";
const { EVENTS } = require("devtools/client/netmonitor/src/constants");
async function waitForExistingRequests(monitor) {
let { store } = monitor.panelWin;
function getRequests() {
return store.getState().requests.requests;
}
function areAllRequestsFullyLoaded() {
let requests = getRequests().valueSeq();
for (let request of requests) {
// Ignore cloned request as we don't lazily fetch data for them
// and have arbitrary number of field set.
if (request.id.includes("-clone")) {
continue;
}
// Do same check than FirefoxDataProvider.isRequestPayloadReady,
// in order to ensure there is no more pending payload requests to be done.
if (!request.requestHeaders || !request.requestCookies ||
!request.eventTimings ||
(!request.securityInfo && !request.fromServiceWorker) ||
((!request.responseHeaders || !request.responseCookies) &&
request.securityState != "broken" &&
(!request.responseContentAvailable || request.status))) {
return false;
}
}
return true;
}
// If there is no request, we are good to go.
if (getRequests().size == 0) {
return;
}
while (!areAllRequestsFullyLoaded()) {
await monitor.panelWin.once(EVENTS.PAYLOAD_READY);
}
}

Просмотреть файл

@ -58,7 +58,6 @@ support-files =
!/devtools/client/inspector/shared/test/head.js
!/devtools/client/inspector/test/head.js
!/devtools/client/inspector/test/shared-head.js
!/devtools/client/netmonitor/test/shared-head.js
!/devtools/client/responsive.html/test/browser/devices.json
!/devtools/client/shared/test/test-actor-registry.js
!/devtools/client/shared/test/test-actor.js

Просмотреть файл

@ -3,14 +3,9 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/* import-globals-from ../../netmonitor/test/shared-head.js */
// A test to ensure Style Editor doesn't bybass cache when loading style sheet
// contents (bug 978688).
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/netmonitor/test/shared-head.js", this);
const TEST_URL = TEST_BASE_HTTP + "doc_uncached.html";
add_task(function* () {
@ -39,8 +34,6 @@ add_task(function* () {
info("Waiting for the source to be loaded.");
yield styleeditor.UI.editors[0].getSourceEditor();
yield waitForExistingRequests(monitor);
info("Checking Netmonitor contents.");
let items = [];
for (let item of getSortedRequests(store.getState())) {

Просмотреть файл

@ -116,9 +116,6 @@ function NetworkEventMessage({
sendHTTPRequest: () => {},
setPreferences: () => {},
triggerActivity: () => {},
requestData: (requestId, dataType) => {
return serviceContainer.requestData(requestId, dataType);
},
};
// Only render the attachment if the network-event is

Просмотреть файл

@ -96,9 +96,6 @@ NewConsoleOutputWrapper.prototype = {
getLongString: (grip) => {
return hud.proxy.webConsoleClient.getString(grip);
},
requestData(id, type) {
return hud.proxy.networkDataProvider.requestData(id, type);
},
};
// Set `openContextMenu` this way so, `serviceContainer` variable

Просмотреть файл

@ -177,13 +177,6 @@ function enableNetProvider(hud) {
actions,
webConsoleClient: proxy.webConsoleClient
});
// /!\ This is terrible, but it allows ResponsePanel to be able to call
// `dataProvider.requestData` to fetch response content lazily.
// `proxy.networkDataProvider` is put by NewConsoleOutputWrapper on
// `serviceContainer` which allow NetworkEventMessage to expose requestData on
// the fake `connector` object it hands over to ResponsePanel.
proxy.networkDataProvider = dataProvider;
}
let type = action.type;

Просмотреть файл

@ -64,6 +64,4 @@ async function testNetmonitor(toolbox) {
let item = getSortedRequests(store.getState()).get(0);
is(item.method, "GET", "The attached method is correct.");
is(item.url, TEST_PATH, "The attached url is correct.");
await waitForExistingRequests(monitor);
}

Просмотреть файл

@ -49,8 +49,6 @@ add_task(async function task() {
info("network-request-payload-ready received");
await testNetworkMessage(messageNode);
await waitForExistingRequests(monitor);
});
async function testNetworkMessage(messageNode) {

Просмотреть файл

@ -75,7 +75,4 @@ async function testNetmonitorLink(toolbox, hud, url) {
});
ok(true, "The attached url is correct.");
let monitor = toolbox.getCurrentPanel();
await waitForExistingRequests(monitor);
}

Просмотреть файл

@ -3,7 +3,6 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* import-globals-from ../../../../framework/test/shared-head.js */
/* import-globals-from ../../../../netmonitor/test/shared-head.js */
/* exported WCUL10n, openNewTabAndConsole, waitForMessages, waitForMessage, waitFor,
findMessage, openContextMenu, hideContextMenu, loadDocument, hasFocus,
waitForNodeMutation, testOpenInDebugger, checkClickOnNode, jstermSetValueAndComplete,
@ -17,9 +16,6 @@ Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/framework/test/shared-head.js",
this);
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/netmonitor/test/shared-head.js", this);
var {HUDService} = require("devtools/client/webconsole/hudservice");
var WCUL10n = require("devtools/client/webconsole/webconsole-l10n");

Просмотреть файл

@ -5,9 +5,6 @@
"use strict";
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/netmonitor/test/shared-head.js", this);
const TEST_URI = "data:text/html;charset=utf8,Test that the netmonitor " +
"displays requests that have been recorded in the " +
"web console, even if the netmonitor hadn't opened yet.";
@ -79,6 +76,4 @@ function* testNetmonitor(toolbox) {
let item = getSortedRequests(store.getState()).get(0);
is(item.method, "GET", "The attached method is correct.");
is(item.url, TEST_PATH, "The attached url is correct.");
yield waitForExistingRequests(monitor);
}

Просмотреть файл

@ -2,8 +2,6 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* import-globals-from ../../netmonitor/test/shared-head.js */
// Tests that network log messages bring up the network panel.
"use strict";
@ -12,9 +10,6 @@ const TEST_NETWORK_REQUEST_URI =
"http://example.com/browser/devtools/client/webconsole/test/" +
"test-network-request.html";
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/netmonitor/test/shared-head.js", this);
add_task(function* () {
let finishedRequest = waitForFinishedRequest(({ request }) => {
return request.url.endsWith("test-network-request.html");
@ -26,9 +21,9 @@ add_task(function* () {
yield hud.ui.openNetworkPanel(request.actor);
let toolbox = gDevTools.getToolbox(hud.target);
is(toolbox.currentToolId, "netmonitor", "Network panel was opened");
let monitor = toolbox.getCurrentPanel();
let panel = toolbox.getCurrentPanel();
let { store, windowRequire } = monitor.panelWin;
let { store, windowRequire } = panel.panelWin;
let { getSelectedRequest } = windowRequire("devtools/client/netmonitor/src/selectors/index");
let selected = getSelectedRequest(store.getState());
@ -36,6 +31,4 @@ add_task(function* () {
"The correct request is selected");
is(selected.url, request.request.url,
"The correct request is definitely selected");
yield waitForExistingRequests(monitor);
});

Просмотреть файл

@ -3,8 +3,6 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* import-globals-from ../../netmonitor/test/shared-head.js */
// Tests that network log messages bring up the network panel and select the
// right request even if it was previously filtered off.
@ -15,9 +13,6 @@ const TEST_FILE_URI =
"test-network.html";
const TEST_URI = "data:text/html;charset=utf8,<p>test file URI";
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/netmonitor/test/shared-head.js", this);
var hud;
add_task(function* () {
@ -42,8 +37,8 @@ add_task(function* () {
let toolbox = gDevTools.getToolbox(hud.target);
is(toolbox.currentToolId, "netmonitor", "Network panel was opened");
let monitor = toolbox.getCurrentPanel();
let { store, windowRequire } = monitor.panelWin;
let panel = toolbox.getCurrentPanel();
let { store, windowRequire } = panel.panelWin;
let Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
let { getSelectedRequest } = windowRequire("devtools/client/netmonitor/src/selectors/index");
@ -69,8 +64,6 @@ add_task(function* () {
// All tests are done. Shutdown.
HUDService.lastFinishedRequest.callback = null;
htmlRequest = browser = requests = hud = null;
yield waitForExistingRequests(monitor);
});
function testMessages() {