зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1662736 - [devtools] Simplify the network request payload r=ochameau
Differential Revision: https://phabricator.services.mozilla.com/D94457
This commit is contained in:
Родитель
0951f9218a
Коммит
a70ec38159
|
@ -325,12 +325,12 @@ class FirefoxConnector {
|
||||||
}
|
}
|
||||||
|
|
||||||
navigate() {
|
navigate() {
|
||||||
if (this.dataProvider.isPayloadQueueEmpty()) {
|
if (!this.dataProvider.hasPendingRequests()) {
|
||||||
this.onReloaded();
|
this.onReloaded();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const listener = () => {
|
const listener = () => {
|
||||||
if (this.dataProvider && !this.dataProvider.isPayloadQueueEmpty()) {
|
if (this.dataProvider && this.dataProvider.hasPendingRequests()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.owner) {
|
if (this.owner) {
|
||||||
|
|
|
@ -43,8 +43,8 @@ class FirefoxDataProvider {
|
||||||
// Map of the stacktrace information keyed by the actor id's
|
// Map of the stacktrace information keyed by the actor id's
|
||||||
this.stackTraceRequestInfoByActorID = new Map();
|
this.stackTraceRequestInfoByActorID = new Map();
|
||||||
|
|
||||||
// Internal properties
|
// For tracking unfinished requests
|
||||||
this.payloadQueue = new Map();
|
this.pendingRequests = new Set();
|
||||||
|
|
||||||
// Map[key string => Promise] used by `requestData` to prevent requesting the same
|
// Map[key string => Promise] used by `requestData` to prevent requesting the same
|
||||||
// request data twice.
|
// request data twice.
|
||||||
|
@ -84,32 +84,14 @@ class FirefoxDataProvider {
|
||||||
* Add a new network request to application state.
|
* Add a new network request to application state.
|
||||||
*
|
*
|
||||||
* @param {string} id request id
|
* @param {string} id request id
|
||||||
* @param {object} data data payload will be added to application state
|
* @param {object} resource resource payload will be added to application state
|
||||||
*/
|
*/
|
||||||
async addRequest(id, data) {
|
async addRequest(id, resource) {
|
||||||
const { startedDateTime, ...payload } = data;
|
// Add to the pending requests which helps when deciding if the request is complete.
|
||||||
|
this.pendingRequests.add(id);
|
||||||
// Insert blocked reason in the payload queue as well, as we'll need it later
|
|
||||||
// when deciding if the request is complete.
|
|
||||||
this.pushRequestToQueue(id, {
|
|
||||||
blockedReason: payload.blockedReason,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (this.actionsEnabled && this.actions.addRequest) {
|
if (this.actionsEnabled && this.actions.addRequest) {
|
||||||
await this.actions.addRequest(
|
await this.actions.addRequest(id, resource, true);
|
||||||
id,
|
|
||||||
{
|
|
||||||
...payload,
|
|
||||||
// Convert the received date/time string to a unix timestamp.
|
|
||||||
startedMs: Date.parse(startedDateTime),
|
|
||||||
|
|
||||||
// Compatibility code to support Firefox 58 and earlier that always
|
|
||||||
// send stack-trace immediately on networkEvent message.
|
|
||||||
// FF59+ supports fetching the traces lazily via requestData.
|
|
||||||
stacktrace: payload.cause.stacktrace,
|
|
||||||
},
|
|
||||||
true
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.emit(EVENTS.REQUEST_ADDED, id);
|
this.emit(EVENTS.REQUEST_ADDED, id);
|
||||||
|
@ -287,25 +269,10 @@ class FirefoxDataProvider {
|
||||||
/**
|
/**
|
||||||
* Public API used by the Toolbox: Tells if there is still any pending request.
|
* Public API used by the Toolbox: Tells if there is still any pending request.
|
||||||
*
|
*
|
||||||
* @return {boolean} returns true if the payload queue is empty
|
* @return {boolean} returns true if pending requests still exist in the queue.
|
||||||
*/
|
*/
|
||||||
isPayloadQueueEmpty() {
|
hasPendingRequests() {
|
||||||
return this.payloadQueue.size === 0;
|
return this.pendingRequests.size > 0;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Merge upcoming networkEventUpdate payload into existing one.
|
|
||||||
*
|
|
||||||
* @param {string} id request actor id
|
|
||||||
* @param {object} payload request data payload
|
|
||||||
*/
|
|
||||||
pushRequestToQueue(id, payload) {
|
|
||||||
let payloadFromQueue = this.payloadQueue.get(id);
|
|
||||||
if (!payloadFromQueue) {
|
|
||||||
payloadFromQueue = {};
|
|
||||||
this.payloadQueue.set(id, payloadFromQueue);
|
|
||||||
}
|
|
||||||
Object.assign(payloadFromQueue, payload);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -359,22 +326,7 @@ class FirefoxDataProvider {
|
||||||
* @param {object} resource The network event resource
|
* @param {object} resource The network event resource
|
||||||
*/
|
*/
|
||||||
async onNetworkResourceAvailable(resource) {
|
async onNetworkResourceAvailable(resource) {
|
||||||
const {
|
const { actor, stacktraceResourceId } = resource;
|
||||||
actor,
|
|
||||||
cause,
|
|
||||||
fromCache,
|
|
||||||
fromServiceWorker,
|
|
||||||
isXHR,
|
|
||||||
request: { method, url },
|
|
||||||
response: { bodySize, ...responseProps },
|
|
||||||
startedDateTime,
|
|
||||||
isThirdPartyTrackingResource,
|
|
||||||
referrerPolicy,
|
|
||||||
blockedReason,
|
|
||||||
blockingExtension,
|
|
||||||
resourceId,
|
|
||||||
stacktraceResourceId,
|
|
||||||
} = resource;
|
|
||||||
|
|
||||||
// Check if a stacktrace resource exists for this network resource.
|
// Check if a stacktrace resource exists for this network resource.
|
||||||
// The stacktrace event is expected to happen before the network
|
// The stacktrace event is expected to happen before the network
|
||||||
|
@ -385,8 +337,10 @@ class FirefoxDataProvider {
|
||||||
lastFrame,
|
lastFrame,
|
||||||
targetFront,
|
targetFront,
|
||||||
} = this.stackTraces.get(stacktraceResourceId);
|
} = this.stackTraces.get(stacktraceResourceId);
|
||||||
cause.stacktraceAvailable = stacktraceAvailable;
|
|
||||||
cause.lastFrame = lastFrame;
|
resource.cause.stacktraceAvailable = stacktraceAvailable;
|
||||||
|
resource.cause.lastFrame = lastFrame;
|
||||||
|
|
||||||
this.stackTraces.delete(stacktraceResourceId);
|
this.stackTraces.delete(stacktraceResourceId);
|
||||||
// We retrieve preliminary information about the stacktrace from the
|
// We retrieve preliminary information about the stacktrace from the
|
||||||
// NETWORK_EVENT_STACKTRACE resource via `this.stackTraces` Map,
|
// NETWORK_EVENT_STACKTRACE resource via `this.stackTraces` Map,
|
||||||
|
@ -398,45 +352,7 @@ class FirefoxDataProvider {
|
||||||
stacktraceResourceId,
|
stacktraceResourceId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
await this.addRequest(actor, resource);
|
||||||
// For resources from the resource watcher cache no updates are going to be fired
|
|
||||||
// as the resource already contains all the updated props. These need to be set so
|
|
||||||
// the UI knows the data is available on the backend.
|
|
||||||
const available = {};
|
|
||||||
[
|
|
||||||
"eventTimings",
|
|
||||||
"requestHeaders",
|
|
||||||
"requestPostData",
|
|
||||||
"responseHeaders",
|
|
||||||
"responseStart",
|
|
||||||
"responseContent",
|
|
||||||
"securityInfo",
|
|
||||||
"responseCache",
|
|
||||||
"responseCookies",
|
|
||||||
].forEach(updateType => {
|
|
||||||
if (resource.updates.includes(updateType)) {
|
|
||||||
available[`${updateType}Available`] = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
await this.addRequest(actor, {
|
|
||||||
cause,
|
|
||||||
fromCache,
|
|
||||||
fromServiceWorker,
|
|
||||||
isXHR,
|
|
||||||
method,
|
|
||||||
startedDateTime,
|
|
||||||
url,
|
|
||||||
isThirdPartyTrackingResource,
|
|
||||||
referrerPolicy,
|
|
||||||
blockedReason,
|
|
||||||
blockingExtension,
|
|
||||||
resourceId,
|
|
||||||
mimeType: resource?.content?.mimeType,
|
|
||||||
contentSize: bodySize,
|
|
||||||
...responseProps,
|
|
||||||
...available,
|
|
||||||
});
|
|
||||||
this.emitForTests(TEST_EVENTS.NETWORK_EVENT, resource);
|
this.emitForTests(TEST_EVENTS.NETWORK_EVENT, resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,66 +361,23 @@ class FirefoxDataProvider {
|
||||||
*
|
*
|
||||||
* @param {object} resource The updated network event resource.
|
* @param {object} resource The updated network event resource.
|
||||||
*/
|
*/
|
||||||
async onNetworkResourceUpdated(resource, update) {
|
async onNetworkResourceUpdated(resource) {
|
||||||
switch (update.updateType) {
|
|
||||||
case "securityInfo":
|
|
||||||
this.pushRequestToQueue(resource.actor, {
|
|
||||||
securityState: resource.securityState,
|
|
||||||
isRacing: resource.isRacing,
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case "responseStart":
|
|
||||||
this.pushRequestToQueue(resource.actor, {
|
|
||||||
httpVersion: resource.response.httpVersion,
|
|
||||||
remoteAddress: resource.response.remoteAddress,
|
|
||||||
remotePort: resource.response.remotePort,
|
|
||||||
status: resource.response.status,
|
|
||||||
statusText: resource.response.statusText,
|
|
||||||
headersSize: resource.response.headersSize,
|
|
||||||
waitingTime: resource.response.waitingTime,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Identify the channel as SSE if mimeType is event-stream.
|
// Identify the channel as SSE if mimeType is event-stream.
|
||||||
if (resource.response.content.mimeType?.includes("text/event-stream")) {
|
if (resource?.mimeType?.includes("text/event-stream")) {
|
||||||
await this.setEventStreamFlag(resource.actor);
|
await this.setEventStreamFlag(resource.actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.emitForTests(
|
this.pendingRequests.delete(resource.actor);
|
||||||
TEST_EVENTS.STARTED_RECEIVING_RESPONSE,
|
if (this.actionsEnabled && this.actions.updateRequest) {
|
||||||
resource.actor
|
await this.actions.updateRequest(resource.actor, resource, true);
|
||||||
);
|
|
||||||
break;
|
|
||||||
case "responseContent":
|
|
||||||
this.pushRequestToQueue(resource.actor, {
|
|
||||||
contentSize: resource.response.bodySize,
|
|
||||||
transferredSize: resource.response.transferredSize,
|
|
||||||
mimeType: resource.response.content.mimeType,
|
|
||||||
blockingExtension: resource.blockingExtension,
|
|
||||||
blockedReason: resource.blockedReason,
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case "eventTimings":
|
|
||||||
// Total time doesn't have to be always set e.g. net provider enhancer
|
|
||||||
// in Console panel is using this method to fetch data when network log
|
|
||||||
// is expanded. So, make sure to not push undefined into the payload queue
|
|
||||||
// (it could overwrite an existing value).
|
|
||||||
if (typeof resource.totalTime !== "undefined") {
|
|
||||||
this.pushRequestToQueue(resource.actor, {
|
|
||||||
totalTime: resource.totalTime,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This available field helps knowing when/if updateType property is arrived
|
// This event is fired only once per request, once all the properties are fetched
|
||||||
// and can be requested via `requestData`
|
// from `onNetworkResourceUpdated`. There should be no more RDP requests after this.
|
||||||
this.pushRequestToQueue(resource.actor, {
|
// Note that this event might be consumed by extension so, emit it in production
|
||||||
[`${update.updateType}Available`]: true,
|
// release as well.
|
||||||
});
|
|
||||||
|
|
||||||
await this.onPayloadDataReceived(resource);
|
|
||||||
|
|
||||||
this.emitForTests(TEST_EVENTS.NETWORK_EVENT_UPDATED, resource.actor);
|
this.emitForTests(TEST_EVENTS.NETWORK_EVENT_UPDATED, resource.actor);
|
||||||
|
this.emit(EVENTS.PAYLOAD_READY, resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -564,42 +437,6 @@ class FirefoxDataProvider {
|
||||||
// TODO: Emit an event for test here
|
// TODO: Emit an event for test here
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify actions when events from onNetworkResourceUpdated are done, updated network event
|
|
||||||
* resources contain initial network info for each updateType and then we can invoke
|
|
||||||
* requestData to fetch its corresponded data lazily.
|
|
||||||
* Once all updateTypes of updated network event resource are available, we flush the merged
|
|
||||||
* request payload from pending queue and then update the component.
|
|
||||||
*/
|
|
||||||
async onPayloadDataReceived(resource) {
|
|
||||||
const payload = this.payloadQueue.get(resource.actor) || {};
|
|
||||||
|
|
||||||
// For blocked requests, we should only expect the request portions and not
|
|
||||||
// the response portions to be available.
|
|
||||||
if (!payload.requestHeadersAvailable || !payload.requestCookiesAvailable) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// For unblocked requests, we should wait for all major portions to be available.
|
|
||||||
if (
|
|
||||||
!payload.blockedReason &&
|
|
||||||
(!payload.eventTimingsAvailable || !payload.responseContentAvailable)
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.payloadQueue.delete(resource.actor);
|
|
||||||
|
|
||||||
if (this.actionsEnabled && this.actions.updateRequest) {
|
|
||||||
await this.actions.updateRequest(resource.actor, payload, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This event is fired only once per request, once all the properties are fetched
|
|
||||||
// from `onNetworkResourceUpdated`. There should be no more RDP requests after this.
|
|
||||||
// Note that this event might be consumed by extension so, emit it in production
|
|
||||||
// release as well.
|
|
||||||
this.emit(EVENTS.PAYLOAD_READY, resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Public connector API to lazily request HTTP details from the backend.
|
* Public connector API to lazily request HTTP details from the backend.
|
||||||
*
|
*
|
||||||
|
|
|
@ -170,12 +170,7 @@ HarCollector.prototype = {
|
||||||
for (const resource of resources) {
|
for (const resource of resources) {
|
||||||
trace.log("HarCollector.onNetworkEvent; ", resource);
|
trace.log("HarCollector.onNetworkEvent; ", resource);
|
||||||
|
|
||||||
const {
|
const { actor, startedDateTime, method, url, isXHR } = resource;
|
||||||
actor,
|
|
||||||
startedDateTime,
|
|
||||||
request: { method, url },
|
|
||||||
isXHR,
|
|
||||||
} = resource;
|
|
||||||
const startTime = Date.parse(startedDateTime);
|
const startTime = Date.parse(startedDateTime);
|
||||||
|
|
||||||
if (this.firstRequestStart == -1) {
|
if (this.firstRequestStart == -1) {
|
||||||
|
@ -211,7 +206,7 @@ HarCollector.prototype = {
|
||||||
},
|
},
|
||||||
|
|
||||||
onResourceUpdated: function(updates) {
|
onResourceUpdated: function(updates) {
|
||||||
for (const { resource, update } of updates) {
|
for (const { resource } of updates) {
|
||||||
// Skip events from unknown actors (not in the list).
|
// Skip events from unknown actors (not in the list).
|
||||||
// It can happen when there are zombie requests received after
|
// It can happen when there are zombie requests received after
|
||||||
// the target is closed or multiple tabs are attached through
|
// the target is closed or multiple tabs are attached through
|
||||||
|
@ -221,84 +216,84 @@ HarCollector.prototype = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
trace.log(
|
|
||||||
"HarCollector.onNetworkEventUpdate; " + update.updateType,
|
|
||||||
resource
|
|
||||||
);
|
|
||||||
|
|
||||||
const includeResponseBodies = Services.prefs.getBoolPref(
|
const includeResponseBodies = Services.prefs.getBoolPref(
|
||||||
"devtools.netmonitor.har.includeResponseBodies"
|
"devtools.netmonitor.har.includeResponseBodies"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
type: "eventTimings",
|
||||||
|
method: "getEventTimings",
|
||||||
|
callbackName: "onEventTimings",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "requestHeaders",
|
||||||
|
method: "getRequestHeaders",
|
||||||
|
callbackName: "onRequestHeaders",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "requestPostData",
|
||||||
|
method: "getRequestPostData",
|
||||||
|
callbackName: "onRequestPostData",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "responseHeaders",
|
||||||
|
method: "getResponseHeaders",
|
||||||
|
callbackName: "onResponseHeaders",
|
||||||
|
},
|
||||||
|
{ type: "responseStart" },
|
||||||
|
{
|
||||||
|
type: "responseContent",
|
||||||
|
method: "getResponseContent",
|
||||||
|
callbackName: "onResponseContent",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "requestCookies",
|
||||||
|
method: "getRequestCookies",
|
||||||
|
callbackName: "onRequestCookies",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "responseCookies",
|
||||||
|
method: "getResponseCookies",
|
||||||
|
callbackName: "onResponseCookies",
|
||||||
|
},
|
||||||
|
].forEach(updateType => {
|
||||||
|
trace.log(
|
||||||
|
"HarCollector.onNetworkEventUpdate; " + updateType.type,
|
||||||
|
resource
|
||||||
|
);
|
||||||
|
|
||||||
let request;
|
let request;
|
||||||
switch (update.updateType) {
|
if (resource[`${updateType.type}Available`]) {
|
||||||
case "requestHeaders":
|
if (updateType.type == "responseStart") {
|
||||||
request = this.getData(
|
file.httpVersion = resource.httpVersion;
|
||||||
resource.actor,
|
file.status = resource.status;
|
||||||
"getRequestHeaders",
|
file.statusText = resource.statusText;
|
||||||
this.onRequestHeaders
|
} else if (updateType.type == "responseContent") {
|
||||||
);
|
|
||||||
break;
|
|
||||||
case "requestCookies":
|
|
||||||
request = this.getData(
|
|
||||||
resource.actor,
|
|
||||||
"getRequestCookies",
|
|
||||||
this.onRequestCookies
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case "requestPostData":
|
|
||||||
request = this.getData(
|
|
||||||
resource.actor,
|
|
||||||
"getRequestPostData",
|
|
||||||
this.onRequestPostData
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case "responseHeaders":
|
|
||||||
request = this.getData(
|
|
||||||
resource.actor,
|
|
||||||
"getResponseHeaders",
|
|
||||||
this.onResponseHeaders
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case "responseCookies":
|
|
||||||
request = this.getData(
|
|
||||||
resource.actor,
|
|
||||||
"getResponseCookies",
|
|
||||||
this.onResponseCookies
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case "responseStart":
|
|
||||||
file.httpVersion = resource.response.httpVersion;
|
|
||||||
file.status = resource.response.status;
|
|
||||||
file.statusText = resource.response.statusText;
|
|
||||||
break;
|
|
||||||
case "responseContent":
|
|
||||||
file.contentSize = resource.contentSize;
|
file.contentSize = resource.contentSize;
|
||||||
file.mimeType = resource.mimeType;
|
file.mimeType = resource.mimeType;
|
||||||
file.transferredSize = resource.transferredSize;
|
file.transferredSize = resource.transferredSize;
|
||||||
|
|
||||||
if (includeResponseBodies) {
|
if (includeResponseBodies) {
|
||||||
request = this.getData(
|
request = this.getData(
|
||||||
resource.actor,
|
resource.actor,
|
||||||
"getResponseContent",
|
updateType.method,
|
||||||
this.onResponseContent
|
this[updateType.callbackName]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
} else {
|
||||||
case "eventTimings":
|
|
||||||
request = this.getData(
|
request = this.getData(
|
||||||
resource.actor,
|
resource.actor,
|
||||||
"getEventTimings",
|
updateType.method,
|
||||||
this.onEventTimings
|
this[updateType.callbackName]
|
||||||
);
|
);
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request) {
|
if (request) {
|
||||||
this.requests.push(request);
|
this.requests.push(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.resetPageLoadTimeout();
|
this.resetPageLoadTimeout();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { TIMING_KEYS } = require("devtools/client/netmonitor/src/constants");
|
const { TIMING_KEYS } = require("devtools/client/netmonitor/src/constants");
|
||||||
|
const {
|
||||||
|
getUrlDetails,
|
||||||
|
} = require("devtools/client/netmonitor/src/utils/request-utils");
|
||||||
|
|
||||||
var guid = 0;
|
var guid = 0;
|
||||||
|
|
||||||
|
@ -47,6 +50,7 @@ HarImporter.prototype = {
|
||||||
startedMs: startedMs,
|
startedMs: startedMs,
|
||||||
method: entry.request.method,
|
method: entry.request.method,
|
||||||
url: entry.request.url,
|
url: entry.request.url,
|
||||||
|
urlDetails: getUrlDetails(entry.request.url),
|
||||||
isXHR: false,
|
isXHR: false,
|
||||||
cause: {
|
cause: {
|
||||||
loadingDocumentUri: "",
|
loadingDocumentUri: "",
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const {
|
const {
|
||||||
getUrlDetails,
|
|
||||||
processNetworkUpdates,
|
processNetworkUpdates,
|
||||||
} = require("devtools/client/netmonitor/src/utils/request-utils");
|
} = require("devtools/client/netmonitor/src/utils/request-utils");
|
||||||
const {
|
const {
|
||||||
|
@ -152,11 +151,12 @@ function requestsReducer(state = Requests(), action) {
|
||||||
|
|
||||||
function addRequest(state, action) {
|
function addRequest(state, action) {
|
||||||
const nextState = { ...state };
|
const nextState = { ...state };
|
||||||
|
// The target front is not used and cannot be serialized by redux
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
const { targetFront, ...requestData } = action.data;
|
||||||
const newRequest = {
|
const newRequest = {
|
||||||
id: action.id,
|
id: action.id,
|
||||||
...action.data,
|
...requestData,
|
||||||
urlDetails: getUrlDetails(action.data.url),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
nextState.requests = [...state.requests, newRequest];
|
nextState.requests = [...state.requests, newRequest];
|
||||||
|
|
|
@ -585,26 +585,25 @@ async function getMessagePayload(payload, getLongString) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This helper function is used for additional processing of
|
* This helper function is used for additional processing of
|
||||||
* incoming network update packets. It's used by Network and
|
* incoming network update packets. It makes sure the only valid
|
||||||
* Console panel reducers.
|
* update properties and the values are correct.
|
||||||
|
* It's used by Network and Console panel reducers.
|
||||||
|
* @param {object} update
|
||||||
|
* The new update payload
|
||||||
|
* @param {object} request
|
||||||
|
* The current request in the state
|
||||||
*/
|
*/
|
||||||
function processNetworkUpdates(update) {
|
function processNetworkUpdates(update) {
|
||||||
const result = {};
|
const newRequest = {};
|
||||||
for (const [key, value] of Object.entries(update)) {
|
for (const [key, value] of Object.entries(update)) {
|
||||||
if (UPDATE_PROPS.includes(key)) {
|
if (UPDATE_PROPS.includes(key)) {
|
||||||
result[key] = value;
|
newRequest[key] = value;
|
||||||
|
if (key == "requestPostData") {
|
||||||
switch (key) {
|
newRequest.requestHeadersFromUploadStream = value.uploadHeaders;
|
||||||
case "totalTime":
|
|
||||||
result.totalTime = update.totalTime;
|
|
||||||
break;
|
|
||||||
case "requestPostData":
|
|
||||||
result.requestHeadersFromUploadStream = value.uploadHeaders;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return newRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -80,16 +80,17 @@ function NetworkEventMessage({
|
||||||
source,
|
source,
|
||||||
type,
|
type,
|
||||||
level,
|
level,
|
||||||
request,
|
url,
|
||||||
|
method,
|
||||||
isXHR,
|
isXHR,
|
||||||
timeStamp,
|
timeStamp,
|
||||||
blockedReason,
|
blockedReason,
|
||||||
|
httpVersion,
|
||||||
|
status,
|
||||||
|
statusText,
|
||||||
|
totalTime,
|
||||||
} = message;
|
} = message;
|
||||||
|
|
||||||
const { response = {}, totalTime } = networkMessageUpdate;
|
|
||||||
|
|
||||||
const { httpVersion, status, statusText } = response;
|
|
||||||
|
|
||||||
const topLevelClasses = ["cm-s-mozilla"];
|
const topLevelClasses = ["cm-s-mozilla"];
|
||||||
if (isMessageNetworkError(message)) {
|
if (isMessageNetworkError(message)) {
|
||||||
topLevelClasses.push("error");
|
topLevelClasses.push("error");
|
||||||
|
@ -139,7 +140,7 @@ function NetworkEventMessage({
|
||||||
const onToggle = (messageId, e) => {
|
const onToggle = (messageId, e) => {
|
||||||
const shouldOpenLink = (isMacOS && e.metaKey) || (!isMacOS && e.ctrlKey);
|
const shouldOpenLink = (isMacOS && e.metaKey) || (!isMacOS && e.ctrlKey);
|
||||||
if (shouldOpenLink) {
|
if (shouldOpenLink) {
|
||||||
serviceContainer.openLink(request.url, e);
|
serviceContainer.openLink(url, e);
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
} else if (open) {
|
} else if (open) {
|
||||||
dispatch(actions.messageClose(messageId));
|
dispatch(actions.messageClose(messageId));
|
||||||
|
@ -149,27 +150,24 @@ function NetworkEventMessage({
|
||||||
};
|
};
|
||||||
|
|
||||||
// Message body components.
|
// Message body components.
|
||||||
const method = dom.span({ className: "method" }, request.method);
|
const requestMethod = dom.span({ className: "method" }, method);
|
||||||
const xhr = isXHR
|
const xhr = isXHR
|
||||||
? dom.span({ className: "xhr" }, l10n.getStr("webConsoleXhrIndicator"))
|
? dom.span({ className: "xhr" }, l10n.getStr("webConsoleXhrIndicator"))
|
||||||
: null;
|
: null;
|
||||||
const requestUrl = dom.span(
|
const requestUrl = dom.span({ className: "url", title: url }, url);
|
||||||
{ className: "url", title: request.url },
|
|
||||||
request.url
|
|
||||||
);
|
|
||||||
const statusBody = statusInfo
|
const statusBody = statusInfo
|
||||||
? dom.a({ className: "status" }, statusInfo)
|
? dom.a({ className: "status" }, statusInfo)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
const messageBody = [xhr, method, requestUrl, statusBody];
|
const messageBody = [xhr, requestMethod, requestUrl, statusBody];
|
||||||
|
|
||||||
// API consumed by Net monitor UI components. Most of the method
|
// API consumed by Net monitor UI components. Most of the method
|
||||||
// are not needed in context of the Console panel (atm) and thus
|
// are not needed in context of the Console panel (atm) and thus
|
||||||
// let's just provide empty implementation.
|
// let's just provide empty implementation.
|
||||||
// Individual methods might be implemented step by step as needed.
|
// Individual methods might be implemented step by step as needed.
|
||||||
const connector = {
|
const connector = {
|
||||||
viewSourceInDebugger: (url, line, column) => {
|
viewSourceInDebugger: (srcUrl, line, column) => {
|
||||||
serviceContainer.onViewSourceInDebugger({ url, line, column });
|
serviceContainer.onViewSourceInDebugger({ url: srcUrl, line, column });
|
||||||
},
|
},
|
||||||
getLongString: grip => {
|
getLongString: grip => {
|
||||||
return serviceContainer.getLongString(grip);
|
return serviceContainer.getLongString(grip);
|
||||||
|
@ -210,6 +208,7 @@ function NetworkEventMessage({
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const request = { url, method };
|
||||||
return Message({
|
return Message({
|
||||||
dispatch,
|
dispatch,
|
||||||
messageId: id,
|
messageId: id,
|
||||||
|
|
|
@ -51,9 +51,7 @@ function enableNetProvider(webConsoleUI) {
|
||||||
const message = updates[action.id];
|
const message = updates[action.id];
|
||||||
if (message && !message.openedOnce && message.source == "network") {
|
if (message && !message.openedOnce && message.source == "network") {
|
||||||
dataProvider.onNetworkResourceAvailable(message);
|
dataProvider.onNetworkResourceAvailable(message);
|
||||||
message.updates.forEach(updateType => {
|
dataProvider.onNetworkResourceUpdated(message);
|
||||||
dataProvider.onNetworkResourceUpdated(message, { updateType });
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,9 +67,7 @@ function enableNetProvider(webConsoleUI) {
|
||||||
const open = allMessages.includes(actor);
|
const open = allMessages.includes(actor);
|
||||||
if (open) {
|
if (open) {
|
||||||
const message = getMessage(newState, actor);
|
const message = getMessage(newState, actor);
|
||||||
message.updates.forEach(updateType => {
|
dataProvider.onNetworkResourceUpdated(message);
|
||||||
dataProvider.onNetworkResourceUpdated(message, { updateType });
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1359,7 +1359,7 @@ function passSearchFilters(message, filters) {
|
||||||
// Look for a match in location.
|
// Look for a match in location.
|
||||||
isTextInFrame(matchStr, message.frame) ||
|
isTextInFrame(matchStr, message.frame) ||
|
||||||
// Look for a match in net events.
|
// Look for a match in net events.
|
||||||
isTextInNetEvent(matchStr, message.request) ||
|
isTextInNetEvent(matchStr, message) ||
|
||||||
// Look for a match in stack-trace.
|
// Look for a match in stack-trace.
|
||||||
isTextInStackTrace(matchStr, message.stacktrace) ||
|
isTextInStackTrace(matchStr, message.stacktrace) ||
|
||||||
// Look for a match in messageText.
|
// Look for a match in messageText.
|
||||||
|
@ -1445,12 +1445,10 @@ function isTextInParameter(matchStr, parameter) {
|
||||||
/**
|
/**
|
||||||
* Returns true if given text is included in provided net event grip.
|
* Returns true if given text is included in provided net event grip.
|
||||||
*/
|
*/
|
||||||
function isTextInNetEvent(matchStr, request) {
|
function isTextInNetEvent(matchStr, { method, url } = {}) {
|
||||||
if (!request) {
|
if (!method && !url) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { method, url } = request;
|
|
||||||
return matchStr(method) || matchStr(url);
|
return matchStr(method) || matchStr(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,8 @@ add_task(async function() {
|
||||||
|
|
||||||
// clear the browser console.
|
// clear the browser console.
|
||||||
await clearOutput(hud);
|
await clearOutput(hud);
|
||||||
|
await waitForTick();
|
||||||
|
await safeCloseBrowserConsole();
|
||||||
});
|
});
|
||||||
|
|
||||||
async function testMessages(hud) {
|
async function testMessages(hud) {
|
||||||
|
|
|
@ -24,9 +24,9 @@ add_task(async function task() {
|
||||||
const currentTab = gBrowser.selectedTab;
|
const currentTab = gBrowser.selectedTab;
|
||||||
const target = await TargetFactory.forTab(currentTab);
|
const target = await TargetFactory.forTab(currentTab);
|
||||||
const toolbox = gDevTools.getToolbox(target);
|
const toolbox = gDevTools.getToolbox(target);
|
||||||
|
const panel = toolbox.getCurrentPanel().panelWin;
|
||||||
|
|
||||||
const monitor = toolbox.getCurrentPanel();
|
const netReady = panel.api.once("NetMonitor:PayloadReady");
|
||||||
const netReady = monitor.panelWin.api.once("NetMonitor:PayloadReady");
|
|
||||||
|
|
||||||
// Fire an XHR POST request.
|
// Fire an XHR POST request.
|
||||||
await SpecialPowers.spawn(gBrowser.selectedBrowser, [], function() {
|
await SpecialPowers.spawn(gBrowser.selectedBrowser, [], function() {
|
||||||
|
@ -46,19 +46,7 @@ add_task(async function task() {
|
||||||
const urlNode = messageNode.querySelector(".url");
|
const urlNode = messageNode.querySelector(".url");
|
||||||
info("Network message found.");
|
info("Network message found.");
|
||||||
|
|
||||||
const onReady = new Promise(resolve => {
|
const onReady = hud.ui.once("network-request-payload-ready");
|
||||||
let count = 0;
|
|
||||||
function onPayloadReady(updateCount) {
|
|
||||||
count += updateCount;
|
|
||||||
// Wait for all NETWORK_REQUEST updated events
|
|
||||||
// Otherwise we may still be having pending request
|
|
||||||
if (count == 7) {
|
|
||||||
hud.ui.off("network-request-payload-ready", onPayloadReady);
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hud.ui.on("network-request-payload-ready", onPayloadReady);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Expand network log
|
// Expand network log
|
||||||
urlNode.click();
|
urlNode.click();
|
||||||
|
@ -66,6 +54,7 @@ add_task(async function task() {
|
||||||
await onReady;
|
await onReady;
|
||||||
|
|
||||||
info("network-request-payload-ready received");
|
info("network-request-payload-ready received");
|
||||||
|
|
||||||
await testNetworkMessage(messageNode);
|
await testNetworkMessage(messageNode);
|
||||||
await waitForLazyRequests(toolbox);
|
await waitForLazyRequests(toolbox);
|
||||||
});
|
});
|
||||||
|
|
|
@ -27,6 +27,9 @@ registerCleanupFunction(async () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
add_task(async function task() {
|
add_task(async function task() {
|
||||||
|
// Make sure the filter to show all the requests is set
|
||||||
|
await pushPref("devtools.netmonitor.filters", '["all"]');
|
||||||
|
|
||||||
// Test that the request appears in the console.
|
// Test that the request appears in the console.
|
||||||
const hud = await openNewTabAndConsole(TEST_URI);
|
const hud = await openNewTabAndConsole(TEST_URI);
|
||||||
const currentTab = gBrowser.selectedTab;
|
const currentTab = gBrowser.selectedTab;
|
||||||
|
@ -65,11 +68,14 @@ async function testNetmonitor(toolbox) {
|
||||||
);
|
);
|
||||||
|
|
||||||
store.dispatch(Actions.batchEnable(false));
|
store.dispatch(Actions.batchEnable(false));
|
||||||
const requestItem = document.querySelector(".request-list-item");
|
|
||||||
await waitUntil(() => store.getState().requests.requests.length > 0);
|
await waitUntil(() => store.getState().requests.requests.length > 0);
|
||||||
// Lets also wait until all the event timings data requested
|
// Lets also wait until all the event timings data requested
|
||||||
// has completed and the column is rendered.
|
// has completed and the column is rendered.
|
||||||
await waitForDOM(requestItem, ".requests-list-timings-total");
|
await waitForDOM(
|
||||||
|
document,
|
||||||
|
".request-list-item:first-child .requests-list-timings-total"
|
||||||
|
);
|
||||||
|
|
||||||
is(
|
is(
|
||||||
store.getState().requests.requests.length,
|
store.getState().requests.requests.length,
|
||||||
|
|
|
@ -40,15 +40,7 @@ add_task(async function() {
|
||||||
|
|
||||||
let failed = false;
|
let failed = false;
|
||||||
for (const [key, packet] of generatedStubs) {
|
for (const [key, packet] of generatedStubs) {
|
||||||
// packet.updates are handle by the webconsole front, and can be updated after
|
|
||||||
// we cleaned the packet, so the order isn't guaranteed. Let's sort the array
|
|
||||||
// here so the test doesn't fail.
|
|
||||||
const existingPacket = existingStubs.stubPackets.get(key);
|
const existingPacket = existingStubs.stubPackets.get(key);
|
||||||
if (packet.updates && existingPacket.updates) {
|
|
||||||
packet.updates.sort();
|
|
||||||
existingPacket.updates.sort();
|
|
||||||
}
|
|
||||||
|
|
||||||
const packetStr = JSON.stringify(packet, null, 2);
|
const packetStr = JSON.stringify(packet, null, 2);
|
||||||
const existingPacketStr = JSON.stringify(existingPacket, null, 2);
|
const existingPacketStr = JSON.stringify(existingPacket, null, 2);
|
||||||
is(packetStr, existingPacketStr, `"${key}" packet has expected value`);
|
is(packetStr, existingPacketStr, `"${key}" packet has expected value`);
|
||||||
|
@ -67,7 +59,6 @@ async function generateNetworkEventStubs() {
|
||||||
const tab = await addTab(TEST_URI);
|
const tab = await addTab(TEST_URI);
|
||||||
const resourceWatcher = await createResourceWatcherForTab(tab);
|
const resourceWatcher = await createResourceWatcherForTab(tab);
|
||||||
const stacktraces = new Map();
|
const stacktraces = new Map();
|
||||||
|
|
||||||
let addNetworkStub = function() {};
|
let addNetworkStub = function() {};
|
||||||
let addNetworkUpdateStub = function() {};
|
let addNetworkUpdateStub = function() {};
|
||||||
|
|
||||||
|
@ -110,7 +101,6 @@ async function generateNetworkEventStubs() {
|
||||||
);
|
);
|
||||||
|
|
||||||
for (const [key, code] of getCommands()) {
|
for (const [key, code] of getCommands()) {
|
||||||
const noExpectedUpdates = 7;
|
|
||||||
const networkEventDone = new Promise(resolve => {
|
const networkEventDone = new Promise(resolve => {
|
||||||
addNetworkStub = resource => {
|
addNetworkStub = resource => {
|
||||||
stubs.set(key, getCleanedPacket(key, getOrderedResource(resource)));
|
stubs.set(key, getCleanedPacket(key, getOrderedResource(resource)));
|
||||||
|
@ -118,12 +108,8 @@ async function generateNetworkEventStubs() {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
const networkEventUpdateDone = new Promise(resolve => {
|
const networkEventUpdateDone = new Promise(resolve => {
|
||||||
let updateCount = 0;
|
|
||||||
addNetworkUpdateStub = resource => {
|
addNetworkUpdateStub = resource => {
|
||||||
const updateKey = `${key} update`;
|
const updateKey = `${key} update`;
|
||||||
// make sure all the updates have been happened
|
|
||||||
if (updateCount >= noExpectedUpdates) {
|
|
||||||
// make sure the network event stub contains all the updates
|
|
||||||
stubs.set(key, getCleanedPacket(key, getOrderedResource(resource)));
|
stubs.set(key, getCleanedPacket(key, getOrderedResource(resource)));
|
||||||
stubs.set(
|
stubs.set(
|
||||||
updateKey,
|
updateKey,
|
||||||
|
@ -132,11 +118,7 @@ async function generateNetworkEventStubs() {
|
||||||
// Hand-picking only what we need should prevent this.
|
// Hand-picking only what we need should prevent this.
|
||||||
getCleanedPacket(updateKey, getOrderedResource(resource))
|
getCleanedPacket(updateKey, getOrderedResource(resource))
|
||||||
);
|
);
|
||||||
|
|
||||||
resolve();
|
resolve();
|
||||||
} else {
|
|
||||||
updateCount++;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -169,15 +151,23 @@ async function generateNetworkEventStubs() {
|
||||||
function getOrderedResource(resource) {
|
function getOrderedResource(resource) {
|
||||||
return {
|
return {
|
||||||
resourceType: resource.resourceType,
|
resourceType: resource.resourceType,
|
||||||
_type: resource._type,
|
|
||||||
timeStamp: resource.timeStamp,
|
timeStamp: resource.timeStamp,
|
||||||
node: resource.node,
|
|
||||||
actor: resource.actor,
|
actor: resource.actor,
|
||||||
startedDateTime: resource.startedDateTime,
|
startedDateTime: resource.startedDateTime,
|
||||||
request: resource.request,
|
method: resource.method,
|
||||||
|
url: resource.url,
|
||||||
isXHR: resource.isXHR,
|
isXHR: resource.isXHR,
|
||||||
cause: resource.cause,
|
cause: resource.cause,
|
||||||
response: resource.response,
|
httpVersion: resource.httpVersion,
|
||||||
|
status: resource.status,
|
||||||
|
statusText: resource.statusText,
|
||||||
|
headersSize: resource.headersSize,
|
||||||
|
remoteAddress: resource.remoteAddress,
|
||||||
|
remotePort: resource.remotePort,
|
||||||
|
mimeType: resource.mimeType,
|
||||||
|
waitingTime: resource.waitingTime,
|
||||||
|
contentSize: resource.contentSize,
|
||||||
|
transferredSize: resource.transferredSize,
|
||||||
timings: resource.timings,
|
timings: resource.timings,
|
||||||
private: resource.private,
|
private: resource.private,
|
||||||
fromCache: resource.fromCache,
|
fromCache: resource.fromCache,
|
||||||
|
@ -185,10 +175,11 @@ function getOrderedResource(resource) {
|
||||||
isThirdPartyTrackingResource: resource.isThirdPartyTrackingResource,
|
isThirdPartyTrackingResource: resource.isThirdPartyTrackingResource,
|
||||||
referrerPolicy: resource.referrerPolicy,
|
referrerPolicy: resource.referrerPolicy,
|
||||||
blockedReason: resource.blockedReason,
|
blockedReason: resource.blockedReason,
|
||||||
|
blockingExtension: resource.blockingExtension,
|
||||||
channelId: resource.channelId,
|
channelId: resource.channelId,
|
||||||
updates: resource.updates,
|
|
||||||
totalTime: resource.totalTime,
|
totalTime: resource.totalTime,
|
||||||
securityState: resource.securityState,
|
securityState: resource.securityState,
|
||||||
|
responseCache: resource.responseCache,
|
||||||
isRacing: resource.isRacing,
|
isRacing: resource.isRacing,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1704,7 +1704,12 @@ function toggleLayout(hud) {
|
||||||
async function waitForLazyRequests(toolbox) {
|
async function waitForLazyRequests(toolbox) {
|
||||||
const { wrapper } = toolbox.getCurrentPanel().hud.ui;
|
const { wrapper } = toolbox.getCurrentPanel().hud.ui;
|
||||||
return waitUntil(() => {
|
return waitUntil(() => {
|
||||||
return !wrapper.networkDataProvider.lazyRequestData.size;
|
return (
|
||||||
|
!wrapper.networkDataProvider.lazyRequestData.size &&
|
||||||
|
// Make sure that batched request updates are all complete
|
||||||
|
// as they trigger late lazy data requests.
|
||||||
|
!wrapper.queuedRequestUpdates.length
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -296,29 +296,8 @@ function getCleanedPacket(key, packet) {
|
||||||
res.actor = existingPacket.actor;
|
res.actor = existingPacket.actor;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res?.request?.headersSize && existingPacket?.request?.headersSize) {
|
if (res.waitingTime && existingPacket.waitingTime) {
|
||||||
res.request.headersSize = existingPacket.request.headersSize;
|
res.waitingTime = existingPacket.waitingTime;
|
||||||
}
|
|
||||||
|
|
||||||
if (res?.response?.headersSize && existingPacket?.response?.headersSize) {
|
|
||||||
res.response.headersSize = existingPacket.response.headersSize;
|
|
||||||
}
|
|
||||||
if (res?.response?.bodySize && existingPacket?.response?.bodySize) {
|
|
||||||
res.response.bodySize = existingPacket.response.bodySize;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
res?.response?.transferredSize &&
|
|
||||||
existingPacket?.response?.transferredSize
|
|
||||||
) {
|
|
||||||
res.response.transferredSize = existingPacket.response.transferredSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res?.response?.waitingTime && existingPacket?.response?.waitingTime) {
|
|
||||||
res.response.waitingTime = existingPacket.response.waitingTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res.updates && Array.isArray(res.updates)) {
|
|
||||||
res.updates.sort();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res.helperResult) {
|
if (res.helperResult) {
|
||||||
|
|
|
@ -23,15 +23,11 @@ rawPackets.set(`GET request`, {
|
||||||
"timeStamp": 1572867483805,
|
"timeStamp": 1572867483805,
|
||||||
"actor": "server0.conn0.netEvent4",
|
"actor": "server0.conn0.netEvent4",
|
||||||
"startedDateTime": "2019-11-04T11:06:34.542Z",
|
"startedDateTime": "2019-11-04T11:06:34.542Z",
|
||||||
"request": {
|
|
||||||
"url": "http://example.com/inexistent.html",
|
|
||||||
"method": "GET",
|
"method": "GET",
|
||||||
"headersSize": 385
|
"url": "http://example.com/inexistent.html",
|
||||||
},
|
|
||||||
"isXHR": false,
|
"isXHR": false,
|
||||||
"cause": {
|
"cause": {
|
||||||
"type": "img",
|
"type": "img",
|
||||||
"loadingDocumentUri": "http://example.com/browser/devtools/client/webconsole/test/browser/stub-generators/test-network-event.html",
|
|
||||||
"stacktraceAvailable": true,
|
"stacktraceAvailable": true,
|
||||||
"lastFrame": {
|
"lastFrame": {
|
||||||
"filename": "http://example.com/browser/devtools/client/webconsole/test/browser/stub-generators/test-network-event.html",
|
"filename": "http://example.com/browser/devtools/client/webconsole/test/browser/stub-generators/test-network-event.html",
|
||||||
|
@ -41,34 +37,20 @@ rawPackets.set(`GET request`, {
|
||||||
"asyncCause": null
|
"asyncCause": null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"response": {
|
|
||||||
"httpVersion": "HTTP/1.1",
|
"httpVersion": "HTTP/1.1",
|
||||||
"status": "404",
|
"status": "404",
|
||||||
"statusText": "Not Found",
|
"statusText": "Not Found",
|
||||||
"headersSize": 160,
|
|
||||||
"remoteAddress": "127.0.0.1",
|
"remoteAddress": "127.0.0.1",
|
||||||
"remotePort": 8888,
|
"remotePort": 8888,
|
||||||
"content": {
|
"mimeType": "text/html; charset=utf-8",
|
||||||
"mimeType": "text/html; charset=utf-8"
|
|
||||||
},
|
|
||||||
"waitingTime": 1,
|
"waitingTime": 1,
|
||||||
"bodySize": 418,
|
"contentSize": 418,
|
||||||
"transferredSize": 578
|
"transferredSize": 578,
|
||||||
},
|
|
||||||
"timings": {},
|
"timings": {},
|
||||||
"private": false,
|
"private": false,
|
||||||
"isThirdPartyTrackingResource": false,
|
"isThirdPartyTrackingResource": false,
|
||||||
"referrerPolicy": "no-referrer-when-downgrade",
|
"referrerPolicy": "no-referrer-when-downgrade",
|
||||||
"updates": [
|
"blockedReason": 0,
|
||||||
"eventTimings",
|
|
||||||
"requestCookies",
|
|
||||||
"requestHeaders",
|
|
||||||
"responseContent",
|
|
||||||
"responseCookies",
|
|
||||||
"responseHeaders",
|
|
||||||
"responseStart",
|
|
||||||
"securityInfo"
|
|
||||||
],
|
|
||||||
"totalTime": 2,
|
"totalTime": 2,
|
||||||
"securityState": "insecure",
|
"securityState": "insecure",
|
||||||
"isRacing": false
|
"isRacing": false
|
||||||
|
@ -79,15 +61,11 @@ rawPackets.set(`GET request update`, {
|
||||||
"timeStamp": 1572867483805,
|
"timeStamp": 1572867483805,
|
||||||
"actor": "server0.conn0.netEvent5",
|
"actor": "server0.conn0.netEvent5",
|
||||||
"startedDateTime": "2020-07-07T14:41:14.572Z",
|
"startedDateTime": "2020-07-07T14:41:14.572Z",
|
||||||
"request": {
|
|
||||||
"url": "http://example.com/inexistent.html",
|
|
||||||
"method": "GET",
|
"method": "GET",
|
||||||
"headersSize": 385
|
"url": "http://example.com/inexistent.html",
|
||||||
},
|
|
||||||
"isXHR": false,
|
"isXHR": false,
|
||||||
"cause": {
|
"cause": {
|
||||||
"type": "img",
|
"type": "img",
|
||||||
"loadingDocumentUri": "http://example.com/browser/devtools/client/webconsole/test/browser/stub-generators/test-network-event.html",
|
|
||||||
"stacktraceAvailable": true,
|
"stacktraceAvailable": true,
|
||||||
"lastFrame": {
|
"lastFrame": {
|
||||||
"filename": "http://example.com/browser/devtools/client/webconsole/test/browser/stub-generators/test-network-event.html",
|
"filename": "http://example.com/browser/devtools/client/webconsole/test/browser/stub-generators/test-network-event.html",
|
||||||
|
@ -97,34 +75,20 @@ rawPackets.set(`GET request update`, {
|
||||||
"asyncCause": null
|
"asyncCause": null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"response": {
|
|
||||||
"httpVersion": "HTTP/1.1",
|
"httpVersion": "HTTP/1.1",
|
||||||
"status": "404",
|
"status": "404",
|
||||||
"statusText": "Not Found",
|
"statusText": "Not Found",
|
||||||
"headersSize": 160,
|
|
||||||
"remoteAddress": "127.0.0.1",
|
"remoteAddress": "127.0.0.1",
|
||||||
"remotePort": 8888,
|
"remotePort": 8888,
|
||||||
"content": {
|
"mimeType": "text/html; charset=utf-8",
|
||||||
"mimeType": "text/html; charset=utf-8"
|
|
||||||
},
|
|
||||||
"waitingTime": 1,
|
"waitingTime": 1,
|
||||||
"bodySize": 418,
|
"contentSize": 418,
|
||||||
"transferredSize": 578
|
"transferredSize": 578,
|
||||||
},
|
|
||||||
"timings": {},
|
"timings": {},
|
||||||
"private": false,
|
"private": false,
|
||||||
"isThirdPartyTrackingResource": false,
|
"isThirdPartyTrackingResource": false,
|
||||||
"referrerPolicy": "no-referrer-when-downgrade",
|
"referrerPolicy": "no-referrer-when-downgrade",
|
||||||
"updates": [
|
"blockedReason": 0,
|
||||||
"eventTimings",
|
|
||||||
"requestCookies",
|
|
||||||
"requestHeaders",
|
|
||||||
"responseContent",
|
|
||||||
"responseCookies",
|
|
||||||
"responseHeaders",
|
|
||||||
"responseStart",
|
|
||||||
"securityInfo"
|
|
||||||
],
|
|
||||||
"totalTime": 3,
|
"totalTime": 3,
|
||||||
"securityState": "insecure",
|
"securityState": "insecure",
|
||||||
"isRacing": false
|
"isRacing": false
|
||||||
|
@ -135,15 +99,11 @@ rawPackets.set(`XHR GET request`, {
|
||||||
"timeStamp": 1572867483805,
|
"timeStamp": 1572867483805,
|
||||||
"actor": "server0.conn0.netEvent21",
|
"actor": "server0.conn0.netEvent21",
|
||||||
"startedDateTime": "2020-07-07T14:41:14.612Z",
|
"startedDateTime": "2020-07-07T14:41:14.612Z",
|
||||||
"request": {
|
|
||||||
"url": "http://example.com/inexistent.html",
|
|
||||||
"method": "GET",
|
"method": "GET",
|
||||||
"headersSize": 385
|
"url": "http://example.com/inexistent.html",
|
||||||
},
|
|
||||||
"isXHR": true,
|
"isXHR": true,
|
||||||
"cause": {
|
"cause": {
|
||||||
"type": "xhr",
|
"type": "xhr",
|
||||||
"loadingDocumentUri": "http://example.com/browser/devtools/client/webconsole/test/browser/stub-generators/test-network-event.html",
|
|
||||||
"stacktraceAvailable": true,
|
"stacktraceAvailable": true,
|
||||||
"lastFrame": {
|
"lastFrame": {
|
||||||
"filename": "http://example.com/browser/devtools/client/webconsole/test/browser/stub-generators/test-network-event.html",
|
"filename": "http://example.com/browser/devtools/client/webconsole/test/browser/stub-generators/test-network-event.html",
|
||||||
|
@ -153,34 +113,20 @@ rawPackets.set(`XHR GET request`, {
|
||||||
"asyncCause": null
|
"asyncCause": null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"response": {
|
|
||||||
"httpVersion": "HTTP/1.1",
|
"httpVersion": "HTTP/1.1",
|
||||||
"status": "404",
|
"status": "404",
|
||||||
"statusText": "Not Found",
|
"statusText": "Not Found",
|
||||||
"headersSize": 160,
|
|
||||||
"remoteAddress": "127.0.0.1",
|
"remoteAddress": "127.0.0.1",
|
||||||
"remotePort": 8888,
|
"remotePort": 8888,
|
||||||
"content": {
|
"mimeType": "text/html; charset=utf-8",
|
||||||
"mimeType": "text/html; charset=utf-8"
|
"waitingTime": 1,
|
||||||
},
|
"contentSize": 418,
|
||||||
"waitingTime": 2,
|
"transferredSize": 578,
|
||||||
"bodySize": 418,
|
|
||||||
"transferredSize": 578
|
|
||||||
},
|
|
||||||
"timings": {},
|
"timings": {},
|
||||||
"private": false,
|
"private": false,
|
||||||
"isThirdPartyTrackingResource": false,
|
"isThirdPartyTrackingResource": false,
|
||||||
"referrerPolicy": "no-referrer-when-downgrade",
|
"referrerPolicy": "no-referrer-when-downgrade",
|
||||||
"updates": [
|
"blockedReason": 0,
|
||||||
"eventTimings",
|
|
||||||
"requestCookies",
|
|
||||||
"requestHeaders",
|
|
||||||
"responseContent",
|
|
||||||
"responseCookies",
|
|
||||||
"responseHeaders",
|
|
||||||
"responseStart",
|
|
||||||
"securityInfo"
|
|
||||||
],
|
|
||||||
"totalTime": 1,
|
"totalTime": 1,
|
||||||
"securityState": "insecure",
|
"securityState": "insecure",
|
||||||
"isRacing": false
|
"isRacing": false
|
||||||
|
@ -190,15 +136,11 @@ rawPackets.set(`XHR GET request update`, {
|
||||||
"resourceType": "network-event",
|
"resourceType": "network-event",
|
||||||
"timeStamp": 1572867483805,
|
"timeStamp": 1572867483805,
|
||||||
"actor": "server0.conn0.netEvent20",
|
"actor": "server0.conn0.netEvent20",
|
||||||
"request": {
|
|
||||||
"url": "http://example.com/inexistent.html",
|
|
||||||
"method": "GET",
|
"method": "GET",
|
||||||
"headersSize": 385
|
"url": "http://example.com/inexistent.html",
|
||||||
},
|
|
||||||
"isXHR": true,
|
"isXHR": true,
|
||||||
"cause": {
|
"cause": {
|
||||||
"type": "xhr",
|
"type": "xhr",
|
||||||
"loadingDocumentUri": "http://example.com/browser/devtools/client/webconsole/test/browser/stub-generators/test-network-event.html",
|
|
||||||
"stacktraceAvailable": true,
|
"stacktraceAvailable": true,
|
||||||
"lastFrame": {
|
"lastFrame": {
|
||||||
"filename": "http://example.com/browser/devtools/client/webconsole/test/browser/stub-generators/test-network-event.html",
|
"filename": "http://example.com/browser/devtools/client/webconsole/test/browser/stub-generators/test-network-event.html",
|
||||||
|
@ -208,34 +150,20 @@ rawPackets.set(`XHR GET request update`, {
|
||||||
"asyncCause": null
|
"asyncCause": null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"response": {
|
|
||||||
"httpVersion": "HTTP/1.1",
|
"httpVersion": "HTTP/1.1",
|
||||||
"status": "404",
|
"status": "404",
|
||||||
"statusText": "Not Found",
|
"statusText": "Not Found",
|
||||||
"headersSize": 160,
|
|
||||||
"remoteAddress": "127.0.0.1",
|
"remoteAddress": "127.0.0.1",
|
||||||
"remotePort": 8888,
|
"remotePort": 8888,
|
||||||
"content": {
|
"mimeType": "text/html; charset=utf-8",
|
||||||
"mimeType": "text/html; charset=utf-8"
|
"waitingTime": 1,
|
||||||
},
|
"contentSize": 418,
|
||||||
"waitingTime": 2,
|
"transferredSize": 578,
|
||||||
"bodySize": 418,
|
|
||||||
"transferredSize": 578
|
|
||||||
},
|
|
||||||
"timings": {},
|
"timings": {},
|
||||||
"private": false,
|
"private": false,
|
||||||
"isThirdPartyTrackingResource": false,
|
"isThirdPartyTrackingResource": false,
|
||||||
"referrerPolicy": "no-referrer-when-downgrade",
|
"referrerPolicy": "no-referrer-when-downgrade",
|
||||||
"updates": [
|
"blockedReason": 0,
|
||||||
"eventTimings",
|
|
||||||
"requestCookies",
|
|
||||||
"requestHeaders",
|
|
||||||
"responseContent",
|
|
||||||
"responseCookies",
|
|
||||||
"responseHeaders",
|
|
||||||
"responseStart",
|
|
||||||
"securityInfo"
|
|
||||||
],
|
|
||||||
"totalTime": 1,
|
"totalTime": 1,
|
||||||
"securityState": "insecure",
|
"securityState": "insecure",
|
||||||
"isRacing": false
|
"isRacing": false
|
||||||
|
@ -246,15 +174,11 @@ rawPackets.set(`XHR POST request`, {
|
||||||
"timeStamp": 1572867483805,
|
"timeStamp": 1572867483805,
|
||||||
"actor": "server0.conn0.netEvent36",
|
"actor": "server0.conn0.netEvent36",
|
||||||
"startedDateTime": "2019-11-04T11:06:35.007Z",
|
"startedDateTime": "2019-11-04T11:06:35.007Z",
|
||||||
"request": {
|
|
||||||
"url": "http://example.com/inexistent.html",
|
|
||||||
"method": "POST",
|
"method": "POST",
|
||||||
"headersSize": 385
|
"url": "http://example.com/inexistent.html",
|
||||||
},
|
|
||||||
"isXHR": true,
|
"isXHR": true,
|
||||||
"cause": {
|
"cause": {
|
||||||
"type": "xhr",
|
"type": "xhr",
|
||||||
"loadingDocumentUri": "http://example.com/browser/devtools/client/webconsole/test/browser/stub-generators/test-network-event.html",
|
|
||||||
"stacktraceAvailable": true,
|
"stacktraceAvailable": true,
|
||||||
"lastFrame": {
|
"lastFrame": {
|
||||||
"filename": "http://example.com/browser/devtools/client/webconsole/test/browser/stub-generators/test-network-event.html",
|
"filename": "http://example.com/browser/devtools/client/webconsole/test/browser/stub-generators/test-network-event.html",
|
||||||
|
@ -264,34 +188,20 @@ rawPackets.set(`XHR POST request`, {
|
||||||
"asyncCause": null
|
"asyncCause": null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"response": {
|
|
||||||
"httpVersion": "HTTP/1.1",
|
"httpVersion": "HTTP/1.1",
|
||||||
"status": "404",
|
"status": "404",
|
||||||
"statusText": "Not Found",
|
"statusText": "Not Found",
|
||||||
"headersSize": 160,
|
|
||||||
"remoteAddress": "127.0.0.1",
|
"remoteAddress": "127.0.0.1",
|
||||||
"remotePort": 8888,
|
"remotePort": 8888,
|
||||||
"content": {
|
"mimeType": "text/html; charset=utf-8",
|
||||||
"mimeType": "text/html; charset=utf-8"
|
"waitingTime": 1,
|
||||||
},
|
"contentSize": 418,
|
||||||
"waitingTime": 2,
|
"transferredSize": 578,
|
||||||
"bodySize": 418,
|
|
||||||
"transferredSize": 578
|
|
||||||
},
|
|
||||||
"timings": {},
|
"timings": {},
|
||||||
"private": false,
|
"private": false,
|
||||||
"isThirdPartyTrackingResource": false,
|
"isThirdPartyTrackingResource": false,
|
||||||
"referrerPolicy": "no-referrer-when-downgrade",
|
"referrerPolicy": "no-referrer-when-downgrade",
|
||||||
"updates": [
|
"blockedReason": 0,
|
||||||
"eventTimings",
|
|
||||||
"requestCookies",
|
|
||||||
"requestHeaders",
|
|
||||||
"responseContent",
|
|
||||||
"responseCookies",
|
|
||||||
"responseHeaders",
|
|
||||||
"responseStart",
|
|
||||||
"securityInfo"
|
|
||||||
],
|
|
||||||
"totalTime": 1,
|
"totalTime": 1,
|
||||||
"securityState": "insecure",
|
"securityState": "insecure",
|
||||||
"isRacing": false
|
"isRacing": false
|
||||||
|
@ -301,15 +211,11 @@ rawPackets.set(`XHR POST request update`, {
|
||||||
"resourceType": "network-event",
|
"resourceType": "network-event",
|
||||||
"timeStamp": 1572867483805,
|
"timeStamp": 1572867483805,
|
||||||
"actor": "server0.conn0.netEvent36",
|
"actor": "server0.conn0.netEvent36",
|
||||||
"request": {
|
|
||||||
"url": "http://example.com/inexistent.html",
|
|
||||||
"method": "POST",
|
"method": "POST",
|
||||||
"headersSize": 385
|
"url": "http://example.com/inexistent.html",
|
||||||
},
|
|
||||||
"isXHR": true,
|
"isXHR": true,
|
||||||
"cause": {
|
"cause": {
|
||||||
"type": "xhr",
|
"type": "xhr",
|
||||||
"loadingDocumentUri": "http://example.com/browser/devtools/client/webconsole/test/browser/stub-generators/test-network-event.html",
|
|
||||||
"stacktraceAvailable": true,
|
"stacktraceAvailable": true,
|
||||||
"lastFrame": {
|
"lastFrame": {
|
||||||
"filename": "http://example.com/browser/devtools/client/webconsole/test/browser/stub-generators/test-network-event.html",
|
"filename": "http://example.com/browser/devtools/client/webconsole/test/browser/stub-generators/test-network-event.html",
|
||||||
|
@ -319,34 +225,20 @@ rawPackets.set(`XHR POST request update`, {
|
||||||
"asyncCause": null
|
"asyncCause": null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"response": {
|
|
||||||
"httpVersion": "HTTP/1.1",
|
"httpVersion": "HTTP/1.1",
|
||||||
"status": "404",
|
"status": "404",
|
||||||
"statusText": "Not Found",
|
"statusText": "Not Found",
|
||||||
"headersSize": 160,
|
|
||||||
"remoteAddress": "127.0.0.1",
|
"remoteAddress": "127.0.0.1",
|
||||||
"remotePort": 8888,
|
"remotePort": 8888,
|
||||||
"content": {
|
"mimeType": "text/html; charset=utf-8",
|
||||||
"mimeType": "text/html; charset=utf-8"
|
"waitingTime": 1,
|
||||||
},
|
"contentSize": 418,
|
||||||
"waitingTime": 2,
|
"transferredSize": 578,
|
||||||
"bodySize": 418,
|
|
||||||
"transferredSize": 578
|
|
||||||
},
|
|
||||||
"timings": {},
|
"timings": {},
|
||||||
"private": false,
|
"private": false,
|
||||||
"isThirdPartyTrackingResource": false,
|
"isThirdPartyTrackingResource": false,
|
||||||
"referrerPolicy": "no-referrer-when-downgrade",
|
"referrerPolicy": "no-referrer-when-downgrade",
|
||||||
"updates": [
|
"blockedReason": 0,
|
||||||
"eventTimings",
|
|
||||||
"requestCookies",
|
|
||||||
"requestHeaders",
|
|
||||||
"responseContent",
|
|
||||||
"responseCookies",
|
|
||||||
"responseHeaders",
|
|
||||||
"responseStart",
|
|
||||||
"securityInfo"
|
|
||||||
],
|
|
||||||
"totalTime": 2,
|
"totalTime": 2,
|
||||||
"securityState": "insecure",
|
"securityState": "insecure",
|
||||||
"isRacing": false
|
"isRacing": false
|
||||||
|
|
|
@ -6,9 +6,6 @@
|
||||||
|
|
||||||
const Services = require("Services");
|
const Services = require("Services");
|
||||||
const l10n = require("devtools/client/webconsole/utils/l10n");
|
const l10n = require("devtools/client/webconsole/utils/l10n");
|
||||||
const {
|
|
||||||
getUrlDetails,
|
|
||||||
} = require("devtools/client/netmonitor/src/utils/request-utils");
|
|
||||||
const {
|
const {
|
||||||
ResourceWatcher,
|
ResourceWatcher,
|
||||||
} = require("devtools/shared/resources/resource-watcher");
|
} = require("devtools/shared/resources/resource-watcher");
|
||||||
|
@ -362,24 +359,7 @@ function transformCSSMessageResource(cssMessageResource) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function transformNetworkEventResource(networkEventResource) {
|
function transformNetworkEventResource(networkEventResource) {
|
||||||
return new NetworkEventMessage({
|
return new NetworkEventMessage(networkEventResource);
|
||||||
targetFront: networkEventResource.targetFront,
|
|
||||||
actor: networkEventResource.actor,
|
|
||||||
isXHR: networkEventResource.isXHR,
|
|
||||||
request: networkEventResource.request,
|
|
||||||
response: networkEventResource.response,
|
|
||||||
timeStamp: networkEventResource.timeStamp,
|
|
||||||
totalTime: networkEventResource.totalTime,
|
|
||||||
url: networkEventResource.request.url,
|
|
||||||
urlDetails: getUrlDetails(networkEventResource.request.url),
|
|
||||||
method: networkEventResource.request.method,
|
|
||||||
updates: networkEventResource.updates,
|
|
||||||
cause: networkEventResource.cause,
|
|
||||||
private: networkEventResource.private,
|
|
||||||
securityState: networkEventResource.securityState,
|
|
||||||
chromeContext: networkEventResource.chromeContext,
|
|
||||||
blockedReason: networkEventResource.blockedReason,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function transformEvaluationResultPacket(packet) {
|
function transformEvaluationResultPacket(packet) {
|
||||||
|
@ -790,8 +770,8 @@ function getNaturalOrder(messageA, messageB) {
|
||||||
function isMessageNetworkError(message) {
|
function isMessageNetworkError(message) {
|
||||||
return (
|
return (
|
||||||
message.source === MESSAGE_SOURCE.NETWORK &&
|
message.source === MESSAGE_SOURCE.NETWORK &&
|
||||||
message?.response?.status &&
|
message?.status &&
|
||||||
message.response.status.toString().match(/^[4,5]\d\d$/)
|
message?.status.toString().match(/^[4,5]\d\d$/)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -423,32 +423,13 @@ class WebConsoleUI {
|
||||||
}
|
}
|
||||||
|
|
||||||
_onResourceUpdated(updates) {
|
_onResourceUpdated(updates) {
|
||||||
const messages = [];
|
const messageUpdates = updates
|
||||||
for (const { resource } of updates) {
|
.filter(
|
||||||
if (
|
({ resource }) =>
|
||||||
resource.resourceType == this.hud.resourceWatcher.TYPES.NETWORK_EVENT
|
resource.resourceType == this.hud.resourceWatcher.TYPES.NETWORK_EVENT
|
||||||
) {
|
)
|
||||||
// network-message-updated will emit when all the update message arrives.
|
.map(({ resource }) => resource);
|
||||||
// Since we can't ensure the order of the network update, we check
|
this.wrapper.dispatchMessagesUpdate(messageUpdates);
|
||||||
// that message.updates has all we need.
|
|
||||||
// Note that 'requestPostData' is sent only for POST requests, so we need
|
|
||||||
// to count with that.
|
|
||||||
const NUMBER_OF_NETWORK_UPDATE = 8;
|
|
||||||
|
|
||||||
let expectedLength = NUMBER_OF_NETWORK_UPDATE;
|
|
||||||
if (resource.updates.includes("responseCache")) {
|
|
||||||
expectedLength++;
|
|
||||||
}
|
|
||||||
if (resource.updates.includes("requestPostData")) {
|
|
||||||
expectedLength++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resource.updates.length === expectedLength) {
|
|
||||||
messages.push(resource);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.wrapper.dispatchMessagesUpdate(messages);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -30,23 +30,30 @@ module.exports = async function({
|
||||||
}
|
}
|
||||||
|
|
||||||
const webConsoleFront = await targetFront.getFront("console");
|
const webConsoleFront = await targetFront.getFront("console");
|
||||||
const _resources = new Map();
|
const resources = new Map();
|
||||||
|
|
||||||
function onNetworkEvent(packet) {
|
function onNetworkEvent(packet) {
|
||||||
const actor = packet.eventActor;
|
const actor = packet.eventActor;
|
||||||
const resource = {
|
|
||||||
|
resources.set(actor.actor, {
|
||||||
|
resourceId: actor.channelId,
|
||||||
|
resourceType: ResourceWatcher.TYPES.NETWORK_EVENT,
|
||||||
|
isBlocked: !!actor.blockedReason,
|
||||||
|
types: [],
|
||||||
|
resourceUpdates: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
onAvailable([
|
||||||
|
{
|
||||||
resourceId: actor.channelId,
|
resourceId: actor.channelId,
|
||||||
resourceType: ResourceWatcher.TYPES.NETWORK_EVENT,
|
resourceType: ResourceWatcher.TYPES.NETWORK_EVENT,
|
||||||
timeStamp: actor.timeStamp,
|
timeStamp: actor.timeStamp,
|
||||||
actor: actor.actor,
|
actor: actor.actor,
|
||||||
startedDateTime: actor.startedDateTime,
|
startedDateTime: actor.startedDateTime,
|
||||||
request: {
|
|
||||||
url: actor.url,
|
url: actor.url,
|
||||||
method: actor.method,
|
method: actor.method,
|
||||||
},
|
|
||||||
isXHR: actor.isXHR,
|
isXHR: actor.isXHR,
|
||||||
cause: actor.cause,
|
cause: { type: actor.cause.type },
|
||||||
response: {},
|
|
||||||
timings: {},
|
timings: {},
|
||||||
private: actor.private,
|
private: actor.private,
|
||||||
fromCache: actor.fromCache,
|
fromCache: actor.fromCache,
|
||||||
|
@ -59,61 +66,44 @@ module.exports = async function({
|
||||||
actor.cause.type == "websocket"
|
actor.cause.type == "websocket"
|
||||||
? actor.url.replace(/^http/, "ws")
|
? actor.url.replace(/^http/, "ws")
|
||||||
: actor.channelId,
|
: actor.channelId,
|
||||||
updates: [],
|
},
|
||||||
};
|
]);
|
||||||
|
|
||||||
// Lets remove the stacktrace info here as
|
|
||||||
// it is passed from the the server by the NETWORK_EVENT_STACKTRACE
|
|
||||||
// resource type.
|
|
||||||
delete resource.cause.stacktraceAvailable;
|
|
||||||
delete resource.cause.lastFrame;
|
|
||||||
|
|
||||||
_resources.set(actor.actor, resource);
|
|
||||||
onAvailable([resource]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onNetworkEventUpdate(packet) {
|
function onNetworkEventUpdate(packet) {
|
||||||
const resource = _resources.get(packet.from);
|
const resource = resources.get(packet.from);
|
||||||
|
|
||||||
if (!resource) {
|
if (!resource) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateType = packet.updateType;
|
const {
|
||||||
const resourceUpdates = {};
|
types,
|
||||||
resourceUpdates.updates = [...resource.updates, updateType];
|
resourceUpdates,
|
||||||
|
resourceId,
|
||||||
|
resourceType,
|
||||||
|
isBlocked,
|
||||||
|
} = resource;
|
||||||
|
|
||||||
switch (updateType) {
|
switch (packet.updateType) {
|
||||||
case "requestHeaders":
|
|
||||||
resourceUpdates.request = Object.assign({}, resource.request, {
|
|
||||||
headersSize: packet.headersSize,
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case "requestPostData":
|
case "requestPostData":
|
||||||
resourceUpdates.request = Object.assign({}, resource.request, {
|
resourceUpdates.contentSize = packet.dataSize;
|
||||||
bodySize: packet.dataSize,
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case "responseStart":
|
case "responseStart":
|
||||||
resourceUpdates.response = Object.assign({}, resource.response, {
|
resourceUpdates.httpVersion = packet.response.httpVersion;
|
||||||
httpVersion: packet.response.httpVersion,
|
resourceUpdates.status = packet.response.status;
|
||||||
status: packet.response.status,
|
resourceUpdates.statusText = packet.response.statusText;
|
||||||
statusText: packet.response.statusText,
|
resourceUpdates.remoteAddress = packet.response.remoteAddress;
|
||||||
headersSize: packet.response.headersSize,
|
resourceUpdates.remotePort = packet.response.remotePort;
|
||||||
remoteAddress: packet.response.remoteAddress,
|
resourceUpdates.mimeType = packet.response.mimeType;
|
||||||
remotePort: packet.response.remotePort,
|
resourceUpdates.waitingTime = packet.response.waitingTime;
|
||||||
content: {
|
|
||||||
mimeType: packet.response.mimeType,
|
|
||||||
},
|
|
||||||
waitingTime: packet.response.waitingTime,
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case "responseContent":
|
case "responseContent":
|
||||||
resourceUpdates.response = Object.assign({}, resource.response, {
|
resourceUpdates.contentSize = packet.contentSize;
|
||||||
bodySize: packet.contentSize,
|
resourceUpdates.transferredSize = packet.transferredSize;
|
||||||
transferredSize: packet.transferredSize,
|
resourceUpdates.mimeType = packet.mimeType;
|
||||||
content: { mimeType: packet.mimeType },
|
resourceUpdates.blockingExtension = packet.blockingExtension;
|
||||||
});
|
resourceUpdates.blockedReason = packet.blockedReason;
|
||||||
break;
|
break;
|
||||||
case "eventTimings":
|
case "eventTimings":
|
||||||
resourceUpdates.totalTime = packet.totalTime;
|
resourceUpdates.totalTime = packet.totalTime;
|
||||||
|
@ -123,40 +113,40 @@ module.exports = async function({
|
||||||
resourceUpdates.isRacing = packet.isRacing;
|
resourceUpdates.isRacing = packet.isRacing;
|
||||||
break;
|
break;
|
||||||
case "responseCache":
|
case "responseCache":
|
||||||
resourceUpdates.response = Object.assign({}, resource.response, {
|
resourceUpdates.responseCache = packet.responseCache;
|
||||||
responseCache: packet.responseCache,
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update local resource.
|
resourceUpdates[`${packet.updateType}Available`] = true;
|
||||||
Object.assign(resource, resourceUpdates);
|
types.push(packet.updateType);
|
||||||
|
|
||||||
|
if (isBlocked) {
|
||||||
|
// Blocked requests
|
||||||
|
if (
|
||||||
|
!types.includes("requestHeaders") ||
|
||||||
|
!types.includes("requestCookies")
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
|
// Un-blocked requests
|
||||||
|
!types.includes("requestHeaders") ||
|
||||||
|
!types.includes("requestCookies") ||
|
||||||
|
!types.includes("eventTimings") ||
|
||||||
|
!types.includes("responseContent")
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
onUpdated([
|
onUpdated([
|
||||||
{
|
{
|
||||||
resourceType: resource.resourceType,
|
resourceType,
|
||||||
resourceId: resource.resourceId,
|
resourceId,
|
||||||
resourceUpdates,
|
resourceUpdates,
|
||||||
updateType,
|
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (resource.blockedReason) {
|
resources.delete(resource.actor);
|
||||||
// Blocked requests
|
|
||||||
if (
|
|
||||||
resource.updates.includes("requestHeaders") &&
|
|
||||||
resource.updates.includes("requestCookies")
|
|
||||||
) {
|
|
||||||
_resources.delete(resource.actor);
|
|
||||||
}
|
|
||||||
} else if (
|
|
||||||
resource.updates.includes("requestHeaders") &&
|
|
||||||
resource.updates.includes("requestCookies") &&
|
|
||||||
resource.updates.includes("eventTimings") &&
|
|
||||||
resource.updates.includes("responseContent")
|
|
||||||
) {
|
|
||||||
_resources.delete(resource.actor);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
webConsoleFront.on("serverNetworkEvent", onNetworkEvent);
|
webConsoleFront.on("serverNetworkEvent", onNetworkEvent);
|
||||||
|
|
|
@ -847,4 +847,6 @@ const ResourceTransformers = {
|
||||||
.ROOT_NODE]: require("devtools/shared/resources/transformers/root-node"),
|
.ROOT_NODE]: require("devtools/shared/resources/transformers/root-node"),
|
||||||
[ResourceWatcher.TYPES
|
[ResourceWatcher.TYPES
|
||||||
.SESSION_STORAGE]: require("devtools/shared/resources/transformers/storage-session-storage.js"),
|
.SESSION_STORAGE]: require("devtools/shared/resources/transformers/storage-session-storage.js"),
|
||||||
|
[ResourceWatcher.TYPES
|
||||||
|
.NETWORK_EVENT]: require("devtools/shared/resources/transformers/network-events"),
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,7 +35,6 @@ support-files =
|
||||||
[browser_resources_getAllResources.js]
|
[browser_resources_getAllResources.js]
|
||||||
[browser_resources_network_event_stacktraces.js]
|
[browser_resources_network_event_stacktraces.js]
|
||||||
[browser_resources_network_events.js]
|
[browser_resources_network_events.js]
|
||||||
skip-if = os == "linux" #Bug 1655183
|
|
||||||
[browser_resources_platform_messages.js]
|
[browser_resources_platform_messages.js]
|
||||||
[browser_resources_root_node.js]
|
[browser_resources_root_node.js]
|
||||||
[browser_resources_several_resources.js]
|
[browser_resources_several_resources.js]
|
||||||
|
|
|
@ -18,63 +18,36 @@ add_task(async function() {
|
||||||
await testNetworkEventResourcesWithExistingResources();
|
await testNetworkEventResourcesWithExistingResources();
|
||||||
await testNetworkEventResourcesWithoutExistingResources();
|
await testNetworkEventResourcesWithoutExistingResources();
|
||||||
|
|
||||||
// These tests would be enabled when the server-side work is done. See Bug 1644191
|
|
||||||
// info("Test network events server listener");
|
// info("Test network events server listener");
|
||||||
// await pushPref("devtools.testing.enableServerWatcherSupport", true);
|
// await pushPref("devtools.testing.enableServerWatcherSupport", true);
|
||||||
// await testNetworkEventResources();
|
// await testNetworkEventResourcesWithExistingResources();
|
||||||
// await testNetworkEventResourcesWithIgnoreExistingResources();
|
// await testNetworkEventResourcesWithoutExistingResources();
|
||||||
});
|
});
|
||||||
|
|
||||||
const UPDATES = [
|
|
||||||
"requestHeaders",
|
|
||||||
"requestCookies",
|
|
||||||
"responseStart",
|
|
||||||
"securityInfo",
|
|
||||||
"responseHeaders",
|
|
||||||
"responseCookies",
|
|
||||||
"eventTimings",
|
|
||||||
"responseContent",
|
|
||||||
];
|
|
||||||
|
|
||||||
async function testNetworkEventResourcesWithExistingResources() {
|
async function testNetworkEventResourcesWithExistingResources() {
|
||||||
info(`Tests for network event resources with the existing resources`);
|
info(`Tests for network event resources with the existing resources`);
|
||||||
await testNetworkEventResources({
|
await testNetworkEventResources({
|
||||||
ignoreExistingResources: false,
|
ignoreExistingResources: false,
|
||||||
// 1 available event fired, for the existing resource in the cache.
|
// 1 available event fired, for the existing resource in the cache.
|
||||||
// 1 available event fired, when live request is created.
|
// 1 available event fired, when live request is created.
|
||||||
expectedOnAvailableCounts: 2,
|
totalExpectedOnAvailableCounts: 2,
|
||||||
// 8 update events fired, when live request is updated.
|
// 1 update events fired, when live request is updated.
|
||||||
expectedOnUpdatedCounts: 8,
|
totalExpectedOnUpdatedCounts: 1,
|
||||||
expectedResourcesOnAvailable: {
|
expectedResourcesOnAvailable: {
|
||||||
[`${EXAMPLE_DOMAIN}existing_post.html`]: {
|
[`${EXAMPLE_DOMAIN}cached_post.html`]: {
|
||||||
resourceType: ResourceWatcher.TYPES.NETWORK_EVENT,
|
resourceType: ResourceWatcher.TYPES.NETWORK_EVENT,
|
||||||
request: {
|
|
||||||
url: `${EXAMPLE_DOMAIN}existing_post.html`,
|
|
||||||
method: "POST",
|
method: "POST",
|
||||||
},
|
},
|
||||||
// gets reset based on the type of request
|
|
||||||
updates: [],
|
|
||||||
},
|
|
||||||
[`${EXAMPLE_DOMAIN}live_get.html`]: {
|
[`${EXAMPLE_DOMAIN}live_get.html`]: {
|
||||||
resourceType: ResourceWatcher.TYPES.NETWORK_EVENT,
|
resourceType: ResourceWatcher.TYPES.NETWORK_EVENT,
|
||||||
request: {
|
|
||||||
url: `${EXAMPLE_DOMAIN}live_get.html`,
|
|
||||||
method: "GET",
|
method: "GET",
|
||||||
},
|
},
|
||||||
// Throttling makes us receive the available event
|
|
||||||
// after processing all the updates events
|
|
||||||
updates: UPDATES,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
expectedResourcesOnUpdated: {
|
expectedResourcesOnUpdated: {
|
||||||
[`${EXAMPLE_DOMAIN}live_get.html`]: {
|
[`${EXAMPLE_DOMAIN}live_get.html`]: {
|
||||||
resourceType: ResourceWatcher.TYPES.NETWORK_EVENT,
|
resourceType: ResourceWatcher.TYPES.NETWORK_EVENT,
|
||||||
request: {
|
|
||||||
url: `${EXAMPLE_DOMAIN}live_get.html`,
|
|
||||||
method: "GET",
|
method: "GET",
|
||||||
},
|
},
|
||||||
updates: UPDATES,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -84,30 +57,20 @@ async function testNetworkEventResourcesWithoutExistingResources() {
|
||||||
await testNetworkEventResources({
|
await testNetworkEventResources({
|
||||||
ignoreExistingResources: true,
|
ignoreExistingResources: true,
|
||||||
// 1 available event fired, when live request is created.
|
// 1 available event fired, when live request is created.
|
||||||
expectedOnAvailableCounts: 1,
|
totalExpectedOnAvailableCounts: 1,
|
||||||
// 8 update events fired, when live request is updated.
|
// 1 update events fired, when live request is updated.
|
||||||
expectedOnUpdatedCounts: 8,
|
totalExpectedOnUpdatedCounts: 1,
|
||||||
expectedResourcesOnAvailable: {
|
expectedResourcesOnAvailable: {
|
||||||
[`${EXAMPLE_DOMAIN}live_get.html`]: {
|
[`${EXAMPLE_DOMAIN}live_get.html`]: {
|
||||||
resourceType: ResourceWatcher.TYPES.NETWORK_EVENT,
|
resourceType: ResourceWatcher.TYPES.NETWORK_EVENT,
|
||||||
request: {
|
|
||||||
url: `${EXAMPLE_DOMAIN}live_get.html`,
|
|
||||||
method: "GET",
|
method: "GET",
|
||||||
},
|
},
|
||||||
// Throttling makes us receive the available event
|
|
||||||
// after processing all the updates events
|
|
||||||
updates: UPDATES,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
expectedResourcesOnUpdated: {
|
expectedResourcesOnUpdated: {
|
||||||
[`${EXAMPLE_DOMAIN}live_get.html`]: {
|
[`${EXAMPLE_DOMAIN}live_get.html`]: {
|
||||||
resourceType: ResourceWatcher.TYPES.NETWORK_EVENT,
|
resourceType: ResourceWatcher.TYPES.NETWORK_EVENT,
|
||||||
request: {
|
|
||||||
url: `${EXAMPLE_DOMAIN}live_get.html`,
|
|
||||||
method: "GET",
|
method: "GET",
|
||||||
},
|
},
|
||||||
updates: UPDATES,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -118,55 +81,35 @@ async function testNetworkEventResources(options) {
|
||||||
tab
|
tab
|
||||||
);
|
);
|
||||||
|
|
||||||
const actualResourcesOnAvailable = {};
|
|
||||||
const actualResourcesOnUpdated = {};
|
|
||||||
|
|
||||||
info(
|
info(
|
||||||
`Trigger some network requests *before* calling ResourceWatcher.watchResources
|
`Trigger some network requests *before* calling ResourceWatcher.watchResources
|
||||||
in order to assert the behavior of already existing network events.`
|
in order to assert the behavior of already existing network events.`
|
||||||
);
|
);
|
||||||
|
|
||||||
let onResourceAvailable = () => {};
|
let onResourceAvailable = () => {};
|
||||||
let onResourceUpdated = () => {};
|
let onResourceUpdated = () => {};
|
||||||
const waitOnAllExpectedUpdatesForExistingRequests = new Promise(resolve => {
|
|
||||||
const existingRequestUrl = `${EXAMPLE_DOMAIN}existing_post.html`;
|
|
||||||
|
|
||||||
|
// Lets make sure there is already a network event resource in the cache.
|
||||||
|
const waitOnRequestForResourceWatcherCache = new Promise(resolve => {
|
||||||
onResourceAvailable = resources => {
|
onResourceAvailable = resources => {
|
||||||
for (const resource of resources) {
|
for (const resource of resources) {
|
||||||
// A blocked request would only have two updates so lets also resolve here
|
is(
|
||||||
if (
|
resource.resourceType,
|
||||||
resource.request.url == existingRequestUrl &&
|
ResourceWatcher.TYPES.NETWORK_EVENT,
|
||||||
resource.blockedReason &&
|
"Received a network event resource"
|
||||||
resource.updates.length == 2
|
);
|
||||||
) {
|
|
||||||
// Reset the updates expectation as the request is blocked
|
|
||||||
if (options.expectedResourcesOnAvailable[resource.request.url]) {
|
|
||||||
options.expectedResourcesOnAvailable[
|
|
||||||
resource.request.url
|
|
||||||
].updates = [...resource.updates];
|
|
||||||
}
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onResourceUpdated = updates => {
|
onResourceUpdated = updates => {
|
||||||
for (const { resource } of updates) {
|
for (const { resource } of updates) {
|
||||||
// Wait until all the update events have fired for the existing request.
|
is(
|
||||||
// Handle both blocked and unblocked requests
|
resource.resourceType,
|
||||||
if (
|
ResourceWatcher.TYPES.NETWORK_EVENT,
|
||||||
resource.request.url == existingRequestUrl &&
|
"Received a network update event resource"
|
||||||
(resource.updates.length == 8 ||
|
);
|
||||||
(resource.blockedReason && resource.updates.length == 2))
|
|
||||||
) {
|
|
||||||
// Makes sure the expectation always correct (for either blocked or unblocked requests)
|
|
||||||
if (options.expectedResourcesOnAvailable[resource.request.url]) {
|
|
||||||
options.expectedResourcesOnAvailable[
|
|
||||||
resource.request.url
|
|
||||||
].updates = [...resource.updates];
|
|
||||||
}
|
|
||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
resourceWatcher
|
resourceWatcher
|
||||||
|
@ -177,23 +120,29 @@ async function testNetworkEventResources(options) {
|
||||||
.then(() => {
|
.then(() => {
|
||||||
// We can only trigger the requests once `watchResources` settles, otherwise the
|
// We can only trigger the requests once `watchResources` settles, otherwise the
|
||||||
// thread might be paused.
|
// thread might be paused.
|
||||||
triggerNetworkRequests(tab.linkedBrowser, EXISTING_REQUESTS_COMMANDS);
|
triggerNetworkRequests(tab.linkedBrowser, [cachedRequest]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
await waitOnAllExpectedUpdatesForExistingRequests;
|
await waitOnRequestForResourceWatcherCache;
|
||||||
|
|
||||||
|
const actualResourcesOnAvailable = {};
|
||||||
|
const actualResourcesOnUpdated = {};
|
||||||
|
|
||||||
let {
|
let {
|
||||||
expectedOnAvailableCounts,
|
totalExpectedOnAvailableCounts,
|
||||||
expectedOnUpdatedCounts,
|
totalExpectedOnUpdatedCounts,
|
||||||
|
expectedResourcesOnAvailable,
|
||||||
|
expectedResourcesOnUpdated,
|
||||||
|
|
||||||
ignoreExistingResources,
|
ignoreExistingResources,
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
const waitForAllOnAvailableEvents = waitUntil(
|
const waitForAllExpectedOnAvailableEvents = waitUntil(
|
||||||
() => expectedOnAvailableCounts == 0
|
() => totalExpectedOnAvailableCounts == 0
|
||||||
);
|
);
|
||||||
const waitForAllOnUpdatedEvents = waitUntil(
|
const waitForAllExpectedOnUpdatedEvents = waitUntil(
|
||||||
() => expectedOnUpdatedCounts == 0
|
() => totalExpectedOnUpdatedCounts == 0
|
||||||
);
|
);
|
||||||
|
|
||||||
const onAvailable = resources => {
|
const onAvailable = resources => {
|
||||||
|
@ -203,13 +152,12 @@ async function testNetworkEventResources(options) {
|
||||||
ResourceWatcher.TYPES.NETWORK_EVENT,
|
ResourceWatcher.TYPES.NETWORK_EVENT,
|
||||||
"Received a network event resource"
|
"Received a network event resource"
|
||||||
);
|
);
|
||||||
actualResourcesOnAvailable[resource.request.url] = {
|
actualResourcesOnAvailable[resource.url] = {
|
||||||
resourceId: resource.resourceId,
|
resourceId: resource.resourceId,
|
||||||
resourceType: resource.resourceType,
|
resourceType: resource.resourceType,
|
||||||
request: resource.request,
|
method: resource.method,
|
||||||
updates: [...resource.updates],
|
|
||||||
};
|
};
|
||||||
expectedOnAvailableCounts--;
|
totalExpectedOnAvailableCounts--;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -220,13 +168,12 @@ async function testNetworkEventResources(options) {
|
||||||
ResourceWatcher.TYPES.NETWORK_EVENT,
|
ResourceWatcher.TYPES.NETWORK_EVENT,
|
||||||
"Received a network update event resource"
|
"Received a network update event resource"
|
||||||
);
|
);
|
||||||
actualResourcesOnUpdated[resource.request.url] = {
|
actualResourcesOnUpdated[resource.url] = {
|
||||||
resourceId: resource.resourceId,
|
resourceId: resource.resourceId,
|
||||||
resourceType: resource.resourceType,
|
resourceType: resource.resourceType,
|
||||||
request: resource.request,
|
method: resource.method,
|
||||||
updates: [...resource.updates],
|
|
||||||
};
|
};
|
||||||
expectedOnUpdatedCounts--;
|
totalExpectedOnUpdatedCounts--;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -240,14 +187,17 @@ async function testNetworkEventResources(options) {
|
||||||
`Trigger the rest of the requests *after* calling ResourceWatcher.watchResources
|
`Trigger the rest of the requests *after* calling ResourceWatcher.watchResources
|
||||||
in order to assert the behavior of live network events.`
|
in order to assert the behavior of live network events.`
|
||||||
);
|
);
|
||||||
await triggerNetworkRequests(tab.linkedBrowser, LIVE_REQUESTS_COMMANDS);
|
await triggerNetworkRequests(tab.linkedBrowser, [liveRequest]);
|
||||||
|
|
||||||
await Promise.all([waitForAllOnAvailableEvents, waitForAllOnUpdatedEvents]);
|
await Promise.all([
|
||||||
|
waitForAllExpectedOnAvailableEvents,
|
||||||
|
waitForAllExpectedOnUpdatedEvents,
|
||||||
|
]);
|
||||||
|
|
||||||
info("Check the resources on available");
|
info("Check the resources on available");
|
||||||
is(
|
is(
|
||||||
Object.keys(actualResourcesOnAvailable).length,
|
Object.keys(actualResourcesOnAvailable).length,
|
||||||
Object.keys(options.expectedResourcesOnAvailable).length,
|
Object.keys(expectedResourcesOnAvailable).length,
|
||||||
"Got the expected number of network events fired onAvailable"
|
"Got the expected number of network events fired onAvailable"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -259,8 +209,8 @@ async function testNetworkEventResources(options) {
|
||||||
);
|
);
|
||||||
|
|
||||||
// assert the resources emitted when the network event is created
|
// assert the resources emitted when the network event is created
|
||||||
for (const key in options.expectedResourcesOnAvailable) {
|
for (const key in expectedResourcesOnAvailable) {
|
||||||
const expected = options.expectedResourcesOnAvailable[key];
|
const expected = expectedResourcesOnAvailable[key];
|
||||||
const actual = actualResourcesOnAvailable[key];
|
const actual = actualResourcesOnAvailable[key];
|
||||||
assertResources(actual, expected);
|
assertResources(actual, expected);
|
||||||
}
|
}
|
||||||
|
@ -269,20 +219,15 @@ async function testNetworkEventResources(options) {
|
||||||
|
|
||||||
is(
|
is(
|
||||||
Object.keys(actualResourcesOnUpdated).length,
|
Object.keys(actualResourcesOnUpdated).length,
|
||||||
Object.keys(options.expectedResourcesOnUpdated).length,
|
Object.keys(expectedResourcesOnUpdated).length,
|
||||||
"Got the expected number of network events fired onUpdated"
|
"Got the expected number of network events fired onUpdated"
|
||||||
);
|
);
|
||||||
|
|
||||||
// assert the resources emitted when the network event is updated
|
// assert the resources emitted when the network event is updated
|
||||||
for (const key in options.expectedResourcesOnUpdated) {
|
for (const key in expectedResourcesOnUpdated) {
|
||||||
const expected = options.expectedResourcesOnUpdated[key];
|
const expected = expectedResourcesOnUpdated[key];
|
||||||
const actual = actualResourcesOnUpdated[key];
|
const actual = actualResourcesOnUpdated[key];
|
||||||
assertResources(actual, expected);
|
assertResources(actual, expected);
|
||||||
is(
|
|
||||||
actual.updates.length,
|
|
||||||
expected.updates.length,
|
|
||||||
"The number of updates is correct"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await resourceWatcher.unwatchResources(
|
await resourceWatcher.unwatchResources(
|
||||||
|
@ -312,14 +257,8 @@ function assertResources(actual, expected) {
|
||||||
expected.resourceType,
|
expected.resourceType,
|
||||||
"The resource type is correct"
|
"The resource type is correct"
|
||||||
);
|
);
|
||||||
is(actual.request.url, expected.request.url, "The url is correct");
|
is(actual.method, expected.method, "The method is correct");
|
||||||
is(actual.request.method, expected.request.method, "The method is correct");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const EXISTING_REQUESTS_COMMANDS = [
|
const cachedRequest = `await fetch("/cached_post.html", { method: "POST" });`;
|
||||||
`await fetch("/existing_post.html", { method: "POST" });`,
|
const liveRequest = `await fetch("/live_get.html", { method: "GET" });`;
|
||||||
];
|
|
||||||
|
|
||||||
const LIVE_REQUESTS_COMMANDS = [
|
|
||||||
`await fetch("/live_get.html", { method: "GET" });`,
|
|
||||||
];
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
DevToolsModules(
|
DevToolsModules(
|
||||||
"console-messages.js",
|
"console-messages.js",
|
||||||
"error-messages.js",
|
"error-messages.js",
|
||||||
|
"network-events.js",
|
||||||
"root-node.js",
|
"root-node.js",
|
||||||
"storage-local-storage.js",
|
"storage-local-storage.js",
|
||||||
"storage-session-storage.js",
|
"storage-session-storage.js",
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
/* 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 {
|
||||||
|
getUrlDetails,
|
||||||
|
// eslint-disable-next-line mozilla/reject-some-requires
|
||||||
|
} = require("devtools/client/netmonitor/src/utils/request-utils");
|
||||||
|
|
||||||
|
module.exports = function({ resource }) {
|
||||||
|
resource.urlDetails = getUrlDetails(resource.url);
|
||||||
|
resource.startedMs = Date.parse(resource.startedDateTime);
|
||||||
|
return resource;
|
||||||
|
};
|
Загрузка…
Ссылка в новой задаче