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
Родитель f61281cfb9
Коммит e7e699e7f7
18 изменённых файлов: 2379 добавлений и 1785 удалений

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

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

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

@ -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",
}
}

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

@ -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;
}

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

@ -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.

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

@ -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"];

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

@ -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);
}

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

@ -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;
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);
}

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

@ -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);
}

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

@ -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);

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

@ -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];
openConsole(null, function(aHud) {
hud = aHud;
Services.console.registerListener(TestObserver);
content.location = TEST_URI;
});
}
function performTest() {

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

@ -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,
});

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

@ -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,
});

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

@ -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);

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

@ -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();
hud = HUDService.getHudByWindow(content);
ok(hud, "Web Console is now open");
openConsole(null, function(aHud) {
hud = aHud;
HUDService.lastFinishedRequestCallback = function(aRequest) {
lastRequest = aRequest;
lastRequest = aRequest.log.entries[0];
if (requestCallback) {
requestCallback();
}
};
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();
}

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

@ -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();
hud = HUDService.getHudByWindow(content);
ok(hud, "Web Console is now open");
openConsole(null, function(aHud) {
hud = aHud;
HUDService.lastFinishedRequestCallback = function(aRequest) {
lastRequest = aRequest;
lastRequest = aRequest.log.entries[0];
lastActivity = aRequest;
if (requestCallback) {
requestCallback();
}
};
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);

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

@ -68,25 +68,39 @@ function testGen() {
let l10n = tempScope.WebConsoleUtils.l10n;
tempScope = null;
var httpActivity = {
let httpActivity = {
meta: {
stages: [],
discardRequestBody: true,
discardResponseBody: true,
},
log: {
entries: [{
startedDateTime: (new Date()).toISOString(),
request: {
url: "http://www.testpage.com",
method: "GET",
panels: [],
request: {
header: {
foo: "bar"
}
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 {
networkPanel.panel.addEventListener("load", function onLoad() {
networkPanel.panel.removeEventListener("load", onLoad, true);
testDriver.next();
} catch (e if e instanceof StopIteration) {
}
}
}, true);
yield;
@ -453,4 +487,6 @@ function testGen() {
// All done!
testDriver = null;
executeSoon(finishTest);
yield;
}