Bug 673148 - (async-webconsole) Part 4 - Make network logging async; r=rcampbell

This commit is contained in:
Mihai Sucan 2012-05-29 15:48:05 +03:00
parent f61281cfb9
commit e7e699e7f7
18 changed files with 2379 additions and 1785 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -13,6 +13,7 @@ include $(DEPTH)/config/autoconf.mk
EXTRA_JS_MODULES = \
PropertyPanel.jsm \
NetworkHelper.jsm \
NetworkPanel.jsm \
AutocompletePopup.jsm \
WebConsoleUtils.jsm \
$(NULL)

View File

@ -49,6 +49,7 @@
* Austin Andrews
* Christoph Dorn
* Steven Roussey (AppCenter Inc, Network54)
* Mihai Sucan (Mozilla Corp.)
*/
const Cc = Components.classes;
@ -68,7 +69,7 @@ var EXPORTED_SYMBOLS = ["NetworkHelper"];
/**
* Helper object for networking stuff.
*
* All of the following functions have been taken from the Firebug source. They
* Most of the following functions have been taken from the Firebug source. They
* have been modified to match the Firefox coding rules.
*/
@ -128,12 +129,13 @@ var NetworkHelper =
* Reads the posted text from aRequest.
*
* @param nsIHttpChannel aRequest
* @param nsIDOMNode aBrowser
* @param string aCharset
* The content document charset, used when reading the POSTed data.
* @returns string or null
* Returns the posted string if it was possible to read from aRequest
* otherwise null.
*/
readPostTextFromRequest: function NH_readPostTextFromRequest(aRequest, aBrowser)
readPostTextFromRequest: function NH_readPostTextFromRequest(aRequest, aCharset)
{
if (aRequest instanceof Ci.nsIUploadChannel) {
let iStream = aRequest.uploadStream;
@ -150,8 +152,7 @@ var NetworkHelper =
}
// Read data from the stream.
let charset = aBrowser.contentWindow.document.characterSet;
let text = this.readAndConvertFromStream(iStream, charset);
let text = this.readAndConvertFromStream(iStream, aCharset);
// Seek locks the file, so seek to the beginning only if necko hasn't
// read it yet, since necko doesn't seek to 0 before reading (at lest
@ -167,14 +168,15 @@ var NetworkHelper =
/**
* Reads the posted text from the page's cache.
*
* @param nsIDOMNode aBrowser
* @param nsIDocShell aDocShell
* @param string aCharset
* @returns string or null
* Returns the posted string if it was possible to read from aBrowser
* otherwise null.
* Returns the posted string if it was possible to read from
* aDocShell otherwise null.
*/
readPostTextFromPage: function NH_readPostTextFromPage(aBrowser)
readPostTextFromPage: function NH_readPostTextFromPage(aDocShell, aCharset)
{
let webNav = aBrowser.webNavigation;
let webNav = aDocShell.QueryInterface(Ci.nsIWebNavigation);
if (webNav instanceof Ci.nsIWebPageDescriptor) {
let descriptor = webNav.currentDescriptor;
@ -182,8 +184,7 @@ var NetworkHelper =
descriptor instanceof Ci.nsISeekableStream) {
descriptor.seek(NS_SEEK_SET, 0);
let charset = browser.contentWindow.document.characterSet;
return this.readAndConvertFromStream(descriptor, charset);
return this.readAndConvertFromStream(descriptor, aCharset);
}
}
return null;
@ -266,6 +267,81 @@ var NetworkHelper =
});
},
/**
* Parse a raw Cookie header value.
*
* @param string aHeader
* The raw Cookie header value.
* @return array
* Array holding an object for each cookie. Each object holds the
* following properties: name and value.
*/
parseCookieHeader: function NH_parseCookieHeader(aHeader)
{
let cookies = aHeader.split(";");
let result = [];
cookies.forEach(function(aCookie) {
let [name, value] = aCookie.split("=");
result.push({name: unescape(name.trim()),
value: unescape(value.trim())});
});
return result;
},
/**
* Parse a raw Set-Cookie header value.
*
* @param string aHeader
* The raw Set-Cookie header value.
* @return array
* Array holding an object for each cookie. Each object holds the
* following properties: name, value, secure (boolean), httpOnly
* (boolean), path, domain and expires (ISO date string).
*/
parseSetCookieHeader: function NH_parseSetCookieHeader(aHeader)
{
let rawCookies = aHeader.split(/\r\n|\n|\r/);
let cookies = [];
rawCookies.forEach(function(aCookie) {
let name = unescape(aCookie.substr(0, aCookie.indexOf("=")).trim());
let parts = aCookie.substr(aCookie.indexOf("=") + 1).split(";");
let value = unescape(parts.shift().trim());
let cookie = {name: name, value: value};
parts.forEach(function(aPart) {
let part = aPart.trim();
if (part.toLowerCase() == "secure") {
cookie.secure = true;
}
else if (part.toLowerCase() == "httponly") {
cookie.httpOnly = true;
}
else if (part.indexOf("=") > -1) {
let pair = part.split("=");
pair[0] = pair[0].toLowerCase();
if (pair[0] == "path" || pair[0] == "domain") {
cookie[pair[0]] = pair[1];
}
else if (pair[0] == "expires") {
try {
pair[1] = pair[1].replace(/-/g, ' ');
cookie.expires = new Date(pair[1]).toISOString();
}
catch (ex) { }
}
}
});
cookies.push(cookie);
});
return cookies;
},
// This is a list of all the mime category maps jviereck could find in the
// firebug code base.
mimeCategoryMap: {
@ -333,6 +409,7 @@ var NetworkHelper =
"audio/x-wav": "media",
"text/json": "json",
"application/x-json": "json",
"application/json-rpc": "json"
"application/json-rpc": "json",
"application/x-web-app-manifest+json": "json",
}
}

View File

@ -0,0 +1,668 @@
/* -*- Mode: js2; js2-basic-offset: 2; indent-tabs-mode: nil; -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "mimeService", "@mozilla.org/mime;1",
"nsIMIMEService");
XPCOMUtils.defineLazyModuleGetter(this, "NetworkHelper",
"resource:///modules/NetworkHelper.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
"resource://gre/modules/NetUtil.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "WebConsoleUtils",
"resource:///modules/WebConsoleUtils.jsm");
XPCOMUtils.defineLazyGetter(this, "l10n", function() {
return WebConsoleUtils.l10n;
});
var EXPORTED_SYMBOLS = ["NetworkPanel"];
/**
* Creates a new NetworkPanel.
*
* @param nsIDOMNode aParent
* Parent node to append the created panel to.
* @param object aHttpActivity
* HttpActivity to display in the panel.
*/
function NetworkPanel(aParent, aHttpActivity)
{
let doc = aParent.ownerDocument;
this.httpActivity = aHttpActivity;
// Create the underlaying panel
this.panel = createElement(doc, "panel", {
label: l10n.getStr("NetworkPanel.label"),
titlebar: "normal",
noautofocus: "true",
noautohide: "true",
close: "true"
});
// Create the iframe that displays the NetworkPanel XHTML.
this.iframe = createAndAppendElement(this.panel, "iframe", {
src: "chrome://browser/content/NetworkPanel.xhtml",
type: "content",
flex: "1"
});
let self = this;
// Destroy the panel when it's closed.
this.panel.addEventListener("popuphidden", function onPopupHide() {
self.panel.removeEventListener("popuphidden", onPopupHide, false);
self.panel.parentNode.removeChild(self.panel);
self.panel = null;
self.iframe = null;
self.document = null;
self.httpActivity = null;
if (self.linkNode) {
self.linkNode._panelOpen = false;
self.linkNode = null;
}
}, false);
// Set the document object and update the content once the panel is loaded.
this.panel.addEventListener("load", function onLoad() {
self.panel.removeEventListener("load", onLoad, true);
self.document = self.iframe.contentWindow.document;
self.update();
}, true);
// Create the footer.
let footer = createElement(doc, "hbox", { align: "end" });
createAndAppendElement(footer, "spacer", { flex: 1 });
createAndAppendElement(footer, "resizer", { dir: "bottomend" });
this.panel.appendChild(footer);
aParent.appendChild(this.panel);
}
NetworkPanel.prototype =
{
/**
* Callback is called once the NetworkPanel is processed completely. Used by
* unit tests.
*/
isDoneCallback: null,
/**
* The current state of the output.
*/
_state: 0,
/**
* State variables.
*/
_INIT: 0,
_DISPLAYED_REQUEST_HEADER: 1,
_DISPLAYED_REQUEST_BODY: 2,
_DISPLAYED_RESPONSE_HEADER: 3,
_TRANSITION_CLOSED: 4,
_fromDataRegExp: /Content-Type\:\s*application\/x-www-form-urlencoded/,
_contentType: null,
/**
* Small helper function that is nearly equal to l10n.getFormatStr
* except that it prefixes aName with "NetworkPanel.".
*
* @param string aName
* The name of an i10n string to format. This string is prefixed with
* "NetworkPanel." before calling the HUDService.getFormatStr function.
* @param array aArray
* Values used as placeholder for the i10n string.
* @returns string
* The i10n formated string.
*/
_format: function NP_format(aName, aArray)
{
return l10n.getFormatStr("NetworkPanel." + aName, aArray);
},
/**
* Returns the content type of the response body. This is based on the
* response.content.mimeType property. If this value is not available, then
* the content type is guessed by the file extension of the request URL.
*
* @return string
* Content type or empty string if no content type could be figured
* out.
*/
get contentType()
{
if (this._contentType) {
return this._contentType;
}
let entry = this.httpActivity.log.entries[0];
let request = entry.request;
let response = entry.response;
let contentType = "";
let types = response.content ?
(response.content.mimeType || "").split(/,|;/) : [];
for (let i = 0; i < types.length; i++) {
if (types[i] in NetworkHelper.mimeCategoryMap) {
contentType = types[i];
break;
}
}
if (contentType) {
this._contentType = contentType;
return contentType;
}
// Try to get the content type from the request file extension.
let uri = NetUtil.newURI(request.url);
if ((uri instanceof Ci.nsIURL) && uri.fileExtension) {
try {
contentType = mimeService.getTypeFromExtension(uri.fileExtension);
}
catch(ex) {
// Added to prevent failures on OS X 64. No Flash?
Cu.reportError(ex);
}
}
this._contentType = contentType;
return contentType;
},
/**
*
* @returns boolean
* True if the response is an image, false otherwise.
*/
get _responseIsImage()
{
return this.contentType &&
NetworkHelper.mimeCategoryMap[this.contentType] == "image";
},
/**
*
* @returns boolean
* True if the response body contains text, false otherwise.
*/
get _isResponseBodyTextData()
{
let contentType = this.contentType;
if (!contentType)
return false;
if (contentType.indexOf("text/") == 0) {
return true;
}
switch (NetworkHelper.mimeCategoryMap[contentType]) {
case "txt":
case "js":
case "json":
case "css":
case "html":
case "svg":
case "xml":
return true;
default:
return false;
}
},
/**
* Tells if the server response is cached.
*
* @returns boolean
* Returns true if the server responded that the request is already
* in the browser's cache, false otherwise.
*/
get _isResponseCached()
{
return this.httpActivity.log.entries[0].response.status == 304;
},
/**
* Tells if the request body includes form data.
*
* @returns boolean
* Returns true if the posted body contains form data.
*/
get _isRequestBodyFormData()
{
let requestBody = this.httpActivity.log.entries[0].request.postData.text;
return this._fromDataRegExp.test(requestBody);
},
/**
* Appends the node with id=aId by the text aValue.
*
* @param string aId
* @param string aValue
* @returns void
*/
_appendTextNode: function NP_appendTextNode(aId, aValue)
{
let textNode = this.document.createTextNode(aValue);
this.document.getElementById(aId).appendChild(textNode);
},
/**
* Generates some HTML to display the key-value pair of the aList data. The
* generated HTML is added to node with id=aParentId.
*
* @param string aParentId
* Id of the parent node to append the list to.
* @oaram array aList
* Array that holds the objects you want to display. Each object must
* have two properties: name and value.
* @param boolean aIgnoreCookie
* If true, the key-value named "Cookie" is not added to the list.
* @returns void
*/
_appendList: function NP_appendList(aParentId, aList, aIgnoreCookie)
{
let parent = this.document.getElementById(aParentId);
let doc = this.document;
aList.sort(function(a, b) {
return a.name.toLowerCase() < b.name.toLowerCase();
});
aList.forEach(function(aItem) {
let name = aItem.name;
let value = aItem.value;
if (aIgnoreCookie && name == "Cookie") {
return;
}
/**
* The following code creates the HTML:
* <tr>
* <th scope="row" class="property-name">${line}:</th>
* <td class="property-value">${aList[line]}</td>
* </tr>
* and adds it to parent.
*/
let row = doc.createElement("tr");
let textNode = doc.createTextNode(name + ":");
let th = doc.createElement("th");
th.setAttribute("scope", "row");
th.setAttribute("class", "property-name");
th.appendChild(textNode);
row.appendChild(th);
textNode = doc.createTextNode(value);
let td = doc.createElement("td");
td.setAttribute("class", "property-value");
td.appendChild(textNode);
row.appendChild(td);
parent.appendChild(row);
});
},
/**
* Displays the node with id=aId.
*
* @param string aId
* @returns void
*/
_displayNode: function NP_displayNode(aId)
{
this.document.getElementById(aId).style.display = "block";
},
/**
* Sets the request URL, request method, the timing information when the
* request started and the request header content on the NetworkPanel.
* If the request header contains cookie data, a list of sent cookies is
* generated and a special sent cookie section is displayed + the cookie list
* added to it.
*
* @returns void
*/
_displayRequestHeader: function NP__displayRequestHeader()
{
let entry = this.httpActivity.log.entries[0];
let request = entry.request;
let requestTime = new Date(entry.startedDateTime);
this._appendTextNode("headUrl", request.url);
this._appendTextNode("headMethod", request.method);
this._appendTextNode("requestHeadersInfo",
l10n.timestampString(requestTime));
this._appendList("requestHeadersContent", request.headers, true);
if (request.cookies.length > 0) {
this._displayNode("requestCookie");
this._appendList("requestCookieContent", request.cookies);
}
},
/**
* Displays the request body section of the NetworkPanel and set the request
* body content on the NetworkPanel.
*
* @returns void
*/
_displayRequestBody: function NP__displayRequestBody() {
let postData = this.httpActivity.log.entries[0].request.postData;
this._displayNode("requestBody");
this._appendTextNode("requestBodyContent", postData.text);
},
/*
* Displays the `sent form data` section. Parses the request header for the
* submitted form data displays it inside of the `sent form data` section.
*
* @returns void
*/
_displayRequestForm: function NP__processRequestForm() {
let postData = this.httpActivity.log.entries[0].request.postData.text;
let requestBodyLines = postData.split("\n");
let formData = requestBodyLines[requestBodyLines.length - 1].
replace(/\+/g, " ").split("&");
function unescapeText(aText)
{
try {
return decodeURIComponent(aText);
}
catch (ex) {
return decodeURIComponent(unescape(aText));
}
}
let formDataArray = [];
for (let i = 0; i < formData.length; i++) {
let data = formData[i];
let idx = data.indexOf("=");
let key = data.substring(0, idx);
let value = data.substring(idx + 1);
formDataArray.push({
name: unescapeText(key),
value: unescapeText(value)
});
}
this._appendList("requestFormDataContent", formDataArray);
this._displayNode("requestFormData");
},
/**
* Displays the response section of the NetworkPanel, sets the response status,
* the duration between the start of the request and the receiving of the
* response header as well as the response header content on the the NetworkPanel.
*
* @returns void
*/
_displayResponseHeader: function NP__displayResponseHeader()
{
let entry = this.httpActivity.log.entries[0];
let timing = entry.timings;
let response = entry.response;
this._appendTextNode("headStatus",
[response.httpVersion, response.status,
response.statusText].join(" "));
// Calculate how much time it took from the request start, until the
// response started to be received.
let deltaDuration = 0;
["dns", "connect", "send", "wait"].forEach(function (aValue) {
let ms = timing[aValue];
if (ms > -1) {
deltaDuration += ms;
}
});
this._appendTextNode("responseHeadersInfo",
this._format("durationMS", [deltaDuration]));
this._displayNode("responseContainer");
this._appendList("responseHeadersContent", response.headers);
},
/**
* Displays the respones image section, sets the source of the image displayed
* in the image response section to the request URL and the duration between
* the receiving of the response header and the end of the request. Once the
* image is loaded, the size of the requested image is set.
*
* @returns void
*/
_displayResponseImage: function NP__displayResponseImage()
{
let self = this;
let entry = this.httpActivity.log.entries[0];
let timing = entry.timings;
let request = entry.request;
let cached = "";
if (this._isResponseCached) {
cached = "Cached";
}
let imageNode = this.document.getElementById("responseImage" + cached +"Node");
imageNode.setAttribute("src", request.url);
// This function is called to set the imageInfo.
function setImageInfo() {
self._appendTextNode("responseImage" + cached + "Info",
self._format("imageSizeDeltaDurationMS",
[ imageNode.width, imageNode.height, timing.receive ]
)
);
}
// Check if the image is already loaded.
if (imageNode.width != 0) {
setImageInfo();
}
else {
// Image is not loaded yet therefore add a load event.
imageNode.addEventListener("load", function imageNodeLoad() {
imageNode.removeEventListener("load", imageNodeLoad, false);
setImageInfo();
}, false);
}
this._displayNode("responseImage" + cached);
},
/**
* Displays the response body section, sets the the duration between
* the receiving of the response header and the end of the request as well as
* the content of the response body on the NetworkPanel.
*
* @returns void
*/
_displayResponseBody: function NP__displayResponseBody()
{
let entry = this.httpActivity.log.entries[0];
let timing = entry.timings;
let response = entry.response;
let cached = this._isResponseCached ? "Cached" : "";
this._appendTextNode("responseBody" + cached + "Info",
this._format("durationMS", [timing.receive]));
this._displayNode("responseBody" + cached);
this._appendTextNode("responseBody" + cached + "Content",
response.content.text);
},
/**
* Displays the `Unknown Content-Type hint` and sets the duration between the
* receiving of the response header on the NetworkPanel.
*
* @returns void
*/
_displayResponseBodyUnknownType: function NP__displayResponseBodyUnknownType()
{
let timing = this.httpActivity.log.entries[0].timings;
this._displayNode("responseBodyUnknownType");
this._appendTextNode("responseBodyUnknownTypeInfo",
this._format("durationMS", [timing.receive]));
this._appendTextNode("responseBodyUnknownTypeContent",
this._format("responseBodyUnableToDisplay.content", [this.contentType]));
},
/**
* Displays the `no response body` section and sets the the duration between
* the receiving of the response header and the end of the request.
*
* @returns void
*/
_displayNoResponseBody: function NP_displayNoResponseBody()
{
let timing = this.httpActivity.log.entries[0].timings;
this._displayNode("responseNoBody");
this._appendTextNode("responseNoBodyInfo",
this._format("durationMS", [timing.receive]));
},
/**
* Updates the content of the NetworkPanel's iframe.
*
* @returns void
*/
update: function NP_update()
{
// After the iframe's contentWindow is ready, the document object is set.
// If the document object is not available yet nothing needs to be updated.
if (!this.document) {
return;
}
let stages = this.httpActivity.meta.stages;
let entry = this.httpActivity.log.entries[0];
let timing = entry.timings;
let request = entry.request;
let response = entry.response;
switch (this._state) {
case this._INIT:
this._displayRequestHeader();
this._state = this._DISPLAYED_REQUEST_HEADER;
// FALL THROUGH
case this._DISPLAYED_REQUEST_HEADER:
// Process the request body if there is one.
if (!this.httpActivity.meta.discardRequestBody && request.postData) {
// Check if we send some form data. If so, display the form data special.
if (this._isRequestBodyFormData) {
this._displayRequestForm();
}
else {
this._displayRequestBody();
}
this._state = this._DISPLAYED_REQUEST_BODY;
}
// FALL THROUGH
case this._DISPLAYED_REQUEST_BODY:
// There is always a response header. Therefore we can skip here if
// we don't have a response header yet and don't have to try updating
// anything else in the NetworkPanel.
if (!response.headers.length || !Object.keys(timing).length) {
break;
}
this._displayResponseHeader();
this._state = this._DISPLAYED_RESPONSE_HEADER;
// FALL THROUGH
case this._DISPLAYED_RESPONSE_HEADER:
if (stages.indexOf("REQUEST_STOP") == -1 ||
stages.indexOf("TRANSACTION_CLOSE") == -1) {
break;
}
this._state = this._TRANSITION_CLOSED;
if (this.httpActivity.meta.discardResponseBody) {
break;
}
if (!response.content || !response.content.text) {
this._displayNoResponseBody();
}
else if (this._responseIsImage) {
this._displayResponseImage();
}
else if (!this._isResponseBodyTextData) {
this._displayResponseBodyUnknownType();
}
else if (response.content.text) {
this._displayResponseBody();
}
break;
}
}
}
/**
* Creates a DOMNode and sets all the attributes of aAttributes on the created
* element.
*
* @param nsIDOMDocument aDocument
* Document to create the new DOMNode.
* @param string aTag
* Name of the tag for the DOMNode.
* @param object aAttributes
* Attributes set on the created DOMNode.
*
* @returns nsIDOMNode
*/
function createElement(aDocument, aTag, aAttributes)
{
let node = aDocument.createElement(aTag);
if (aAttributes) {
for (let attr in aAttributes) {
node.setAttribute(attr, aAttributes[attr]);
}
}
return node;
}
/**
* Creates a new DOMNode and appends it to aParent.
*
* @param nsIDOMNode aParent
* A parent node to append the created element.
* @param string aTag
* Name of the tag for the DOMNode.
* @param object aAttributes
* Attributes set on the created DOMNode.
*
* @returns nsIDOMNode
*/
function createAndAppendElement(aParent, aTag, aAttributes)
{
let node = createElement(aParent.ownerDocument, aTag, aAttributes);
aParent.appendChild(node);
return node;
}

View File

@ -11,17 +11,12 @@ const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyGetter(this, "WebConsoleUtils", function () {
let obj = {};
Cu.import("resource:///modules/WebConsoleUtils.jsm", obj);
return obj.WebConsoleUtils;
});
XPCOMUtils.defineLazyModuleGetter(this, "WebConsoleUtils",
"resource:///modules/WebConsoleUtils.jsm");
var EXPORTED_SYMBOLS = ["PropertyPanel", "PropertyTreeView"];
///////////////////////////////////////////////////////////////////////////
//// PropertyTreeView.

View File

@ -11,7 +11,9 @@ const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
var EXPORTED_SYMBOLS = ["WebConsoleUtils", "JSPropertyProvider"];

View File

@ -5,31 +5,17 @@
const TEST_FILE = "test-network.html";
function tabLoad(aEvent) {
browser.removeEventListener(aEvent.type, arguments.callee, true);
openConsole();
let hudId = HUDService.getHudIdByWindow(content);
hud = HUDService.hudReferences[hudId];
browser.addEventListener("load", tabReload, true);
content.location.reload();
}
function tabReload(aEvent) {
browser.removeEventListener(aEvent.type, arguments.callee, true);
browser.removeEventListener(aEvent.type, tabReload, true);
let textContent = hud.outputNode.textContent;
isnot(textContent.indexOf("test-network.html"), -1,
"found test-network.html");
isnot(textContent.indexOf("test-image.png"), -1, "found test-image.png");
isnot(textContent.indexOf("testscript.js"), -1, "found testscript.js");
isnot(textContent.indexOf("running network console logging tests"), -1,
outputNode = hud.outputNode;
findLogEntry("test-network.html");
findLogEntry("test-image.png");
findLogEntry("testscript.js");
isnot(outputNode.textContent.indexOf("running network console logging tests"), -1,
"found the console.log() message from testscript.js");
finishTest();
executeSoon(finishTest);
}
function test() {
@ -42,5 +28,12 @@ function test() {
let uri = Services.io.newFileURI(dir);
addTab(uri.spec);
browser.addEventListener("load", tabLoad, true);
browser.addEventListener("load", function tabLoad() {
browser.removeEventListener("load", tabLoad, true);
openConsole(null, function(aHud) {
hud = aHud;
browser.addEventListener("load", tabReload, true);
content.location.reload();
});
}, true);
}

View File

@ -10,25 +10,27 @@
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-bug-599725-response-headers.sjs";
let lastFinishedRequest = null;
function requestDoneCallback(aHttpRequest)
{
lastFinishedRequest = aHttpRequest;
}
function performTest()
function performTest(lastFinishedRequest)
{
ok(lastFinishedRequest, "page load was logged");
let headers = lastFinishedRequest.response.header;
ok(headers, "we have the response headers");
ok(!headers["Content-Type"], "we do not have the Content-Type header");
ok(headers["Content-Length"] != 60, "Content-Length != 60");
function readHeader(aName)
{
for (let header of headers) {
if (header.name == aName) {
return header.value;
}
}
return null;
}
let headers = lastFinishedRequest.log.entries[0].response.headers;
ok(headers, "we have the response headers");
ok(!readHeader("Content-Type"), "we do not have the Content-Type header");
isnot(readHeader("Content-Length"), 60, "Content-Length != 60");
lastFinishedRequest = null;
HUDService.lastFinishedRequestCallback = null;
finishTest();
executeSoon(finishTest);
}
function test()
@ -37,15 +39,15 @@ function test()
let initialLoad = true;
browser.addEventListener("load", function () {
browser.addEventListener("load", function onLoad() {
if (initialLoad) {
openConsole();
HUDService.lastFinishedRequestCallback = requestDoneCallback;
content.location.reload();
openConsole(null, function() {
HUDService.lastFinishedRequestCallback = performTest;
content.location.reload();
});
initialLoad = false;
} else {
browser.removeEventListener("load", arguments.callee, true);
performTest();
browser.removeEventListener("load", onLoad, true);
}
}, true);
}

View File

@ -10,28 +10,19 @@
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-bug-600183-charset.html";
let lastFinishedRequest = null;
function requestDoneCallback(aHttpRequest)
{
lastFinishedRequest = aHttpRequest;
}
function performTest()
function performTest(lastFinishedRequest)
{
ok(lastFinishedRequest, "charset test page was loaded and logged");
let body = lastFinishedRequest.response.body;
let body = lastFinishedRequest.log.entries[0].response.content.text;
ok(body, "we have the response body");
let chars = "\u7684\u95ee\u5019!"; // 的问候!
isnot(body.indexOf("<p>" + chars + "</p>"), -1,
"found the chinese simplified string");
lastFinishedRequest = null;
HUDService.saveRequestAndResponseBodies = false;
HUDService.lastFinishedRequestCallback = null;
finishTest();
executeSoon(finishTest);
}
function test()
@ -40,20 +31,18 @@ function test()
let initialLoad = true;
browser.addEventListener("load", function () {
browser.addEventListener("load", function onLoad() {
if (initialLoad) {
waitForFocus(function() {
openConsole();
openConsole(null, function(hud) {
HUDService.saveRequestAndResponseBodies = true;
HUDService.lastFinishedRequestCallback = requestDoneCallback;
hud.saveRequestAndResponseBodies = true;
HUDService.lastFinishedRequestCallback = performTest;
content.location = TEST_URI;
}, content);
});
initialLoad = false;
} else {
browser.removeEventListener("load", arguments.callee, true);
performTest();
browser.removeEventListener("load", onLoad, true);
}
}, true);
}

View File

@ -57,10 +57,10 @@ function onpopupshown2(aEvent)
isnot(menuitems[1].getAttribute("checked"), "true",
"menuitems[1] is not checked");
ok(!HUDService.saveRequestAndResponseBodies, "bodies are not logged");
ok(!huds[1].saveRequestAndResponseBodies, "bodies are not logged");
// Enable body logging.
HUDService.saveRequestAndResponseBodies = true;
huds[1].saveRequestAndResponseBodies = true;
menupopups[1].addEventListener("popuphidden", function _onhidden(aEvent) {
menupopups[1].removeEventListener(aEvent.type, _onhidden, false);
@ -103,11 +103,12 @@ function onpopupshown1(aEvent)
{
menupopups[0].removeEventListener(aEvent.type, onpopupshown1, false);
// The menuitem checkbox must be in sync with the other tabs.
is(menuitems[0].getAttribute("checked"), "true", "menuitems[0] is checked");
// The menuitem checkbox must not be in sync with the other tabs.
isnot(menuitems[0].getAttribute("checked"), "true",
"menuitems[0] is not checked");
// Disable body logging.
HUDService.saveRequestAndResponseBodies = false;
// Enable body logging for tab 1 as well.
huds[0].saveRequestAndResponseBodies = true;
// Close the menu, and switch back to tab 2.
menupopups[0].addEventListener("popuphidden", function _onhidden(aEvent) {
@ -127,8 +128,7 @@ function onpopupshown2c(aEvent)
{
menupopups[1].removeEventListener(aEvent.type, onpopupshown2c, false);
isnot(menuitems[1].getAttribute("checked"), "true",
"menuitems[1] is not checked");
is(menuitems[1].getAttribute("checked"), "true", "menuitems[1] is checked");
menupopups[1].addEventListener("popuphidden", function _onhidden(aEvent) {
menupopups[1].removeEventListener(aEvent.type, _onhidden, false);

View File

@ -41,14 +41,11 @@ let TestObserver = {
function tabLoad(aEvent) {
browser.removeEventListener(aEvent.type, tabLoad, true);
openConsole();
let hudId = HUDService.getHudIdByWindow(content);
hud = HUDService.hudReferences[hudId];
Services.console.registerListener(TestObserver);
content.location = TEST_URI;
openConsole(null, function(aHud) {
hud = aHud;
Services.console.registerListener(TestObserver);
content.location = TEST_URI;
});
}
function performTest() {

View File

@ -92,8 +92,8 @@ function tabLoaded() {
successFn: function()
{
let jstermMessage = HUD.outputNode.querySelector(".webconsole-msg-output");
EventUtils.synthesizeMouse(networkLink, 2, 2, {});
EventUtils.synthesizeMouse(jstermMessage, 2, 2, {});
EventUtils.synthesizeMouse(networkLink, 2, 2, {});
},
failureFn: finishTest,
});

View File

@ -118,8 +118,8 @@ function tabLoaded() {
successFn: function()
{
let jstermMessage = HUD.outputNode.querySelector(".webconsole-msg-output");
EventUtils.synthesizeMouse(networkLink, 2, 2, {});
EventUtils.synthesizeMouse(jstermMessage, 2, 2, {});
EventUtils.synthesizeMouse(networkLink, 2, 2, {});
},
failureFn: finishTest,
});

View File

@ -13,57 +13,63 @@ let lastFinishedRequests = {};
function requestDoneCallback(aHttpRequest)
{
let status = aHttpRequest.response.status.
replace(/^HTTP\/\d\.\d (\d+).+$/, "$1");
let status = aHttpRequest.log.entries[0].response.status;
lastFinishedRequests[status] = aHttpRequest;
}
function performTest(aEvent)
{
HUDService.saveRequestAndResponseBodies = false;
HUDService.lastFinishedRequestCallback = null;
ok("301" in lastFinishedRequests, "request 1: 301 Moved Permanently");
ok("404" in lastFinishedRequests, "request 2: 404 Not found");
let headers0 = lastFinishedRequests["301"].response.header;
is(headers0["Content-Type"], "text/html",
function readHeader(aName)
{
for (let header of headers) {
if (header.name == aName) {
return header.value;
}
}
return null;
}
let headers = lastFinishedRequests["301"].log.entries[0].response.headers;
is(readHeader("Content-Type"), "text/html",
"we do have the Content-Type header");
is(headers0["Content-Length"], 71, "Content-Length is correct");
is(headers0["Location"], "/redirect-from-bug-630733",
is(readHeader("Content-Length"), 71, "Content-Length is correct");
is(readHeader("Location"), "/redirect-from-bug-630733",
"Content-Length is correct");
is(headers0["x-foobar-bug630733"], "bazbaz",
is(readHeader("x-foobar-bug630733"), "bazbaz",
"X-Foobar-bug630733 is correct");
let body = lastFinishedRequests["301"].response.body;
ok(!body, "body discarded for request 1");
let body = lastFinishedRequests["301"].log.entries[0].response.content;
ok(!body.text, "body discarded for request 1");
let headers1 = lastFinishedRequests["404"].response.header;
ok(!headers1["Location"], "no Location header");
ok(!headers1["x-foobar-bug630733"], "no X-Foobar-bug630733 header");
headers = lastFinishedRequests["404"].log.entries[0].response.headers;
ok(!readHeader("Location"), "no Location header");
ok(!readHeader("x-foobar-bug630733"), "no X-Foobar-bug630733 header");
body = lastFinishedRequests["404"].response.body;
body = lastFinishedRequests["404"].log.entries[0].response.content.text;
isnot(body.indexOf("404"), -1,
"body is correct for request 2");
lastFinishedRequests = null;
finishTest();
executeSoon(finishTest);
}
function test()
{
addTab("data:text/html;charset=utf-8,<p>Web Console test for bug 630733");
browser.addEventListener("load", function(aEvent) {
browser.removeEventListener(aEvent.type, arguments.callee, true);
browser.addEventListener("load", function onLoad1(aEvent) {
browser.removeEventListener(aEvent.type, onLoad1, true);
executeSoon(function() {
openConsole();
HUDService.saveRequestAndResponseBodies = true;
openConsole(null, function(hud) {
hud.saveRequestAndResponseBodies = true;
HUDService.lastFinishedRequestCallback = requestDoneCallback;
browser.addEventListener("load", function(aEvent) {
browser.removeEventListener(aEvent.type, arguments.callee, true);
browser.addEventListener("load", function onLoad2(aEvent) {
browser.removeEventListener(aEvent.type, onLoad2, true);
executeSoon(performTest);
}, true);

View File

@ -18,38 +18,36 @@ function test()
{
addTab("data:text/html;charset=utf-8,Web Console network logging tests");
browser.addEventListener("load", function() {
browser.removeEventListener("load", arguments.callee, true);
browser.addEventListener("load", function onLoad() {
browser.removeEventListener("load", onLoad, true);
openConsole();
openConsole(null, function(aHud) {
hud = aHud;
hud = HUDService.getHudByWindow(content);
ok(hud, "Web Console is now open");
HUDService.lastFinishedRequestCallback = function(aRequest) {
lastRequest = aRequest.log.entries[0];
if (requestCallback) {
requestCallback();
}
};
HUDService.lastFinishedRequestCallback = function(aRequest) {
lastRequest = aRequest;
if (requestCallback) {
requestCallback();
}
};
executeSoon(testPageLoad);
executeSoon(testPageLoad);
});
}, true);
}
function testPageLoad()
{
browser.addEventListener("load", function(aEvent) {
browser.removeEventListener(aEvent.type, arguments.callee, true);
requestCallback = function() {
// Check if page load was logged correctly.
ok(lastRequest, "Page load was logged");
is(lastRequest.url, TEST_NETWORK_REQUEST_URI,
is(lastRequest.request.url, TEST_NETWORK_REQUEST_URI,
"Logged network entry is page load");
is(lastRequest.method, "GET", "Method is correct");
is(lastRequest.request.method, "GET", "Method is correct");
lastRequest = null;
requestCallback = null;
executeSoon(testPageLoadBody);
}, true);
};
content.location = TEST_NETWORK_REQUEST_URI;
}
@ -57,12 +55,12 @@ function testPageLoad()
function testPageLoadBody()
{
// Turn off logging of request bodies and check again.
browser.addEventListener("load", function(aEvent) {
browser.removeEventListener(aEvent.type, arguments.callee, true);
requestCallback = function() {
ok(lastRequest, "Page load was logged again");
lastRequest = null;
requestCallback = null;
executeSoon(testXhrGet);
}, true);
};
content.location.reload();
}
@ -71,7 +69,7 @@ function testXhrGet()
{
requestCallback = function() {
ok(lastRequest, "testXhrGet() was logged");
is(lastRequest.method, "GET", "Method is correct");
is(lastRequest.request.method, "GET", "Method is correct");
lastRequest = null;
requestCallback = null;
executeSoon(testXhrPost);
@ -85,7 +83,7 @@ function testXhrPost()
{
requestCallback = function() {
ok(lastRequest, "testXhrPost() was logged");
is(lastRequest.method, "POST", "Method is correct");
is(lastRequest.request.method, "POST", "Method is correct");
lastRequest = null;
requestCallback = null;
executeSoon(testFormSubmission);
@ -99,12 +97,11 @@ function testFormSubmission()
{
// Start the form submission test. As the form is submitted, the page is
// loaded again. Bind to the load event to catch when this is done.
browser.addEventListener("load", function(aEvent) {
browser.removeEventListener(aEvent.type, arguments.callee, true);
requestCallback = function() {
ok(lastRequest, "testFormSubmission() was logged");
is(lastRequest.method, "POST", "Method is correct");
is(lastRequest.request.method, "POST", "Method is correct");
executeSoon(testLiveFilteringOnSearchStrings);
}, true);
};
let form = content.document.querySelector("form");
ok(form, "we have the HTML form");
@ -112,9 +109,6 @@ function testFormSubmission()
}
function testLiveFilteringOnSearchStrings() {
browser.removeEventListener("DOMContentLoaded",
testLiveFilteringOnSearchStrings, false);
setStringFilter("http");
isnot(countMessageNodes(), 0, "the log nodes are not hidden when the " +
"search string is set to \"http\"");
@ -146,6 +140,9 @@ function testLiveFilteringOnSearchStrings() {
is(countMessageNodes(), 0, "the log nodes are hidden when searching for " +
"the string \"foo\"bar'baz\"boo'\"");
HUDService.lastFinishedRequestCallback = null;
lastRequest = null;
requestCallback = null;
finishTest();
}

View File

@ -21,47 +21,47 @@ const TEST_DATA_JSON_CONTENT =
let lastRequest = null;
let requestCallback = null;
let lastActivity = null;
function test()
{
addTab("data:text/html;charset=utf-8,Web Console network logging tests");
browser.addEventListener("load", function() {
browser.removeEventListener("load", arguments.callee, true);
browser.addEventListener("load", function onLoad() {
browser.removeEventListener("load", onLoad, true);
openConsole();
openConsole(null, function(aHud) {
hud = aHud;
hud = HUDService.getHudByWindow(content);
ok(hud, "Web Console is now open");
HUDService.lastFinishedRequestCallback = function(aRequest) {
lastRequest = aRequest.log.entries[0];
lastActivity = aRequest;
if (requestCallback) {
requestCallback();
}
};
HUDService.lastFinishedRequestCallback = function(aRequest) {
lastRequest = aRequest;
if (requestCallback) {
requestCallback();
}
};
executeSoon(testPageLoad);
executeSoon(testPageLoad);
});
}, true);
}
function testPageLoad()
{
browser.addEventListener("load", function(aEvent) {
browser.removeEventListener(aEvent.type, arguments.callee, true);
requestCallback = function() {
// Check if page load was logged correctly.
ok(lastRequest, "Page load was logged");
is(lastRequest.url, TEST_NETWORK_REQUEST_URI,
is(lastRequest.request.url, TEST_NETWORK_REQUEST_URI,
"Logged network entry is page load");
is(lastRequest.method, "GET", "Method is correct");
ok(!("body" in lastRequest.request), "No request body was stored");
ok(!("body" in lastRequest.response), "No response body was stored");
ok(!lastRequest.response.listener, "No response listener is stored");
is(lastRequest.request.method, "GET", "Method is correct");
ok(!lastRequest.request.postData, "No request body was stored");
ok(!lastRequest.response.content.text, "No response body was stored");
lastRequest = null;
requestCallback = null;
executeSoon(testPageLoadBody);
}, true);
};
content.location = TEST_NETWORK_REQUEST_URI;
}
@ -69,17 +69,16 @@ function testPageLoad()
function testPageLoadBody()
{
// Turn on logging of request bodies and check again.
HUDService.saveRequestAndResponseBodies = true;
browser.addEventListener("load", function(aEvent) {
browser.removeEventListener(aEvent.type, arguments.callee, true);
hud.saveRequestAndResponseBodies = true;
requestCallback = function() {
ok(lastRequest, "Page load was logged again");
is(lastRequest.response.body.indexOf("<!DOCTYPE HTML>"), 0,
is(lastRequest.response.content.text.indexOf("<!DOCTYPE HTML>"), 0,
"Response body's beginning is okay");
lastRequest = null;
requestCallback = null;
executeSoon(testXhrGet);
}, true);
};
content.location.reload();
}
@ -88,9 +87,9 @@ function testXhrGet()
{
requestCallback = function() {
ok(lastRequest, "testXhrGet() was logged");
is(lastRequest.method, "GET", "Method is correct");
is(lastRequest.request.body, null, "No request body was sent");
is(lastRequest.response.body, TEST_DATA_JSON_CONTENT,
is(lastRequest.request.method, "GET", "Method is correct");
ok(!lastRequest.request.postData, "No request body was sent");
is(lastRequest.response.content.text, TEST_DATA_JSON_CONTENT,
"Response is correct");
lastRequest = null;
@ -106,10 +105,10 @@ function testXhrPost()
{
requestCallback = function() {
ok(lastRequest, "testXhrPost() was logged");
is(lastRequest.method, "POST", "Method is correct");
is(lastRequest.request.body, "Hello world!",
is(lastRequest.request.method, "POST", "Method is correct");
is(lastRequest.request.postData.text, "Hello world!",
"Request body was logged");
is(lastRequest.response.body, TEST_DATA_JSON_CONTENT,
is(lastRequest.response.content.text, TEST_DATA_JSON_CONTENT,
"Response is correct");
lastRequest = null;
@ -125,23 +124,21 @@ function testFormSubmission()
{
// Start the form submission test. As the form is submitted, the page is
// loaded again. Bind to the load event to catch when this is done.
browser.addEventListener("load", function(aEvent) {
browser.removeEventListener(aEvent.type, arguments.callee, true);
requestCallback = function() {
ok(lastRequest, "testFormSubmission() was logged");
is(lastRequest.method, "POST", "Method is correct");
isnot(lastRequest.request.body.
is(lastRequest.request.method, "POST", "Method is correct");
isnot(lastRequest.request.postData.text.
indexOf("Content-Type: application/x-www-form-urlencoded"), -1,
"Content-Type is correct");
isnot(lastRequest.request.body.
isnot(lastRequest.request.postData.text.
indexOf("Content-Length: 20"), -1, "Content-length is correct");
isnot(lastRequest.request.body.
isnot(lastRequest.request.postData.text.
indexOf("name=foo+bar&age=144"), -1, "Form data is correct");
ok(lastRequest.response.body.indexOf("<!DOCTYPE HTML>") == 0,
is(lastRequest.response.content.text.indexOf("<!DOCTYPE HTML>"), 0,
"Response body's beginning is okay");
executeSoon(testNetworkPanel);
}, true);
};
let form = content.document.querySelector("form");
ok(form, "we have the HTML form");
@ -152,19 +149,19 @@ function testNetworkPanel()
{
// Open the NetworkPanel. The functionality of the NetworkPanel is tested
// within separate test files.
let networkPanel = HUDService.openNetworkPanel(hud.filterBox, lastRequest);
is(networkPanel, lastRequest.panels[0].get(),
"Network panel stored on lastRequest object");
let networkPanel = HUDService.openNetworkPanel(hud.filterBox, lastActivity);
is(networkPanel, hud.filterBox._netPanel,
"Network panel stored on anchor node");
networkPanel.panel.addEventListener("load", function(aEvent) {
networkPanel.panel.removeEventListener(aEvent.type, arguments.callee,
true);
networkPanel.panel.addEventListener("load", function onLoad(aEvent) {
networkPanel.panel.removeEventListener(aEvent.type, onLoad, true);
ok(true, "NetworkPanel was opened");
// All tests are done. Shutdown.
networkPanel.panel.hidePopup();
lastRequest = null;
lastActivity = null;
HUDService.lastFinishedRequestCallback = null;
executeSoon(finishTest);
}, true);

View File

@ -68,25 +68,39 @@ function testGen() {
let l10n = tempScope.WebConsoleUtils.l10n;
tempScope = null;
var httpActivity = {
url: "http://www.testpage.com",
method: "GET",
panels: [],
request: {
header: {
foo: "bar"
}
let httpActivity = {
meta: {
stages: [],
discardRequestBody: true,
discardResponseBody: true,
},
log: {
entries: [{
startedDateTime: (new Date()).toISOString(),
request: {
url: "http://www.testpage.com",
method: "GET",
cookies: [],
headers: [
{ name: "foo", value: "bar" },
],
},
response: {
headers: [],
content: {},
},
timings: {},
}],
},
response: { },
timing: {
"REQUEST_HEADER": 0
}
};
let entry = httpActivity.log.entries[0];
let networkPanel = HUDService.openNetworkPanel(filterBox, httpActivity);
is (networkPanel, httpActivity.panels[0].get(), "Network panel stored on httpActivity object");
is(filterBox._netPanel, networkPanel,
"Network panel stored on the anchor object");
networkPanel.panel.addEventListener("load", function onLoad() {
networkPanel.panel.removeEventListener("load", onLoad, true);
testDriver.next();
@ -94,6 +108,8 @@ function testGen() {
yield;
info("test 1");
checkIsVisible(networkPanel, {
requestCookie: false,
requestFormData: false,
@ -110,8 +126,11 @@ function testGen() {
checkNodeKeyValue(networkPanel, "requestHeadersContent", "foo", "bar");
// Test request body.
httpActivity.request.body = "hello world";
info("test 2: request body");
httpActivity.meta.discardRequestBody = false;
entry.request.postData = { text: "hello world" };
networkPanel.update();
checkIsVisible(networkPanel, {
requestBody: true,
requestFormData: false,
@ -125,13 +144,19 @@ function testGen() {
checkNodeContent(networkPanel, "requestBodyContent", "hello world");
// Test response header.
httpActivity.timing.RESPONSE_HEADER = 1000;
httpActivity.response.status = "999 earthquake win";
httpActivity.response.header = {
"Content-Type": "text/html",
leaveHouses: "true"
}
info("test 3: response header");
entry.timings.wait = 10;
entry.response.httpVersion = "HTTP/3.14";
entry.response.status = 999;
entry.response.statusText = "earthquake win";
entry.response.content.mimeType = "text/html";
entry.response.headers.push(
{ name: "Content-Type", value: "text/html" },
{ name: "leaveHouses", value: "true" }
);
networkPanel.update();
checkIsVisible(networkPanel, {
requestBody: true,
requestFormData: false,
@ -143,13 +168,14 @@ function testGen() {
responseImageCached: false
});
checkNodeContent(networkPanel, "header", "999 earthquake win");
checkNodeContent(networkPanel, "header", "HTTP/3.14 999 earthquake win");
checkNodeKeyValue(networkPanel, "responseHeadersContent", "leaveHouses", "true");
checkNodeContent(networkPanel, "responseHeadersInfo", "1ms");
checkNodeContent(networkPanel, "responseHeadersInfo", "10ms");
httpActivity.timing.RESPONSE_COMPLETE = 2500;
// This is necessary to show that the request is done.
httpActivity.timing.TRANSACTION_CLOSE = 2500;
info("test 4");
httpActivity.meta.discardResponseBody = false;
entry.timings.receive = 2;
networkPanel.update();
checkIsVisible(networkPanel, {
@ -163,7 +189,9 @@ function testGen() {
responseImageCached: false
});
httpActivity.response.isDone = true;
info("test 5");
httpActivity.meta.stages.push("REQUEST_STOP", "TRANSACTION_CLOSE");
networkPanel.update();
checkNodeContent(networkPanel, "responseNoBodyInfo", "2ms");
@ -180,11 +208,17 @@ function testGen() {
networkPanel.panel.hidePopup();
// Second run: Test for cookies and response body.
httpActivity.request.header.Cookie = "foo=bar; hello=world";
httpActivity.response.body = "get out here";
info("test 6: cookies and response body");
entry.request.cookies.push(
{ name: "foo", value: "bar" },
{ name: "hello", value: "world" }
);
entry.response.content.text = "get out here";
networkPanel = HUDService.openNetworkPanel(filterBox, httpActivity);
is (networkPanel, httpActivity.panels[1].get(), "Network panel stored on httpActivity object");
is(filterBox._netPanel, networkPanel,
"Network panel stored on httpActivity object");
networkPanel.panel.addEventListener("load", function onLoad() {
networkPanel.panel.removeEventListener("load", onLoad, true);
testDriver.next();
@ -192,7 +226,6 @@ function testGen() {
yield;
checkIsVisible(networkPanel, {
requestBody: true,
requestFormData: false,
@ -212,8 +245,10 @@ function testGen() {
networkPanel.panel.hidePopup();
// Check image request.
httpActivity.response.header["Content-Type"] = "image/png";
httpActivity.url = TEST_IMG;
info("test 7: image request");
entry.response.headers[1].value = "image/png";
entry.response.content.mimeType = "image/png";
entry.request.url = TEST_IMG;
networkPanel = HUDService.openNetworkPanel(filterBox, httpActivity);
networkPanel.panel.addEventListener("load", function onLoad() {
@ -259,7 +294,10 @@ function testGen() {
}
// Check cached image request.
httpActivity.response.status = "HTTP/1.1 304 Not Modified";
info("test 8: cached image request");
entry.response.httpVersion = "HTTP/1.1";
entry.response.status = 304;
entry.response.statusText = "Not Modified";
networkPanel = HUDService.openNetworkPanel(filterBox, httpActivity);
networkPanel.panel.addEventListener("load", function onLoad() {
@ -286,11 +324,12 @@ function testGen() {
networkPanel.panel.hidePopup();
// Test sent form data.
httpActivity.request.body = [
"Content-Type: application/x-www-form-urlencoded\n" +
"Content-Length: 59\n" +
info("test 9: sent form data");
entry.request.postData.text = [
"Content-Type: application/x-www-form-urlencoded",
"Content-Length: 59",
"name=rob&age=20"
].join("");
].join("\n");
networkPanel = HUDService.openNetworkPanel(filterBox, httpActivity);
networkPanel.panel.addEventListener("load", function onLoad() {
@ -316,7 +355,8 @@ function testGen() {
networkPanel.panel.hidePopup();
// Test no space after Content-Type:
httpActivity.request.body = "Content-Type:application/x-www-form-urlencoded\n";
info("test 10: no space after Content-Type header in post data");
entry.request.postData.text = "Content-Type:application/x-www-form-urlencoded\n";
networkPanel = HUDService.openNetworkPanel(filterBox, httpActivity);
networkPanel.panel.addEventListener("load", function onLoad() {
@ -341,25 +381,18 @@ function testGen() {
// Test cached data.
// Load a Latin-1 encoded page.
browser.addEventListener("load", function onLoad () {
browser.removeEventListener("load", onLoad, true);
httpActivity.charset = content.document.characterSet;
testDriver.next();
}, true);
browser.contentWindow.wrappedJSObject.document.location = TEST_ENCODING_ISO_8859_1;
info("test 11: cached data");
yield;
httpActivity.url = TEST_ENCODING_ISO_8859_1;
httpActivity.response.header["Content-Type"] = "application/json";
httpActivity.response.body = "";
entry.request.url = TEST_ENCODING_ISO_8859_1;
entry.response.headers[1].value = "application/json";
entry.response.content.mimeType = "application/json";
entry.response.content.text = "my cached data is here!";
networkPanel = HUDService.openNetworkPanel(filterBox, httpActivity);
networkPanel.isDoneCallback = function NP_doneCallback() {
networkPanel.isDoneCallback = null;
networkPanel.panel.addEventListener("load", function onLoad() {
networkPanel.panel.removeEventListener("load", onLoad, true);
testDriver.next();
}
}, true);
yield;
@ -375,21 +408,22 @@ function testGen() {
responseImageCached: false
});
checkNodeContent(networkPanel, "responseBodyCachedContent", "<body>\u00fc\u00f6\u00E4</body>");
checkNodeContent(networkPanel, "responseBodyCachedContent",
"my cached data is here!");
networkPanel.panel.hidePopup();
// Test a response with a content type that can't be displayed in the
// NetworkPanel.
httpActivity.response.header["Content-Type"] = "application/x-shockwave-flash";
info("test 12: unknown content type");
entry.response.headers[1].value = "application/x-shockwave-flash";
entry.response.content.mimeType = "application/x-shockwave-flash";
networkPanel = HUDService.openNetworkPanel(filterBox, httpActivity);
networkPanel.isDoneCallback = function NP_doneCallback() {
networkPanel.isDoneCallback = null;
try {
testDriver.next();
} catch (e if e instanceof StopIteration) {
}
}
networkPanel.panel.addEventListener("load", function onLoad() {
networkPanel.panel.removeEventListener("load", onLoad, true);
testDriver.next();
}, true);
yield;
@ -453,4 +487,6 @@ function testGen() {
// All done!
testDriver = null;
executeSoon(finishTest);
yield;
}